From: Csaba Henk <csaba@lowlife.hu>
To: git@vger.kernel.org
Subject: git symbolic-ref vs. reflog (vs. rebase)
Date: Fri, 29 Apr 2011 15:03:52 +0000 (UTC) [thread overview]
Message-ID: <ipek0o$l0v$1@dough.gmane.org> (raw)
"git symbolic-ref" is a dangerous command in the sense that it can
change your HEAD position without updating the reflog. Is it
intended behaviour?
I found now a case where this feature causes strange behavior.
It seems to me that either behaviour of git symbolic-ref, or the way
it is used should be changed, but I'm not sure which of these
would be the right solution.
If I'm at a detached HEAD and I do a rebase onto it, from which then
I step back with "git rebase --abort", then I seem to lose references
to the HEAD before rebase, as git reflog won't show it anymore.
This is because of two factors:
- unlike a rebase onto a branch-referred head, we don't get an
additional reflog entry for moving to the starting position
of the rebase (ie. we don't actually changes HEAD, nevertheless
in the branchy case a dummy reflog entry is made for HEAD);
- upon aborting the rebase, a call is done to "git symbolic-ref"
in the aforementioned unsafe way, ie. it changes HEAD but
does not update reflog.
The phenomenon is illustrated by the script below. Usage:
- fist arg is the dir where the script will run (should
not exist at invocation, script creates it).
- optional second arg is a branchname, if you give it, you'll
see the branchy case, else you get the rebase-onto-detached
case
Observe the following:
- in both of branchy and detached cases, one reflog entry for
the starting HEAD disappears from reflog output, but in the
branchy case there are two of them before "rebase --abort"
so you don't lose the reference;
- "rebase --abort" does not change the reflog file, but
the reflog command's output changes, as it shows the actual HEAD
as HEAD{0}, regardless of the last log entry.
Csaba
* * *
bash> cat gtr.sh
#!/bin/bash -e
GIT=${GIT:-git}
if !([ $# -eq 1 ] || [ $# -eq 2 ]) || [ "$1" = -h ]; then
echo usage: `basename $0` scratchdir [branchname]
fi
if ! [ -z $2 ]; then
branch=$2
bropt=-b
fi
mkdir "$1"
cd "$1"
{
$GIT init
echo master > file
$GIT add file
$GIT commit -m Master.
$GIT checkout -b topic
echo topic > file
$GIT commit -am Topic.
$GIT checkout $bropt $branch master~0
echo detached > file
$GIT commit -am 'Rebase base'.
} &>/dev/null
echo
$GIT log --all --graph --decorate --pretty=oneline
echo
set -x
$GIT hash-object .git/logs/HEAD
$GIT rebase HEAD topic || :
$GIT hash-object .git/logs/HEAD
$GIT reflog
# ruby is used to compactify the logfile,
# if you don't have ruby, comment out
# the filtering part.
cat .git/logs/HEAD | ruby -ane 'puts $F.map{|x| x[0..(x =~ /:$/ ? -1 : 7)] }.join(" ")'
$GIT rebase --abort
$GIT hash-object .git/logs/HEAD
$GIT reflog
bash> ./gtr.sh testdir
* 27a1300e35857be6357adaf6759eb8ce0818d37b (topic) Topic.
| * 5d4be82c08bf6effc906a37419220ca428834844 (HEAD) Rebase base.
|/
* 6fa006d134be4d986e1a680cac4eddd61494164a (master) Master.
+ git hash-object .git/logs/HEAD
cd15f363cf16ea3e03f5177b502de8ce3543ff21
+ git rebase HEAD topic
First, rewinding head to replay your work on top of it...
Applying: Topic.
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging file
CONFLICT (content): Merge conflict in file
Failed to merge in the changes.
Patch failed at 0001 Topic.
When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".
+ :
+ git hash-object .git/logs/HEAD
cd15f363cf16ea3e03f5177b502de8ce3543ff21
+ git reflog
5d4be82 HEAD@{0}: commit: Rebase base.
6fa006d HEAD@{1}: checkout: moving from topic to master~0
27a1300 HEAD@{2}: commit: Topic.
6fa006d HEAD@{3}: checkout: moving from master to topic
6fa006d HEAD@{4}: commit (initial): Master.
+ cat .git/logs/HEAD
+ ruby -ane 'puts $F.map{|x| x[0..(x =~ /:$/ ? -1 : 7)] }.join(" ")'
00000000 6fa006d1 Csaba Henk <csaba@l 13040883 +0530 commit (initial): Master.
6fa006d1 6fa006d1 Csaba Henk <csaba@l 13040883 +0530 checkout: moving from master to topic
6fa006d1 27a1300e Csaba Henk <csaba@l 13040883 +0530 commit: Topic.
27a1300e 6fa006d1 Csaba Henk <csaba@l 13040883 +0530 checkout: moving from topic to master~0
6fa006d1 5d4be82c Csaba Henk <csaba@l 13040883 +0530 commit: Rebase base.
+ git rebase --abort
HEAD is now at 27a1300 Topic.
+ git hash-object .git/logs/HEAD
cd15f363cf16ea3e03f5177b502de8ce3543ff21
+ git reflog
27a1300 HEAD@{0}: commit: Rebase base.
6fa006d HEAD@{1}: checkout: moving from topic to master~0
27a1300 HEAD@{2}: commit: Topic.
6fa006d HEAD@{3}: checkout: moving from master to topic
6fa006d HEAD@{4}: commit (initial): Master.
bash> rm -rf testdir
bash> ./gtr.sh testdir foobr
* fa0c2b339d1f048281ed7098d8d7d55a12b35154 (HEAD, foobr) Rebase base.
| * a87b990fcd5c7a109611694dcc9523d4f00ae8fe (topic) Topic.
|/
* 1e2d1c12f46105c9329479535780ec230afe7fa0 (master) Master.
+ git hash-object .git/logs/HEAD
734ae3b60eee21ee2b8b51450040389004d56e5d
+ git rebase HEAD topic
First, rewinding head to replay your work on top of it...
Applying: Topic.
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging file
CONFLICT (content): Merge conflict in file
Failed to merge in the changes.
Patch failed at 0001 Topic.
When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".
+ :
+ git hash-object .git/logs/HEAD
5acf3d5f543333f549b3f9d295ed2ba91074b43d
+ git reflog
fa0c2b3 HEAD@{0}: checkout: moving from foobr to fa0c2b339d1f048281ed7098d8d7d55a12b35154^0
fa0c2b3 HEAD@{1}: commit: Rebase base.
1e2d1c1 HEAD@{2}: checkout: moving from topic to foobr
a87b990 HEAD@{3}: commit: Topic.
1e2d1c1 HEAD@{4}: checkout: moving from master to topic
1e2d1c1 HEAD@{5}: commit (initial): Master.
+ cat .git/logs/HEAD
+ ruby -ane 'puts $F.map{|x| x[0..(x =~ /:$/ ? -1 : 7)] }.join(" ")'
00000000 1e2d1c12 Csaba Henk <csaba@l 13040887 +0530 commit (initial): Master.
1e2d1c12 1e2d1c12 Csaba Henk <csaba@l 13040887 +0530 checkout: moving from master to topic
1e2d1c12 a87b990f Csaba Henk <csaba@l 13040887 +0530 commit: Topic.
a87b990f 1e2d1c12 Csaba Henk <csaba@l 13040887 +0530 checkout: moving from topic to foobr
1e2d1c12 fa0c2b33 Csaba Henk <csaba@l 13040887 +0530 commit: Rebase base.
fa0c2b33 fa0c2b33 Csaba Henk <csaba@l 13040887 +0530 checkout: moving from foobr to fa0c2b33
+ git rebase --abort
HEAD is now at a87b990 Topic.
+ git hash-object .git/logs/HEAD
5acf3d5f543333f549b3f9d295ed2ba91074b43d
+ git reflog
a87b990 HEAD@{0}: checkout: moving from foobr to fa0c2b339d1f048281ed7098d8d7d55a12b35154^0
fa0c2b3 HEAD@{1}: commit: Rebase base.
1e2d1c1 HEAD@{2}: checkout: moving from topic to foobr
a87b990 HEAD@{3}: commit: Topic.
1e2d1c1 HEAD@{4}: checkout: moving from master to topic
1e2d1c1 HEAD@{5}: commit (initial): Master.
next reply other threads:[~2011-04-29 15:10 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-04-29 15:03 Csaba Henk [this message]
2011-04-29 16:19 ` git symbolic-ref vs. reflog (vs. rebase) Junio C Hamano
2011-04-29 17:21 ` Csaba Henk
2011-04-30 4:13 ` Jeff King
2011-05-02 8:46 ` Csaba Henk
2011-05-27 20:13 ` [PATCH 1/2] rebase: create HEAD reflog entry when aborting Jeff King
2011-05-27 20:16 ` [PATCH 2/2] rebase: write a reflog entry when finishing Jeff King
2011-04-29 22:48 ` git symbolic-ref vs. reflog (vs. rebase) Jeff King
2011-04-29 23:00 ` Junio C Hamano
2011-04-30 3:58 ` Jeff King
2011-05-02 8:38 ` Csaba Henk
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='ipek0o$l0v$1@dough.gmane.org' \
--to=csaba@lowlife.hu \
--cc=git@vger.kernel.org \
/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).