Reputation: 3649
I went through reading a bunch of stuff on SO and the Git docs, and noticed something, after messing around, that I don't completely understand:
Let's say I have the following state and configuration post-fetch, stage 2 of a git pull, and a forced update has occurred on origin/master:
$ git log -2 --oneline
a589c89 foo2
e0e5946 foo
$ git log -2 --oneline origin/master
e0e5946 foo
$ git config branch.master.remote
origin
$ git config branch.master.rebase
true
$ git config branch.master.merge
refs/heads/master
The doc says (https://www.kernel.org/pub/software/scm/git/docs/git-rebase.html)
If <branch> is specified, git rebase will perform an automatic git
checkout <branch> before doing anything else. Otherwise it remains on
the current branch.
If <upstream> is not specified, the upstream configured in
branch.<name>.remote and branch.<name>.merge options will be used
When I specify the single argument version of git rebase this happens:
$ git rebase origin/master
Pruned remote csv test branches
Successfully rebased and updated refs/heads/master.
$ git log -2 --oneline
a589c89 foo2
e0e5946 foo
Cool, foo2 still exists on my local branch as expected. Now doing this, which should be the same thing (implicitly) because according to the docs, branch.master.remote and branch.master.merge resolve as origin/master as shown above, unless I'm interpreting things wrong:
$ git rebase
Pruned remote csv test branches
Successfully rebased and updated refs/heads/master.
$ git log -2 --oneline
e0e5946 foo
Except foo2 is lost and we have to do git reset --hard HEAD@{2}
to recover. Wasn’t really expecting that one. Any idea why I'm getting different behavior here? And how would I go about preventing foo2 from being lost in the process without switching branch.master.rebase to false? I intend for the pull to do a rebase.
Upvotes: 4
Views: 487
Reputation: 488519
The difference depends on your specific Git version.
Currently (Git versions above 2.something, I am not sure off-hand what the something is), the biggest difference is that the three-argument version disables --fork-point
by default, while the two-argument version enables it by default.
Introducing git pull
into the mix makes things even trickier, because git pull
is where --fork-point
originated, and older versions of Git behave much more differently than newer ones. In particular, before --fork-point
was its own separate option, only git pull
did fork-point style rebasing. I doubt this is an issue in your particular Git version, as then you would not see a difference with git rebase origin/master
vs git rebase
(with branch.master.*
configurations supplying the <upstream>
). At least, I think you would not.
(For completeness, you might want to show the output of git config --get-all remote.origin.fetch
, although I expect it to be the standard single line of +refs/heads/*:refs/remotes/origin/*
.)
Further reading on --fork-point
: the git rebase
documentation and the git merge-base
documentation section on --fork-point
.
Upvotes: 1