Git development
 help / color / mirror / Atom feed
From: "Harald Nordgren via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Kristoffer Haugsbakk <kristofferhaugsbakk@fastmail.com>,
	"D. Ben Knoble" <ben.knoble@gmail.com>,
	Phillip Wood <phillip.wood123@gmail.com>,
	Harald Nordgren <haraldnordgren@gmail.com>
Subject: [PATCH v5 0/2] reflog: add format %gb
Date: Sat, 07 Nov 2026 11:55:34 +0000	[thread overview]
Message-ID: <pull.2448.v5.git.git.1794052536.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.2448.git.git.1792070038.gitgitgadget@gmail.com>

Create a better reflog. Follows the discussion in
https://lore.kernel.org/git/akZfm-igZKeHaDST@pks.im/.

The reflog of HEAD records the work done on every branch, so "git reflog"
mixes them and does not say which entry was made on which branch. This adds
a "%gb" placeholder that names the branch HEAD was on when each entry was
recorded:

$ git log -g --format='%h %gd: (%gb) %gs'
9c8d7e6 HEAD@{0}: (topic) rebase (finish): returning to refs/heads/topic
1a2b3c4 HEAD@{2}: (topic) rebase (start): checkout main
1a2b3c4 HEAD@{3}: (main) commit: fix typo


It follows branch switches, branch renames and rebases, including "git
rebase ", rebases of a detached HEAD and rebases of a branch that was
already up to date. When HEAD was detached, the entry shows "detached at ".

Changes in v5:

 * detached at <commit> now names the commit HEAD was detached at, or for a
   detached rebase, the commit it ended on.
 * git rebase <upstream> <rev> counts <rev> as a branch only if
   refs/heads/<rev> exists, so origin/main and refs/heads/main show as
   detached.
 * A commit whose subject starts with checkout is no longer taken for a
   rebase checkout.
 * Added Phillip's test, and tests for a detached rebase that fast-forwards
   and one that is aborted.

Changes in v4:

 * %gb now names the right branch when git rebase <upstream> <branch> runs
   with GIT_REFLOG_ACTION set.
 * Reworded the %gb commit message.

Changes in v3:

 * Dropped --operations.
 * Replaced --historical-branch with a %gb placeholder for --format, e.g.
   git log -g --format='%h %gd: (%gb) %gs'.
 * %gb names the right branch after git rebase <upstream> <branch>, a rebase
   of a detached HEAD and an up-to-date rebase.
 * Named the returning to and checkout reflog strings in reflog.h too.

Changes in v2:

 * Move the "historical branch" rightward in the display for cleaner
   alignment.
 * Improve commit messages.

Harald Nordgren (2):
  reflog: name the strings that mark switches, renames and rebase steps
  pretty: add %gb to name the branch of each reflog entry

 Documentation/pretty-formats.adoc |   3 +
 builtin/branch.c                  |   3 +-
 builtin/checkout.c                |   3 +-
 builtin/rebase.c                  |  19 +--
 object-name.c                     |   3 +-
 pretty.c                          |   4 +
 reflog-walk.c                     | 217 +++++++++++++++++++++++++++-
 reflog-walk.h                     |   2 +
 reflog.h                          |   9 ++
 sequencer.c                       |  15 +-
 t/t1414-reflog-walk.sh            | 229 ++++++++++++++++++++++++++++++
 wt-status.c                       |   3 +-
 12 files changed, 484 insertions(+), 26 deletions(-)


base-commit: fb255012acbcbe81189cb8014da0280b09c66ecc
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2448%2FHaraldNordgren%2Freflog-operations-v5
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2448/HaraldNordgren/reflog-operations-v5
Pull-Request: https://github.com/git/git/pull/2448

