Rebase consists of repeated git cherry-pick
operations (or one single en-masse pick in some cases, but that amounts to the same thing): it takes all the commits selected by your rebase specification (basically <upstream>..HEAD
) and copies those to new commits with the new chain grown on the --onto
argument (which defaults to the tip of your <upstream>
argument).
Doing the cherry-picking requires a small change of perspective: rebase starts by checking out an anonymous (detached HEAD) branch at the --onto
point, and then iterates through the commit-IDs it saved away earlier from the <upstream>..HEAD
before it detached HEAD. It's these cherry-pick steps that hit the merge conflict(s) (which is why you often have to solve the merge conflicts repeatedly, once for each commit being cherry-picked).
This means that to answer your question we may want to look at the git cherry-pick
documentation in addition to the git rebase
documentation. There, we find:
When it is not obvious how to apply a change, the following happens:
The current branch and HEAD
pointer stay at the last commit successfully made.
The CHERRY_PICK_HEAD
ref is set to point at the commit that introduced the change that is difficult to apply.
This means that in this state, we can use either git checkout HEAD -- path/to/file
(the --
is not actually required here, but is a good habit) or git checkout CHERRY_PICK_HEAD -- path/to/file
.
Since we're now cherry-picking, not rebasing (the rebase is still going on, we're just in the cherry-pick phase at this point), HEAD
refers to the most recent successful commit. If the conflict is at the very first commit, HEAD
refers to the same commit as master
in your particular example, while CHERRY_PICK_HEAD
refers to the commit being copied from the original new-feature
branch. If the conflict is a bit further along, HEAD
refers to one of the new commits that has been grown on the anonymous branch leading into the future from (again, using your example) master
. In either case that's the one you actually want, here.
(Side note: if you know that you didn't touch the file, it's going to be the same, in this case, in both the CHERRY_PICK_HEAD
commit and the master
commit, so you can use git checkout master -- path/to/file
instead, which is easier to type. However, this assumes that you're rebasing onto the tip of master
, while using the name CHERRY_PICK_HEAD
makes this independent of the target commit.)
Once the cherry-picking phase is done, git rebase
takes over again and completes the rebase by changing the rebased branch name—in this case, new-feature
—to point to the tip-most commit on the new anonymous branch. The old (pre-rebase) branch tip, from before all this cherry-picking, remains in the reflog for new-feature
(as new-feature@{1}
or any of the other ways to name it). It's also available in ORIG_HEAD
at this point, until you run something that overwrites ORIG_HEAD
(various git commands, including git am
, git merge
, and git reset
, also write to ORIG_HEAD
). This is particularly handy if you accidentally goof up the rebase.