Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: git/git
base: 221c3daef41bdd7eebd5f45d711e847d0a85aa86
Choose a base ref
...
head repository: git/git
compare: d699d15c328b03fd822d3950f7ed76debef02c26
Choose a head ref
  • 9 commits
  • 34 files changed
  • 2 contributors

Commits on Feb 19, 2024

  1. Merge branch 'ps/reftable-backend' into ps/reflog-list

    * ps/reftable-backend:
      refs/reftable: fix leak when copying reflog fails
      ci: add jobs to test with the reftable backend
      refs: introduce reftable backend
    gitster committed Feb 19, 2024
    Configuration menu
    Copy the full SHA
    f7cdeaf View commit details
    Browse the repository at this point in the history

Commits on Feb 21, 2024

  1. dir-iterator: pass name to prepare_next_entry_data() directly

    When adding the next directory entry for `struct dir_iterator` we pass
    the complete `struct dirent *` to `prepare_next_entry_data()` even
    though we only need the entry's name.
    
    Refactor the code to pass in the name, only. This prepares for a
    subsequent commit where we introduce the ability to iterate through
    dir entries in an ordered manner.
    
    Signed-off-by: Patrick Steinhardt <[email protected]>
    Signed-off-by: Junio C Hamano <[email protected]>
    pks-t authored and gitster committed Feb 21, 2024
    Configuration menu
    Copy the full SHA
    0218de2 View commit details
    Browse the repository at this point in the history
  2. dir-iterator: support iteration in sorted order

    The `struct dir_iterator` is a helper that allows us to iterate through
    directory entries. This iterator returns entries in the exact same order
    as readdir(3P) does -- or in other words, it guarantees no specific
    order at all.
    
    This is about to become problematic as we are introducing a new reflog
    subcommand to list reflogs. As the "files" backend uses the directory
    iterator to enumerate reflogs, returning reflog names and exposing them
    to the user would inherit the indeterministic ordering. Naturally, it
    would make for a terrible user interface to show a list with no
    discernible order.
    
    While this could be handled at a higher level by the new subcommand
    itself by collecting and ordering the reflogs, this would be inefficient
    because we would first have to collect all reflogs before we can sort
    them, which would introduce additional latency when there are many
    reflogs.
    
    Instead, introduce a new option into the directory iterator that asks
    for its entries to be yielded in lexicographical order. If set, the
    iterator will read all directory entries greedily and sort them before
    we start to iterate over them.
    
    While this will of course also incur overhead as we cannot yield the
    directory entries immediately, it should at least be more efficient than
    having to sort the complete list of reflogs as we only need to sort one
    directory at a time.
    
    This functionality will be used in a follow-up commit.
    
    Signed-off-by: Patrick Steinhardt <[email protected]>
    Signed-off-by: Junio C Hamano <[email protected]>
    pks-t authored and gitster committed Feb 21, 2024
    Configuration menu
    Copy the full SHA
    de34f26 View commit details
    Browse the repository at this point in the history
  3. refs/files: sort reflogs returned by the reflog iterator

    We use a directory iterator to return reflogs via the reflog iterator.
    This iterator returns entries in the same order as readdir(3P) would and
    will thus yield reflogs with no discernible order.
    
    Set the new `DIR_ITERATOR_SORTED` flag that was introduced in the
    preceding commit so that the order is deterministic. While the effect of
    this can only been observed in a test tool, a subsequent commit will
    start to expose this functionality to users via a new `git reflog list`
    subcommand.
    
    Signed-off-by: Patrick Steinhardt <[email protected]>
    Signed-off-by: Junio C Hamano <[email protected]>
    pks-t authored and gitster committed Feb 21, 2024
    Configuration menu
    Copy the full SHA
    e69e8ff View commit details
    Browse the repository at this point in the history
  4. refs/files: sort merged worktree and common reflogs

    When iterating through reflogs in a worktree we create a merged iterator
    that merges reflogs from both refdbs. The resulting refs are ordered so
    that instead we first return all worktree reflogs before we return all
    common refs.
    
    This is the only remaining case where a ref iterator returns entries in
    a non-lexicographic order. The result would look something like the
    following (listed with a command we introduce in a subsequent commit):
    
    ```
    $ git reflog list
    HEAD
    refs/worktree/per-worktree
    refs/heads/main
    refs/heads/wt
    ```
    
    So we first print the per-worktree reflogs in lexicographic order, then
    the common reflogs in lexicographic order. This is confusing and not
    consistent with how we print per-worktree refs, which are exclusively
    sorted lexicographically.
    
    Sort reflogs lexicographically in the same way as we sort normal refs.
    As this is already implemented properly by the "reftable" backend via a
    separate selection function, we simply pull out that logic and reuse it
    for the "files" backend. As logs are properly sorted now, mark the
    merged reflog iterator as sorted.
    
    Tests will be added in a subsequent commit.
    
    Signed-off-by: Patrick Steinhardt <[email protected]>
    Signed-off-by: Junio C Hamano <[email protected]>
    pks-t authored and gitster committed Feb 21, 2024
    Configuration menu
    Copy the full SHA
    6f22780 View commit details
    Browse the repository at this point in the history
  5. refs: always treat iterators as ordered

    In the preceding commit we have converted the reflog iterator of the
    "files" backend to be ordered, which was the only remaining ref iterator
    that wasn't ordered. Refactor the ref iterator infrastructure so that we
    always assume iterators to be ordered, thus simplifying the code.
    
    Signed-off-by: Patrick Steinhardt <[email protected]>
    Signed-off-by: Junio C Hamano <[email protected]>
    pks-t authored and gitster committed Feb 21, 2024
    Configuration menu
    Copy the full SHA
    5e01d83 View commit details
    Browse the repository at this point in the history
  6. refs: drop unused params from the reflog iterator callback

    The ref and reflog iterators share much of the same underlying code to
    iterate over the corresponding entries. This results in some weird code
    because the reflog iterator also exposes an object ID as well as a flag
    to the callback function. Neither of these fields do refer to the reflog
    though -- they refer to the corresponding ref with the same name. This
    is quite misleading. In practice at least the object ID cannot really be
    implemented in any other way as a reflog does not have a specific object
    ID in the first place. This is further stressed by the fact that none of
    the callbacks except for our test helper make use of these fields.
    
    Split up the infrastucture so that ref and reflog iterators use separate
    callback signatures. This allows us to drop the nonsensical fields from
    the reflog iterator.
    
    Note that internally, the backends still use the same shared infra to
    iterate over both types. As the backends should never end up being
    called directly anyway, this is not much of a problem and thus kept
    as-is for simplicity's sake.
    
    Signed-off-by: Patrick Steinhardt <[email protected]>
    Signed-off-by: Junio C Hamano <[email protected]>
    pks-t authored and gitster committed Feb 21, 2024
    Configuration menu
    Copy the full SHA
    31f8983 View commit details
    Browse the repository at this point in the history
  7. refs: stop resolving ref corresponding to reflogs

    The reflog iterator tries to resolve the corresponding ref for every
    reflog that it is about to yield. Historically, this was done due to
    multiple reasons:
    
      - It ensures that the refname is safe because we end up calling
        `check_refname_format()`. Also, non-conformant refnames are skipped
        altogether.
    
      - The iterator used to yield the resolved object ID as well as its
        flags to the callback. This info was never used though, and the
        corresponding parameters were dropped in the preceding commit.
    
      - When a ref is corrupt then the reflog is not emitted at all.
    
    We're about to introduce a new `git reflog list` subcommand that will
    print all reflogs that the refdb knows about. Skipping over reflogs
    whose refs are corrupted would be quite counterproductive in this case
    as the user would have no way to learn about reflogs which may still
    exist in their repository to help and rescue such a corrupted ref. Thus,
    the only remaining reason for why we'd want to resolve the ref is to
    verify its refname.
    
    Refactor the code to call `check_refname_format()` directly instead of
    trying to resolve the ref. This is significantly more efficient given
    that we don't have to hit the object database anymore to list reflogs.
    And second, it ensures that we end up showing reflogs of broken refs,
    which will help to make the reflog more useful.
    
    Note that this really only impacts the case where the corresponding ref
    is corrupt. Reflogs for nonexistent refs would have been returned to the
    caller beforehand already as we did not pass `RESOLVE_REF_READING` to
    the function, and thus `refs_resolve_ref_unsafe()` would have returned
    successfully in that case.
    
    Signed-off-by: Patrick Steinhardt <[email protected]>
    Signed-off-by: Junio C Hamano <[email protected]>
    pks-t authored and gitster committed Feb 21, 2024
    Configuration menu
    Copy the full SHA
    59c50a9 View commit details
    Browse the repository at this point in the history
  8. builtin/reflog: introduce subcommand to list reflogs

    While the git-reflog(1) command has subcommands to show reflog entries
    or check for reflog existence, it does not have any subcommands that
    would allow the user to enumerate all existing reflogs. This makes it
    quite hard to discover which reflogs a repository has. While this can
    be worked around with the "files" backend by enumerating files in the
    ".git/logs" directory, users of the "reftable" backend don't enjoy such
    a luxury.
    
    Introduce a new subcommand `git reflog list` that lists all reflogs the
    repository knows of to fill this gap.
    
    Signed-off-by: Patrick Steinhardt <[email protected]>
    Signed-off-by: Junio C Hamano <[email protected]>
    pks-t authored and gitster committed Feb 21, 2024
    Configuration menu
    Copy the full SHA
    d699d15 View commit details
    Browse the repository at this point in the history