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
next prev 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.