Skip to content

reflog: introduce subcommand to list reflogs

Patrick Steinhardt git 3 versions – New

Get series with b4
b4 am [email protected]

Versions newest first · linked by author and title

  1. v3 Latest8 patches 0 repliesNew
  2. v27 patches 2 repliesSuperseded
  3. v16 patches 10 repliesSuperseded

Patches in v3 No applies recorded yet

#Subject and filesSizeRepliesApplied
1/8dir-iterator: pass name to `prepare_next_entry_data()` directlydir-iterator.c+4 -40 replies
2/8dir-iterator: support iteration in sorted orderdir-iterator.c dir-iterator.h+89 -130 replies
3/8refs/files: sort reflogs returned by the reflog iteratorrefs/files-backend.c t/t0600-reffiles-backend.sh t/t1405-main-ref-store.sh +1 more+6 -60 replies
4/8refs/files: sort merged worktree and common reflogsrefs/files-backend.c refs/iterator.c refs/refs-internal.h +1 more+56 -730 replies
5/8refs: always treat iterators as orderedrefs.c refs/debug.c refs/files-backend.c +5 more+20 -500 replies
6/8refs: drop unused params from the reflog iterator callbackbuiltin/fsck.c builtin/reflog.c refs.c +8 more+65 -540 replies
7/8refs: stop resolving ref corresponding to reflogsrefs/files-backend.c refs/reftable-backend.c+4 -140 replies
8/8builtin/reflog: introduce subcommand to list reflogsDocumentation/git-reflog.txt builtin/reflog.c t/t1410-reflog.sh+145 -00 replies

Reviews trailers per patch

No Reviewed-by, Acked-by or Tested-by trailers for v3 yet.

Read the v3 thread

Cover letter [PATCH v3 0/8] reflog: introduce subcommand to list reflogs

Hi,

this is the second version of my patch series that introduces a new git reflog list subcommand to list available reflogs in a repository.

There is only a single change compared to v2. Junio made me double check my assumption that the select function for reflogs yielded by the merged iterator in the "files" backend would return things lexicographically. Turns out it didn't -- instead, it returns all worktree refs first, then all common refs.

This isn't only an issue because I prematurely marked the merged iter as sorted. It's also an issue because the user-visible ordering would be quite weird when executing git reflog list in a worktree.

I've thus added another commit on top that extracts the preexisting logic to merge worktree and common refs by name from the "reftable" backend and reuses it for the "files" reflogs.

Patrick

Patrick Steinhardt (8):
dir-iterator: pass name to prepare_next_entry_data() directly
dir-iterator: support iteration in sorted order refs/files: sort reflogs returned by the reflog iterator refs/files: sort merged worktree and common reflogs
refs: always treat iterators as ordered
refs: drop unused params from the reflog iterator callback
refs: stop resolving ref corresponding to reflogs builtin/reflog: introduce subcommand to list reflogs

 Documentation/git-reflog.txt   |   3 +
 builtin/fsck.c                 |   4 +-
 builtin/reflog.c               |  37 ++++++++++-
 dir-iterator.c                 | 105 +++++++++++++++++++++++++++-----
 dir-iterator.h                 |   3 +
 refs.c                         |  27 ++++++---
 refs.h                         |  11 +++-
 refs/debug.c                   |   3 +-
 refs/files-backend.c           |  55 +++--------------
 refs/iterator.c                |  69 +++++++++++++++------
 refs/packed-backend.c          |   2 +-
 refs/ref-cache.c               |   2 +-
 refs/refs-internal.h           |  27 ++++-----
 refs/reftable-backend.c        |  67 +++-----------------
 revision.c                     |   4 +-
 t/helper/test-ref-store.c      |  18 ++++--
 t/t0600-reffiles-backend.sh    |  24 ++++----
 t/t1405-main-ref-store.sh      |   8 +--
 t/t1406-submodule-ref-store.sh |   8 +--
 t/t1410-reflog.sh              | 108 +++++++++++++++++++++++++++++++++
 20 files changed, 380 insertions(+), 205 deletions(-)

Range-diff against v2:

1:  12de25dfe2 = 1:  d474f9cf77 dir-iterator: pass name to `prepare_next_entry_data()` directly
2:  788afce189 = 2:  89cf960d47 dir-iterator: support iteration in sorted order
3:  32b24a3d4b ! 3:  8ad63eb3f6 refs/files: sort reflogs returned by the reflog iterator

