git/list[1] front-page[2] threads[3] people[4] search[5] about
 

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

From
Patrick Steinhardt <ps@pks.im>
Date
Feb 21, 2024, 12:37 UTC
Message-ID
<cover.1708518982.git.ps@pks.im>
In-Reply-To
<cover.1708353264.git.ps@pks.im>
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}
-- 
2.44.0-rc1
Previous: Patrick SteinhardtNext: Patrick Steinhardt
Message 31 of 39 in “reflog: introduce subcommand to list reflogs”
  1. 0/6 reflog: introduce subcommand to list reflogsPatrick Steinhardt, Feb 19, 2024
  2. 1/6 dir-iterator: pass name to `prepare_next_entry_data()` directlyPatrick Steinhardt, Feb 19, 2024
  3. 2/6 dir-iterator: support iteration in sorted orderPatrick Steinhardt, Feb 19, 2024
  4. Junio C HamanoFeb 19, 2024
  5. Patrick SteinhardtFeb 20, 2024
  6. 3/6 refs/files: sort reflogs returned by the reflog iteratorPatrick Steinhardt, Feb 19, 2024
  7. Junio C HamanoFeb 20, 2024
  8. Patrick SteinhardtFeb 20, 2024
  9. 4/6 refs: drop unused params from the reflog iterator callbackPatrick Steinhardt, Feb 19, 2024
  10. Junio C HamanoFeb 20, 2024
  11. Patrick SteinhardtFeb 20, 2024
  12. 5/6 refs: stop resolving ref corresponding to reflogsPatrick Steinhardt, Feb 19, 2024
  13. Junio C HamanoFeb 20, 2024
  14. Patrick SteinhardtFeb 20, 2024
  15. 6/6 builtin/reflog: introduce subcommand to list reflogsPatrick Steinhardt, Feb 19, 2024
  16. Junio C HamanoFeb 20, 2024
  17. Patrick SteinhardtFeb 20, 2024
  18. 0/7 reflog: introduce subcommand to list reflogsPatrick Steinhardt, Feb 20, 2024
  19. 1/7 dir-iterator: pass name to `prepare_next_entry_data()` directlyPatrick Steinhardt, Feb 20, 2024
  20. 2/7 dir-iterator: support iteration in sorted orderPatrick Steinhardt, Feb 20, 2024
  21. 3/7 refs/files: sort reflogs returned by the reflog iteratorPatrick Steinhardt, Feb 20, 2024
  22. 4/7 refs: always treat iterators as orderedPatrick Steinhardt, Feb 20, 2024
  23. 5/7 refs: drop unused params from the reflog iterator callbackPatrick Steinhardt, Feb 20, 2024
  24. 6/7 refs: stop resolving ref corresponding to reflogsPatrick Steinhardt, Feb 20, 2024
  25. 7/7 builtin/reflog: introduce subcommand to list reflogsPatrick Steinhardt, Feb 20, 2024
  26. 7/7 builtin/reflog: introduce subcommand to list reflogsTeng Long, Apr 24, 2024
  27. Patrick SteinhardtApr 24, 2024
  28. Junio C HamanoApr 24, 2024
  29. Junio C HamanoFeb 20, 2024
  30. Patrick SteinhardtFeb 21, 2024
  31. 0/8 reflog: introduce subcommand to list reflogsPatrick Steinhardt, Feb 21, 2024
  32. 1/8 dir-iterator: pass name to `prepare_next_entry_data()` directlyPatrick Steinhardt, Feb 21, 2024
  33. 2/8 dir-iterator: support iteration in sorted orderPatrick Steinhardt, Feb 21, 2024
  34. 3/8 refs/files: sort reflogs returned by the reflog iteratorPatrick Steinhardt, Feb 21, 2024
  35. 4/8 refs/files: sort merged worktree and common reflogsPatrick Steinhardt, Feb 21, 2024
  36. 5/8 refs: always treat iterators as orderedPatrick Steinhardt, Feb 21, 2024
  37. 6/8 refs: drop unused params from the reflog iterator callbackPatrick Steinhardt, Feb 21, 2024
  38. 7/8 refs: stop resolving ref corresponding to reflogsPatrick Steinhardt, Feb 21, 2024
  39. 8/8 builtin/reflog: introduce subcommand to list reflogsPatrick Steinhardt, Feb 21, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.