Re: HEAD's reflog entry for a renamed branch
From: Jeff King <hidden>
Date: 2017-01-26 21:12:12
On Mon, Jan 16, 2017 at 06:17:29PM -0500, Kyle Meyer wrote:
I noticed that, after renaming the current branch, the corresponding
message in .git/logs/HEAD is empty.
For example, running
$ mkdir test-repo
$ cd test-repo
$ git init
$ echo abc >file.txt
$ git add file.txt
$ git commit -m"Add file.txt"
$ git branch -m master new-masterThanks for providing a simple reproduction recipe.
resulted in the following reflogs: $ cat .git/logs/refs/heads/new-master 00000... 68730... Kyle Meyer [off-list ref] 1484607020 -0500 commit (initial): Add file.txt 68730... 68730... Kyle Meyer [off-list ref] 1484607020 -0500 Branch: renamed refs/heads/master to refs/heads/new-master $ cat .git/logs/HEAD 00000... 68730... Kyle Meyer [off-list ref] 1484607020 -0500 commit (initial): Add file.txt 68730... 00000... Kyle Meyer [off-list ref] 1484607020 -0500 I expected the second line of .git/logs/HEAD to mirror the second line of .git/logs/refs/heads/new-master. Are the empty message and null sha1 in HEAD's entry intentional?
The null sha1 is correct, I think. The branch we were on went away, and
we use the null sha1 to indicate "no value" in both the creation and
deletion cases.
It's unfortunate that there's no message. This is because the rename
calls delete_ref() under the hood, but that function doesn't take a
reflog message argument at all. It usually doesn't matter because
deleting the ref will also delete the reflog.
But as your example shows, deletions _can_ get logged in the HEAD
reflog; the low-level ref code detects when HEAD points to the updated
ref and logs an entry there, too.
You can see the same thing with a simpler example:
$ git init
$ git commit -m foo --allow-empty
$ git update-ref -d refs/heads/master
$ cat .git/logs/HEAD
00000... 8ffd1... Jeff King [off-list ref] 1485464779 -0500 commit (initial): foo
8ffd1... 00000... Jeff King [off-list ref] 1485464787 -0500
This doesn't come up much because most porcelain commands will refuse to
delete the current branch (notice I had to use "update-ref" and not
"branch -d").
I'd say there are two potential improvements:
- delete_ref() should take a reflog message argument, in case it
updates the HEAD reflog (as a bonus, this will future-proof us for a
day when we might keep reflogs for deleted refs).
- "git branch -m" does seem to realize when we are renaming HEAD,
because it updates HEAD to point to the new branch name. But it
should probably insert another reflog entry mentioning the rename
(we do for "git checkout foo", even when "foo" has the same sha1 as
the current HEAD).
-Peff