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 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.