From: Karthik Nayak <karthik.188@gmail.com>
To: git@vger.kernel.org
Cc: ps@pks.im, kristofferhaugsbakk@fastmail.com, gitster@pobox.com,
Karthik Nayak <karthik.188@gmail.com>
Subject: [PATCH v3 0/2] reflog: implement subcommand to drop reflogs
Date: Fri, 14 Mar 2025 09:40:33 +0100 [thread overview]
Message-ID: <20250314-493-add-command-to-purge-reflog-entries-v3-0-c24e23a6146d@gmail.com> (raw)
In-Reply-To: <20250307-493-add-command-to-purge-reflog-entries-v1-0-84ab8529cf9e@gmail.com>
While 'git-reflog(1)' currently allows users to expire reflogs and
delete individual entries, it lacks functionality to completely remove
reflogs for specific references. This becomes problematic in
repositories where reflogs are not needed but continue to accumulate
entries despite setting 'core.logAllRefUpdates=false'.
Add a new 'drop' subcommand to git-reflog that allows users to delete
the entire reflog for a specified reference. Include a '--all' flag to
enable dropping all reflogs from all worktrees and an addon flag
'--single-worktree', to drop all reflogs from the current worktree.
The first patch is a small cleanup in 'git refs expire' which improves
the error message used when there is no reflog present for a given
reference.
Changes in v3:
- Add a preparatory commit to fix the error message in 'git reflog
expire' when a non-existent ref is provided.
- Add support for '--single-worktree' to provide feature parity with
'git reflog expire'.
- Improved error message and small code fixes.
- Added some additional tests.
- Link to v2: https://lore.kernel.org/r/20250310-493-add-command-to-purge-reflog-entries-v2-1-05caa92e0bfa@gmail.com
Changes in v2:
- Rephrase the commit message to be clearer and fix typo.
- Move the documentation to be next to 'git reflog delete' and also
add missing documentation for the '--all' flag.
- Ensure '--all' is not used with references and add a test.
- Cleanup variable assignment.
- Check for error message in the test.
- Drop the cleanup commit.
- Rebased on top of master a36e024e98 (Merge branch 'js/win-2.49-build-fixes',
2025-03-06), this was to include the adoc changes which were breaking
tests on the CI.
- Link to v1: https://lore.kernel.org/r/20250307-493-add-command-to-purge-reflog-entries-v1-0-84ab8529cf9e@gmail.com
Documentation/git-reflog.adoc | 23 ++++++--
builtin/reflog.c | 68 ++++++++++++++++++++++-
t/t1410-reflog.sh | 126 +++++++++++++++++++++++++++++++++++++++++-
3 files changed, 209 insertions(+), 8 deletions(-)
Karthik Nayak (2):
reflog: improve error for when reflog is not found
reflog: implement subcommand to drop reflogs
Range-diff versus v2:
-: ---------- > 1: d4c4bf8c99 reflog: improve error for when reflog is not found
1: 9405eaacb7 ! 2: a7f88d71da reflog: implement subcommand to drop reflogs
@@ Commit message
entries despite setting 'core.logAllRefUpdates=false'.
Add a new 'drop' subcommand to git-reflog that allows users to delete
- the entire reflog for a specified reference. Include a '--all' flag to
- enable dropping all reflogs in a repository.
+ the entire reflog for a specified reference. Include an '--all' flag to
+ enable dropping all reflogs from all worktrees and an addon flag
+ '--single-worktree', to only drop all reflogs from the current worktree.
While here, remove an extraneous newline in the file.
@@ Documentation/git-reflog.adoc: SYNOPSIS
[--dry-run | -n] [--verbose] [--all [--single-worktree] | <refs>...]
'git reflog delete' [--rewrite] [--updateref]
[--dry-run | -n] [--verbose] <ref>@{<specifier>}...
-+'git reflog drop' [--all | <refs>...]
++'git reflog drop' [--all [--single-worktree] | <refs>...]
'git reflog exists' <ref>
DESCRIPTION
@@ Documentation/git-reflog.adoc: and not reachable from the current tip, are remov
+not the reflog itself. Its argument must be an _exact_ entry (e.g. "`git
+reflog delete master@{2}`"). This subcommand is also typically not used
+directly by end users.
-
- The "exists" subcommand checks whether a ref has a reflog. It exits
- with zero status if the reflog exists, and non-zero status if it does
- not.
-
++
+The "drop" subcommand completely removes the reflog for the specified
+references. This is in contrast to "expire" and "delete", both of which
+can be used to delete reflog entries, but not the reflog itself.
-+
- OPTIONS
- -------
+ The "exists" subcommand checks whether a ref has a reflog. It exits
+ with zero status if the reflog exists, and non-zero status if it does
@@ Documentation/git-reflog.adoc: Options for `delete`
`--dry-run`, and `--verbose`, with the same meanings as when they are
used with `expire`.
@@ Documentation/git-reflog.adoc: Options for `delete`
+
+--all::
+ Drop the reflogs of all references from all worktrees.
++
++--single-worktree::
++ By default when `--all` is specified, reflogs from all working
++ trees are dropped. This option limits the processing to reflogs
++ from the current working tree only.
GIT
---
@@ builtin/reflog.c
N_("git reflog exists <ref>")
+#define BUILTIN_REFLOG_DROP_USAGE \
-+ N_("git reflog drop [--all | <refs>...]")
++ N_("git reflog drop [--all [--single-worktree] | <refs>...]")
+
static const char *const reflog_show_usage[] = {
BUILTIN_REFLOG_SHOW_USAGE,
@@ builtin/reflog.c: static int cmd_reflog_exists(int argc, const char **argv, cons
+static int cmd_reflog_drop(int argc, const char **argv, const char *prefix,
+ struct repository *repo)
+{
-+ int ret = 0, do_all = 0;
++ int ret = 0, do_all = 0, single_worktree = 0;
+ const struct option options[] = {
-+ OPT_BOOL(0, "all", &do_all, N_("process the reflogs of all references")),
++ OPT_BOOL(0, "all", &do_all, N_("drop the reflogs of all references")),
++ OPT_BOOL(0, "single-worktree", &single_worktree,
++ N_("drop reflogs from the current worktree only")),
+ OPT_END()
+ };
+
+ argc = parse_options(argc, argv, prefix, options, reflog_drop_usage, 0);
+
+ if (argc && do_all)
-+ die(_("references specified along with --all"));
++ usage(_("references specified along with --all"));
+
+ if (do_all) {
+ struct worktree_reflogs collected = {
@@ builtin/reflog.c: static int cmd_reflog_exists(int argc, const char **argv, cons
+
+ worktrees = get_worktrees();
+ for (p = worktrees; *p; p++) {
++ if (single_worktree && !(*p)->is_current)
++ continue;
+ collected.worktree = *p;
+ refs_for_each_reflog(get_worktree_ref_store(*p),
+ collect_reflog, &collected);
@@ builtin/reflog.c: static int cmd_reflog_exists(int argc, const char **argv, cons
+ ret |= refs_delete_reflog(get_main_ref_store(repo),
+ item->string);
+ string_list_clear(&collected.reflogs, 0);
++
++ return ret;
+ }
+
+ for (int i = 0; i < argc; i++) {
+ char *ref;
+ if (!repo_dwim_log(repo, argv[i], strlen(argv[i]), NULL, &ref)) {
-+ ret |= error(_("%s points nowhere!"), argv[i]);
++ ret |= error(_("reflog could not be found: '%s'"), argv[i]);
+ continue;
+ }
+
@@ t/t1410-reflog.sh: test_expect_success 'reflog with invalid object ID can be lis
+ cd repo &&
+ test_must_fail git reflog exists refs/heads/non-existent &&
+ test_must_fail git reflog drop refs/heads/non-existent 2>stderr &&
-+ test_grep "error: refs/heads/non-existent points nowhere!" stderr
++ test_grep "error: reflog could not be found: ${SQ}refs/heads/non-existent${SQ}" stderr
+ )
+'
+
@@ t/t1410-reflog.sh: test_expect_success 'reflog with invalid object ID can be lis
+ )
+'
+
++test_expect_success 'reflog drop multiple references some non-existent' '
++ test_when_finished "rm -rf repo" &&
++ git init repo &&
++ (
++ cd repo &&
++ test_commit A &&
++ test_commit_bulk --ref=refs/heads/branch 1 &&
++ git reflog exists refs/heads/main &&
++ git reflog exists refs/heads/branch &&
++ test_must_fail git reflog exists refs/heads/non-existent &&
++ test_must_fail git reflog drop refs/heads/main refs/heads/non-existent refs/heads/branch 2>stderr &&
++ test_must_fail git reflog exists refs/heads/main &&
++ test_must_fail git reflog exists refs/heads/branch &&
++ test_must_fail git reflog exists refs/heads/non-existent &&
++ test_grep "error: reflog could not be found: ${SQ}refs/heads/non-existent${SQ}" stderr
++ )
++'
++
+test_expect_success 'reflog drop --all' '
+ test_when_finished "rm -rf repo" &&
+ git init repo &&
@@ t/t1410-reflog.sh: test_expect_success 'reflog with invalid object ID can be lis
+ )
+'
+
++test_expect_success 'reflog drop --all multiple worktrees' '
++ test_when_finished "rm -rf repo" &&
++ test_when_finished "rm -rf wt" &&
++ git init repo &&
++ (
++ cd repo &&
++ test_commit A &&
++ git worktree add ../wt &&
++ test_commit_bulk -C ../wt --ref=refs/heads/branch 1 &&
++ git reflog exists refs/heads/main &&
++ git reflog exists refs/heads/branch &&
++ git reflog drop --all &&
++ test_must_fail git reflog exists refs/heads/main &&
++ test_must_fail git reflog exists refs/heads/branch
++ )
++'
++
++test_expect_success 'reflog drop --all --single-worktree' '
++ test_when_finished "rm -rf repo" &&
++ test_when_finished "rm -rf wt" &&
++ git init repo &&
++ (
++ cd repo &&
++ test_commit A &&
++ git worktree add ../wt &&
++ test_commit -C ../wt foobar &&
++ git reflog exists refs/heads/main &&
++ git reflog exists refs/heads/wt &&
++ test-tool ref-store worktree:wt reflog-exists HEAD &&
++ git reflog drop --all --single-worktree &&
++ test_must_fail git reflog exists refs/heads/main &&
++ test_must_fail git reflog exists refs/heads/wt &&
++ test_must_fail test-tool ref-store worktree:main reflog-exists HEAD &&
++ test-tool ref-store worktree:wt reflog-exists HEAD
++ )
++'
++
+test_expect_success 'reflog drop --all with reference' '
+ test_when_finished "rm -rf repo" &&
+ git init repo &&
@@ t/t1410-reflog.sh: test_expect_success 'reflog with invalid object ID can be lis
+ cd repo &&
+ test_commit A &&
+ test_must_fail git reflog drop --all refs/heads/main 2>stderr &&
-+ test_grep "fatal: references specified along with --all" stderr
++ test_grep "usage: references specified along with --all" stderr
+ )
+'
+
base-commit: a36e024e989f4d35f35987a60e3af8022cac3420
change-id: 20250306-493-add-command-to-purge-reflog-entries-bd22547ad34a
Thanks
- Karthik
next prev parent reply other threads:[~2025-03-14 8:40 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-07 11:17 [PATCH 0/2] EDITME: cover title for 493-add-command-to-purge-reflog-entries Karthik Nayak
2025-03-07 11:17 ` [PATCH 1/2] reflog: drop usage of global variables Karthik Nayak
2025-03-07 21:19 ` Junio C Hamano
2025-03-10 11:41 ` Karthik Nayak
2025-03-10 15:24 ` Junio C Hamano
2025-03-13 13:30 ` Karthik Nayak
2025-03-07 11:17 ` [PATCH 2/2] reflog: implement subcommand to drop reflogs Karthik Nayak
2025-03-07 11:50 ` Patrick Steinhardt
2025-03-07 12:53 ` Karthik Nayak
2025-03-07 12:59 ` Patrick Steinhardt
2025-03-07 13:28 ` Karthik Nayak
2025-03-07 13:28 ` Karthik Nayak
2025-03-07 21:28 ` Junio C Hamano
2025-03-10 11:28 ` Karthik Nayak
2025-03-10 7:39 ` [PATCH 0/2] EDITME: cover title for 493-add-command-to-purge-reflog-entries Kristoffer Haugsbakk
2025-03-10 12:34 ` Karthik Nayak
2025-03-10 15:28 ` Junio C Hamano
2025-03-10 12:36 ` [PATCH v2] reflog: implement subcommand to drop reflogs Karthik Nayak
2025-03-12 7:15 ` Patrick Steinhardt
2025-03-13 14:24 ` Karthik Nayak
2025-03-13 14:45 ` Patrick Steinhardt
2025-03-14 8:40 ` Karthik Nayak [this message]
2025-03-14 8:40 ` [PATCH v3 1/2] reflog: improve error for when reflog is not found Karthik Nayak
2025-03-14 8:40 ` [PATCH v3 2/2] reflog: implement subcommand to drop reflogs Karthik Nayak
2025-03-18 14:01 ` Christian Couder
2025-03-18 17:44 ` Junio C Hamano
2025-03-19 8:17 ` Christian Couder
2025-03-19 9:06 ` Karthik Nayak
2025-03-18 15:56 ` Toon Claes
2025-03-19 9:16 ` Karthik Nayak
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250314-493-add-command-to-purge-reflog-entries-v3-0-c24e23a6146d@gmail.com \
--to=karthik.188@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=kristofferhaugsbakk@fastmail.com \
--cc=ps@pks.im \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).