Range-diff vs v4:

 1:  f960a24b8b ! 1:  115b5a81b7 reflog: name the strings that mark switches, renames and rebase steps
     @@ Commit message
          messages are written or read: the "checkout: moving from " prefix
          written by "git checkout", the "Branch: renamed " prefix written by
          "git branch -m", and the "start", "finish" and "abort" steps, the
     -    "returning to " before the branch a rebase goes back to and the
     -    "checkout " before what it checks out, all written by "git rebase".
     +    "returning to " before the branch a rebase goes back to, the
     +    "checkout " before what it checks out and the "fast-forward" it
     +    records when a commit can be reused, all written by "git rebase".
      
          No change in behavior.
      
     @@ reflog.h
      +#define REFLOG_STEP_ABORT "abort"
      +#define REFLOG_RETURNING_TO "returning to "
      +#define REFLOG_CHECKOUT "checkout "
     ++#define REFLOG_FAST_FORWARD "fast-forward"
      +
       #define REFLOG_EXPIRE_TOTAL   (1 << 0)
       #define REFLOG_EXPIRE_UNREACH (1 << 1)
     @@ sequencer.c
       #include "sparse-index.h"
       #include "strvec.h"
       #include "quote.h"
     +@@ sequencer.c: static int fast_forward_to(struct repository *r,
     + 	if (checkout_fast_forward(r, from, to, 1))
     + 		return -1; /* the callee should have complained already */
     + 
     +-	strbuf_addf(&sb, "%s: fast-forward", action_name(opts));
     ++	strbuf_addf(&sb, "%s: " REFLOG_FAST_FORWARD, action_name(opts));
     + 
     + 	transaction = ref_store_transaction_begin(get_main_ref_store(the_repository),
     + 						  0, &err);
      @@ sequencer.c: static int checkout_onto(struct repository *r, struct replay_opts *opts,
       			 RESET_WORKING_TREE_UPDATE_HEAD |
       			 RESET_WORKING_TREE_UPDATE_ORIG_HEAD |
 2:  99a1047702 ! 2:  34bb930908 pretty: add %gb to name the branch of each reflog entry
     @@ Commit message
          The branch is read from the entries created by branch switches,
          branch renames and rebases. The entries of a rebase are labeled with
          the branch being rebased. When HEAD was detached, the entry shows
     -    "detached at <commit>" with the commit HEAD was at when it moved on.
     +    "detached at <commit>" with the commit HEAD was detached at, or for a
     +    rebase of a detached HEAD the commit the rebase ended on. These
     +    entries only record what was typed, so when no newer entry says
     +    otherwise, a name counts as a branch if a branch of that name exists.
          When nothing older in the reflog says which branch a rebase started
          on, the rebase is taken to have started on the branch it rebased. For
          the reflog of any other ref, "%gb" is the name of that ref.
     @@ reflog-walk.c: static void complete_reflogs_clear(void *util, const char *str UN
       	free_complete_reflog(array);
       }
       
     -+static char *branch_label(const char *name, size_t len,
     -+			  const struct object_id *oid)
     -+{
     -+	if (name) {
     -+		struct object_id hex_oid;
     -+		char *branch;
     -+
     -+		if (skip_prefix(name, "refs/heads/", &name))
     -+			len -= strlen("refs/heads/");
     -+		branch = xmemdupz(name, len);
     -+		if (strcmp(branch, "HEAD") && get_oid_hex(branch, &hex_oid) &&
     -+		    !check_refname_format(branch, REFNAME_ALLOW_ONELEVEL))
     -+			return branch;
     -+		free(branch);
     -+	}
     -+	return xstrfmt("detached at %s",
     -+		       repo_find_unique_abbrev(the_repository, oid,
     -+					       DEFAULT_ABBREV));
     -+}
     -+
      +static const char *skip_rebase_step(const char *message, const char *step)
      +{
      +	const char *p = strstr(message, " (");
     @@ reflog-walk.c: static void complete_reflogs_clear(void *util, const char *str UN
      +	return p;
      +}
      +
     -+static const char *skip_rebase_checkout(const char *message)
     ++static bool is_commit_subject(const char *text, const struct object_id *oid)
      +{
     -+	const char *p = strstr(message, " (");
     -+	const char *colon = strstr(message, ": ");
     ++	struct commit *commit = lookup_commit_reference_gently(the_repository,
     ++							       oid, 1);
     ++	const char *buffer, *subject;
     ++	size_t len;
     ++	bool ret;
     ++
     ++	if (!commit)
     ++		return false;
     ++	buffer = repo_get_commit_buffer(the_repository, commit, NULL);
     ++	len = find_commit_subject(buffer, &subject);
     ++	ret = strcspn(text, "\n") == len && !memcmp(text, subject, len);
     ++	repo_unuse_commit_buffer(the_repository, commit, buffer);
     ++	return ret;
     ++}
      +
     -+	if (!colon || (p && p < colon) ||
     -+	    !skip_prefix(colon + 2, REFLOG_CHECKOUT, &p))
     ++static const char *skip_rebase_checkout(const struct reflog_info *item)
     ++{
     ++	const char *colon = strstr(item->message, ": ");
     ++	const char *rev;
     ++
     ++	if (!colon || !skip_prefix(colon + 2, REFLOG_CHECKOUT, &rev) ||
     ++	    is_commit_subject(colon + 2, &item->noid))
      +		return NULL;
     -+	return p;
     ++	return rev;
     ++}
     ++
     ++static const char *existing_branch(const char *name)
     ++{
     ++	char *ref = xstrfmt("refs/heads/%.*s", (int)strcspn(name, "\n"), name);
     ++	bool exists = refs_ref_exists(get_main_ref_store(the_repository), ref);
     ++
     ++	free(ref);
     ++	return exists ? name : NULL;
      +}
      +
      +struct branch_move {
      +	const char *from, *to;
      +	size_t from_len, to_len;
     ++	bool from_detached;
      +};
      +
     -+static bool parse_branch_move(const char *message, struct branch_move *move)
     ++static bool parse_branch_move(const struct reflog_info *item,
     ++			      struct branch_move *move)
      +{
     -+	const char *to;
     ++	const char *message = item->message;
     ++	const char *from, *to, *end;
     ++	struct object_id oid;
      +
     -+	move->from = move->to = NULL;
     -+	move->from_len = move->to_len = 0;
     -+	if (skip_prefix(message, REFLOG_SWITCH_PREFIX, &move->from) ||
     -+	    skip_prefix(message, REFLOG_RENAME_PREFIX, &move->from)) {
     -+		to = strstr(move->from, " to ");
     ++	memset(move, 0, sizeof(*move));
     ++	if (skip_prefix(message, REFLOG_SWITCH_PREFIX, &from)) {
     ++		to = strstr(from, " to ");
      +		if (!to)
      +			return false;
     -+		move->from_len = to - move->from;
     -+		move->to = to + strlen(" to ");
     ++		if (!parse_oid_hex(from, &oid, &end) && end == to) {
     ++			move->from_detached = true;
     ++		} else {
     ++			move->from = from;
     ++			move->from_len = to - from;
     ++		}
     ++		move->to = existing_branch(to + strlen(" to "));
     ++	} else if (skip_prefix(message, REFLOG_RENAME_PREFIX "refs/heads/",
     ++			       &from)) {
     ++		to = strstr(from, " to refs/heads/");
     ++		if (!to)
     ++			return false;
     ++		move->from = from;
     ++		move->from_len = to - from;
     ++		move->to = to + strlen(" to refs/heads/");
      +	} else if (((to = skip_rebase_step(message, REFLOG_STEP_FINISH)) ||
      +		    (to = skip_rebase_step(message, REFLOG_STEP_ABORT))) &&
     -+		   skip_prefix(to, REFLOG_RETURNING_TO, &to)) {
     ++		   skip_prefix(to, REFLOG_RETURNING_TO "refs/heads/", &to)) {
      +		move->from = move->to = to;
      +		move->from_len = strcspn(to, "\n");
     -+	} else if ((to = skip_rebase_checkout(message))) {
     -+		move->to = to;
     -+	} else if (!skip_rebase_step(message, REFLOG_STEP_START)) {
     ++	} else if (skip_rebase_step(message, REFLOG_STEP_START)) {
     ++		return true;
     ++	} else if ((to = skip_rebase_checkout(item))) {
     ++		move->to = existing_branch(to);
     ++	} else {
      +		return false;
      +	}
      +	if (move->to)
     @@ reflog-walk.c: static void complete_reflogs_clear(void *util, const char *str UN
      +	return true;
      +}
      +
     ++static char *detached_label(const struct complete_reflogs *array,
     ++			    int i, int end)
     ++{
     ++	const struct reflog_info *item = &array->items[i];
     ++
     ++	if (skip_rebase_step(item->message, REFLOG_STEP_START)) {
     ++		size_t len = strstr(item->message, " (") + 2 - item->message;
     ++
     ++		for (int j = end - 1; j > i; j--) {
     ++			const char *message = array->items[j].message;
     ++
     ++			if (!strncmp(message, item->message, len) ||
     ++			    starts_with(message,
     ++					"rebase: " REFLOG_FAST_FORWARD)) {
     ++				item = &array->items[j];
     ++				break;
     ++			}
     ++		}
     ++	}
     ++	return xstrfmt("detached at %s",
     ++		       repo_find_unique_abbrev(the_repository, &item->noid,
     ++					       DEFAULT_ABBREV));
     ++}
     ++
      +static void mark_branches(struct complete_reflogs *array)
      +{
      +	struct ref_store *refs = get_main_ref_store(the_repository);
     -+	struct object_id oid;
     -+	const char *head = refs_resolve_ref_unsafe(refs, "HEAD", 0, &oid, NULL);
     ++	const char *head = refs_resolve_ref_unsafe(refs, "HEAD", 0, NULL, NULL);
      +	char *branch = NULL;
     -+	int unknown = array->nr;
     ++	bool detached = false;
     ++	int unlabeled = array->nr;
      +
     -+	if (head)
     -+		branch = branch_label(head, strlen(head), &oid);
     ++	if (head && skip_prefix(head, "refs/heads/", &head))
     ++		branch = xstrdup(head);
     ++	else if (head)
     ++		detached = true;
      +
      +	for (int i = array->nr - 1; i >= 0; i--) {
      +		struct reflog_info *item = &array->items[i];
      +		struct branch_move move;
      +
     -+		if (!parse_branch_move(item->message, &move)) {
     ++		if (!parse_branch_move(item, &move)) {
      +			item->branch = xstrdup_or_null(branch);
      +			continue;
      +		}
      +
      +		if (!branch) {
     -+			branch = branch_label(move.to, move.to_len,
     -+					      &array->items[unknown - 1].noid);
     -+			for (int j = i + 1; j < unknown; j++)
     ++			branch = move.to && !detached ?
     ++				xmemdupz(move.to, move.to_len) :
     ++				detached_label(array, i, unlabeled);
     ++			for (int j = i + 1; j < unlabeled; j++)
      +				array->items[j].branch = xstrdup(branch);
      +		}
      +		item->branch = branch;
     -+		if (move.from) {
     -+			branch = branch_label(move.from, move.from_len,
     -+					      &item->ooid);
     -+		} else {
     -+			branch = NULL;
     -+			unknown = i;
     -+		}
     ++		branch = move.from ? xmemdupz(move.from, move.from_len) : NULL;
     ++		detached = move.from_detached;
     ++		unlabeled = i;
      +	}
      +
     -+	if (!branch && unknown < array->nr)
     -+		for (int i = 0; i < unknown; i++)
     -+			array->items[i].branch =
     -+				xstrdup(array->items[unknown].branch);
     ++	if (!branch) {
     ++		if (detached)
     ++			branch = detached_label(array, 0, unlabeled);
     ++		else if (unlabeled < array->nr)
     ++			branch = xstrdup(array->items[unlabeled].branch);
     ++		for (int i = 0; branch && i < unlabeled; i++)
     ++			array->items[i].branch = xstrdup(branch);
     ++	}
      +	free(branch);
      +}
      +
     @@ t/t1414-reflog-walk.sh: test_expect_success 'walk prefers reflog to ref tip' '
      +	)
      +'
      +
     -+test_expect_success '%gb names a detached HEAD by the commit it was left at' '
     ++test_expect_success '%gb names a detached HEAD by the commit it was detached at' '
      +	(
      +		cd branches &&
      +		git switch --detach topic~1 &&
     ++		detached_at=$(git rev-parse --short HEAD) &&
      +		test_commit detached &&
      +		git rebase topic &&
      +		rebased=$(git rev-parse HEAD) &&
      +		git switch topic &&
      +
     -+		left_before=$(git rev-parse --short detached) &&
     -+		left_after=$(git rev-parse --short $rebased) &&
     ++		rebased_at=$(git rev-parse --short $rebased) &&
      +		cat >expect <<-EOF &&
      +		(topic) checkout: moving from $rebased to topic
     -+		(detached at $left_after) rebase (pick): detached
     -+		(detached at $left_after) rebase (start): checkout topic
     -+		(detached at $left_before) commit: detached
     -+		(detached at $left_before) checkout: moving from topic to topic~1
     ++		(detached at $rebased_at) rebase (pick): detached
     ++		(detached at $rebased_at) rebase (start): checkout topic
     ++		(detached at $detached_at) commit: detached
     ++		(detached at $detached_at) checkout: moving from topic to topic~1
      +		EOF
      +		git log -g -5 --format="(%gb) %gs" >actual &&
      +		test_cmp expect actual
      +	)
      +'
      +
     -+test_expect_success '%gb names the branch of a "git pull --rebase" in a fresh clone' '
     -+	git clone branches downstream &&
     ++test_expect_success '%gb names a detached rebase by the commit it ended on' '
     ++	write_script add-exec <<-\EOF &&
     ++	{ echo "exec true" && cat "$1"; } >"$1.new" &&
     ++	mv "$1.new" "$1"
     ++	EOF
      +	(
      +		cd branches &&
     -+		test_commit upstream-change
     -+	) &&
     ++		git switch --detach topic^0 &&
     ++		test_set_sequence_editor "$TRASH_DIRECTORY/add-exec" &&
     ++		git rebase -i @^ &&
     ++		ended_at=$(git rev-parse --short HEAD) &&
     ++		test_commit after-fast-forward &&
     ++
     ++		cat >expect <<-EOF &&
     ++		(detached at $ended_at) commit: after-fast-forward
     ++		(detached at $ended_at) rebase: fast-forward
     ++		(detached at $ended_at) rebase (start): checkout @^
     ++		EOF
     ++		git log -g -3 --format="(%gb) %gs" >actual &&
     ++		test_cmp expect actual
     ++	)
     ++'
     ++
     ++test_expect_success '%gb names an aborted rebase of a detached HEAD' '
      +	(
     -+		cd downstream &&
     -+		test_commit local-change &&
     -+		git pull --rebase &&
     ++		cd branches &&
     ++		git switch --detach topic^0 &&
     ++		test_must_fail git rebase -f -x false @^ &&
     ++		git rebase --abort &&
     ++		returned_to=$(git rev-parse HEAD) &&
     ++		short=$(git rev-parse --short HEAD) &&
      +
     -+		echo "(topic)" >expect &&
     -+		git log -g --format="(%gb)" >out &&
     -+		sort -u out >actual &&
     ++		cat >expect <<-EOF &&
     ++		(detached at $short) rebase (abort): returning to $returned_to
     ++		(detached at $short) rebase (pick): B
     ++		(detached at $short) rebase (start): checkout @^
     ++		EOF
     ++		git log -g -3 --format="(%gb) %gs" >actual &&
      +		test_cmp expect actual
      +	)
      +'
     @@ t/t1414-reflog-walk.sh: test_expect_success 'walk prefers reflog to ref tip' '
      +test_expect_success '%gb follows a renamed branch' '
      +	(
      +		cd branches &&
     ++		git switch topic &&
      +		test_commit before-rename &&
      +		git branch -m topic renamed &&
      +		test_commit after-rename &&
     @@ t/t1414-reflog-walk.sh: test_expect_success 'walk prefers reflog to ref tip' '
      +		test_cmp expect actual
      +	)
      +'
     ++
     ++test_expect_success '%gb labels branches and detached HEADs' '
     ++	test_create_repo origin &&
     ++	(
     ++		cd origin &&
     ++		test_commit O1 &&
     ++		test_commit O2
     ++	) &&
     ++	git clone origin downstream &&
     ++	(
     ++		cd origin &&
     ++		test_commit O3
     ++	) &&
     ++	(
     ++		cd downstream &&
     ++		test_commit L1 &&
     ++		git branch side &&
     ++		test_commit L2 &&
     ++		git pull -r "file://$TRASH_DIRECTORY/origin" &&
     ++		test_commit L3 &&
     ++		GIT_REFLOG_ACTION="sync switch" git rebase -i FETCH_HEAD side^0 &&
     ++		H1=$(git rev-parse --short HEAD) &&
     ++		test_commit "checkout main" L4.t L4 L4 &&
     ++		git rebase FETCH_HEAD side &&
     ++		test_commit L5 &&
     ++		git rebase origin/main origin/main &&
     ++		H2=$(git rev-parse --short HEAD) &&
     ++		test_commit L6 &&
     ++		git rebase main refs/heads/main &&
     ++		H3=$(git rev-parse --short HEAD) &&
     ++		test_commit L7 &&
     ++		git switch side &&
     ++		test_commit L8 &&
     ++		git checkout origin/main &&
     ++		H4=$(git rev-parse --short HEAD) &&
     ++		test_commit L9 &&
     ++
     ++		cat >expect <<-EOF &&
     ++		commit: L9 (detached at $H4)
     ++		checkout: moving from side to origin/main (detached at $H4)
     ++		commit: L8 (side)
     ++		checkout: moving from $(git rev-parse L7) to side (side)
     ++		commit: L7 (detached at $H3)
     ++		rebase: checkout refs/heads/main (detached at $H3)
     ++		commit: L6 (detached at $H2)
     ++		rebase: checkout origin/main (detached at $H2)
     ++		commit: L5 (side)
     ++		rebase (finish): returning to refs/heads/side (side)
     ++		rebase (pick): L1 (side)
     ++		rebase (start): checkout FETCH_HEAD (side)
     ++		commit: checkout main (detached at $H1)
     ++		sync switch (pick): L1 (detached at $H1)
     ++		sync switch (start): checkout FETCH_HEAD (detached at $H1)
     ++		commit: L3 (main)
     ++		pull -r file://$TRASH_DIRECTORY/origin (finish): returning to refs/heads/main (main)
     ++		pull -r file://$TRASH_DIRECTORY/origin (pick): L2 (main)
     ++		pull -r file://$TRASH_DIRECTORY/origin (pick): L1 (main)
     ++		pull -r file://$TRASH_DIRECTORY/origin (start): checkout $(git rev-parse FETCH_HEAD) (main)
     ++		commit: L2 (main)
     ++		commit: L1 (main)
     ++		clone: from $(cd ../origin && pwd) (main)
     ++		EOF
     ++
     ++		git log -g --format="%gs (%gb)" >actual &&
     ++		test_cmp expect actual
     ++	)
     ++'
      +
       test_expect_success 'rev-list -g complains when there are no reflogs' '
       	test_must_fail git rev-list -g

-- 
gitgitgadget

  parent reply	other threads:[~2026-11-07 11:55 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-15 13:13 [PATCH 0/3] reflog: add --operations and --historical-branch Harald Nordgren via GitGitGadget
2026-10-15 13:13 ` [PATCH 1/3] reflog: name the strings that mark switches, renames and rebase steps Harald Nordgren via GitGitGadget
2026-10-15 14:35   ` Kristoffer Haugsbakk
2026-10-15 20:52     ` Harald Nordgren
2026-10-15 13:13 ` [PATCH 2/3] reflog: add --operations to show one entry per command Harald Nordgren via GitGitGadget
2026-10-15 13:13 ` [PATCH 3/3] reflog: add --historical-branch to name the branch of each entry Harald Nordgren via GitGitGadget
2026-10-15 14:36 ` [PATCH 0/3] reflog: add --operations and --historical-branch Kristoffer Haugsbakk
2026-10-15 15:24   ` Harald Nordgren
2026-10-15 15:35     ` Kristoffer Haugsbakk
2026-10-15 20:47       ` Harald Nordgren
2026-10-16 18:26     ` D. Ben Knoble
2026-10-23 15:31   ` Harald Nordgren
2026-10-16 18:36 ` D. Ben Knoble
2026-10-17 10:03   ` Harald Nordgren
2026-10-18 18:27 ` [PATCH v2 " Harald Nordgren via GitGitGadget
2026-10-18 18:27   ` [PATCH v2 1/3] reflog: name the strings that mark switches, renames and rebase steps Harald Nordgren via GitGitGadget
2026-10-23 21:19     ` Junio C Hamano
2026-10-23 22:47       ` Harald Nordgren
2026-10-23 22:55         ` Junio C Hamano
2026-10-18 18:27   ` [PATCH v2 2/3] reflog: add --operations to show one entry per command Harald Nordgren via GitGitGadget
2026-10-18 18:27   ` [PATCH v2 3/3] reflog: add --historical-branch to name the branch of each entry Harald Nordgren via GitGitGadget
2026-10-25 19:18     ` Kristoffer Haugsbakk
2026-10-25 20:22       ` Harald Nordgren
2026-10-26  8:39         ` Kristoffer Haugsbakk
2026-10-26  8:42           ` Harald Nordgren
2026-10-23 15:32   ` [PATCH v2 0/3] reflog: add --operations and --historical-branch Harald Nordgren
2026-10-24 13:51   ` Phillip Wood
2026-10-24 15:22     ` D. Ben Knoble
2026-10-24 16:40     ` Junio C Hamano
2026-10-24 18:46       ` Harald Nordgren
2026-10-25 18:52         ` Kristoffer Haugsbakk
2026-10-26 10:52       ` Phillip Wood
2026-10-26 11:00         ` Harald Nordgren
2026-10-26 15:07           ` Junio C Hamano
2026-10-27 13:40             ` Ben Knoble
2026-10-27 19:24               ` Junio C Hamano
2026-10-27 19:33               ` Harald Nordgren
2026-10-27 13:37         ` Ben Knoble
2026-10-24 19:12     ` Harald Nordgren
2026-10-27  8:38 ` [PATCH v3 0/2] " Harald Nordgren via GitGitGadget
2026-10-27  8:38   ` [PATCH v3 1/2] reflog: name the strings that mark switches, renames and rebase steps Harald Nordgren via GitGitGadget
2026-10-27  8:38   ` [PATCH v3 2/2] pretty: add %gb to name the branch of each reflog entry Harald Nordgren via GitGitGadget
2026-11-03 16:16     ` Phillip Wood
2026-11-04 21:15 ` [PATCH v4 0/2] reflog: add format %gb Harald Nordgren via GitGitGadget
2026-11-04 21:15   ` [PATCH v4 1/2] reflog: name the strings that mark switches, renames and rebase steps Harald Nordgren via GitGitGadget
2026-11-04 21:15   ` [PATCH v4 2/2] pretty: add %gb to name the branch of each reflog entry Harald Nordgren via GitGitGadget
2026-11-06 11:08   ` [PATCH v4 0/2] reflog: add format %gb Phillip Wood
2026-11-07  9:59     ` Harald Nordgren
2026-11-07 11:55 ` Harald Nordgren via GitGitGadget [this message]
2026-11-07 11:55   ` [PATCH v5 1/2] reflog: name the strings that mark switches, renames and rebase steps Harald Nordgren via GitGitGadget
2026-11-07 11:55   ` [PATCH v5 2/2] pretty: add %gb to name the branch of each reflog entry Harald Nordgren via GitGitGadget

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=pull.2448.v5.git.git.1794052536.gitgitgadget@gmail.com \
    --to=gitgitgadget@gmail.com \
    --cc=ben.knoble@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=haraldnordgren@gmail.com \
    --cc=kristofferhaugsbakk@fastmail.com \
    --cc=phillip.wood123@gmail.com \
    /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