@@ refs/files-backend.c: static struct ref_iterator *reflog_iterator_begin(struct r
iter->dir_iterator = diter;
iter->ref_store = ref_store;
strbuf_release(&sb);
-@@ refs/files-backend.c: static struct ref_iterator *files_reflog_iterator_begin(struct ref_store *ref_st
- return reflog_iterator_begin(ref_store, refs->gitcommondir);
- } else {
- return merge_ref_iterator_begin(
-- 0, reflog_iterator_begin(ref_store, refs->base.gitdir),
-+ 1, reflog_iterator_begin(ref_store, refs->base.gitdir),
- reflog_iterator_begin(ref_store, refs->gitcommondir),
- reflog_iterator_select, refs);
- }

## t/t0600-reffiles-backend.sh ##
@@ t/t0600-reffiles-backend.sh: test_expect_success 'for_each_reflog()' '

-:  ---------- > 4:  0b52f6c4af refs/files: sort merged worktree and common reflogs
4:  4254f23fd4 ! 5:  d44564c8b3 refs: always treat iterators as ordered
    @@ refs/files-backend.c: static struct ref_iterator *files_reflog_iterator_begin(st
     -			1, reflog_iterator_begin(ref_store, refs->base.gitdir),
     +			reflog_iterator_begin(ref_store, refs->base.gitdir),
      			reflog_iterator_begin(ref_store, refs->gitcommondir),
    - 			reflog_iterator_select, refs);
    + 			ref_iterator_select, refs);
      	}
     
      ## refs/iterator.c ##
    @@ refs/refs-internal.h: enum do_for_each_ref_flags {
      	const char *refname;
      	const struct object_id *oid;
      	unsigned int flags;
    -@@ refs/refs-internal.h: typedef enum iterator_selection ref_iterator_select_fn(
    +@@ refs/refs-internal.h: enum iterator_selection ref_iterator_select(struct ref_iterator *iter_worktree,
       * Iterate over the entries from iter0 and iter1, with the values
       * interleaved as directed by the select function. The iterator takes
       * ownership of iter0 and iter1 and frees them when the iteration is
    @@ refs/reftable-backend.c: static struct ref_iterator *reftable_be_iterator_begin(
      	worktree_iter = ref_iterator_for_stack(refs, refs->worktree_stack, prefix, flags);
     -	return merge_ref_iterator_begin(1, &worktree_iter->base, &main_iter->base,
     +	return merge_ref_iterator_begin(&worktree_iter->base, &main_iter->base,
    - 					iterator_select, NULL);
    + 					ref_iterator_select, NULL);
      }
      
     @@ refs/reftable-backend.c: static struct reftable_reflog_iterator *reflog_iterator_for_stack(struct reftabl
    @@ refs/reftable-backend.c: static struct ref_iterator *reftable_be_reflog_iterator
      
     -	return merge_ref_iterator_begin(1, &worktree_iter->base, &main_iter->base,
     +	return merge_ref_iterator_begin(&worktree_iter->base, &main_iter->base,
    - 					iterator_select, NULL);
    + 					ref_iterator_select, NULL);
      }
5:  240334df6c = 6:  c06fef8a64 refs: drop unused params from the reflog iterator callback
6:  7928661318 = 7:  fc96d5bbab refs: stop resolving ref corresponding to reflogs
7:  d7b9cff4c3 ! 8:  f3f50f3742 builtin/reflog: introduce subcommand to list reflogs
    @@ t/t1410-reflog.sh: test_expect_success 'empty reflog' '
     +	)
     +'
     +
    ++test_expect_success 'list reflogs with worktree' '
    ++	test_when_finished "rm -rf repo" &&
    ++	git init repo &&
    ++	(
    ++		cd repo &&
    ++
    ++		test_commit A &&
    ++		git worktree add wt &&
    ++		git -c core.logAllRefUpdates=always \
    ++			update-ref refs/worktree/main HEAD &&
    ++		git -c core.logAllRefUpdates=always \
    ++			update-ref refs/worktree/per-worktree HEAD &&
    ++		git -c core.logAllRefUpdates=always -C wt \
    ++			update-ref refs/worktree/per-worktree HEAD &&
    ++		git -c core.logAllRefUpdates=always -C wt \
    ++			update-ref refs/worktree/worktree HEAD &&
    ++
    ++		cat >expect <<-EOF &&
    ++		HEAD
    ++		refs/heads/main
    ++		refs/heads/wt
    ++		refs/worktree/main
    ++		refs/worktree/per-worktree
    ++		EOF
    ++		git reflog list >actual &&
    ++		test_cmp expect actual &&
    ++
    ++		cat >expect <<-EOF &&
    ++		HEAD
    ++		refs/heads/main
    ++		refs/heads/wt
    ++		refs/worktree/per-worktree
    ++		refs/worktree/worktree
    ++		EOF
    ++		git -C wt reflog list >actual &&
    ++		test_cmp expect actual
    ++	)
    ++'
    ++
     +test_expect_success 'reflog list returns error with additional args' '
     +	cat >expect <<-EOF &&
     +	error: list does not accept arguments: ${SQ}bogus${SQ}
Signature · 1 line
2.44.0-rc1