I have a old branch foo
, and wanna make it up to the latest master
.
If I execute $ git rebase origin master
on the foo
branch, somewhy the changes made in foo
branch disappears and foo
gets just same as the HEAD
of master
.
Why does this happen? And How to rebase my foo
branch to the master?
Here is my git reflog
. foo
is equal to komoto/crop_image
.
fd8d9c1d (HEAD -> komoto/crop_image, origin/master, origin/HEAD, master) HEAD@{0}: rebase finished: returning to refs/heads/komoto/crop_image
fd8d9c1d (HEAD -> komoto/crop_image, origin/master, origin/HEAD, master) HEAD@{1}: rebase: checkout master
92284980 (tag: beta-test, origin/komoto/crop_image) HEAD@{2}: checkout: moving from master to komoto/crop_image
Beware: git rebase origin master
means git checkout master; git rebase origin
git checkout master; git rebase origin
(and then return to the original branch). That's why your reflog shows:
HEAD@{1}: rebase: checkout master
(and then HEAD@{0}: rebase finished: returning to refs/heads/komoto/crop_image
: obviously you were on komoto/crop_image
when you started).
When you write origin
by itself in this positional argument , your Git follows the six-step process outlined in the gitrevisions documentation . Step 6 reads:
- otherwise, refs/remotes/<refname>/HEAD if it exists.
So if git rev-parse origin/HEAD
succeeds (and the five preceding steps fail), the sequence of commands:
git checkout master
git rebase origin
is equivalent to the sequence:
git checkout master
git rebase origin/master
If there are no commits on your master
that are not already reachable from origin/master
, this does nothing. For a good introduction to reachability, see Think Like (a) Git .
I have a old branch
foo
, and wanna make it up to the latestmaster
.
In general, I prefer to do this as:
git checkout foo
git rebase master
but you can—because of the shortcut that I think people should avoid (it has bad failure modes in older versions of Git)—run:
git rebase master foo
Remember that rebase works by copying commits, so this will first enumerate all non-merge commits reachable from foo
that are not reachable from master
, in a topologically-sorted order, 1 saving their hash IDs somewhere. 2 It will then use the equivalent of git cherry-pick
3 to copy each such commit, with the copy landing after the previously-copied commit. The first-copied commit lands right after the tip of master
:
...--A--B--C--...--N--O <-- master
\
G--H--I <-- foo
becomes:
G'-H'-I' <-- foo
/
...--A--B--C--...--N--O <-- master
\
G--H--I [abandoned, but still findable as foo@{1}]
where G'-H'-I'
is the sequence of cherry-picked, ie, copied, commits that correspond to the original commits GHI
.
1 For a simple chain of commits with no branching and merging, the only correct topological sort is: in order from first to last . If there are branch-and-merge sequences in the chain of commits you are rebasing, rebase picks some valid topological sort, linearizing the commits in the process and omitting merge commits. This is actually sometimes a good idea and what you want, but more often, it's not. Git is growing a new kind of rebase that will be able to handle this better; currently there is an option called --preserve-merges
that attempts to do the job, but is not really adequate and should be avoided except in emergencies.
2 This somewhere is literally in the file full of pick
directives when you use git rebase -i
. Each pick hash
directive tells Git to do a cherry-pick of that particular commit, listing its true name: its hash ID. for some other kinds of rebases, the IDs are not as easily visible—but they are still saved somewhere, with the ability to stop the copying process when a copy step fails, then resume from the point where it stopped after you have manually fixed things up.
3 An interactive rebase, or a rebase run with -m
or -s
flags, literally uses git cherry-pick
. All rebases probably should default to this, but currently, non -interactive rebases that do not use -m
or -s
use an older method that combines git format-patch
with git am --3way
. See also What is the difference between git cherry-pick and git format-patch | git am?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.