For this particular case, you just need git merge
.
Let's redraw your graph. Instead of:
mybranchX : commitXA--commitXB--commitXC--commitXD--commitXE--HEAD
mybranchY : commitYP--commitYQ--commitYR--commitYS--HEAD
let's use
A--B--C--D--E <-- mybranchX
/
...--* [this commit and all earlier commits are on BOTH branches]
\
P--Q--R--S <-- mybranchY (HEAD)
as this is (presumably) an accurate representation of the state of the repository and your current branch after you run git checkout mybranchY
, which attaches the name HEAD
to mybranchY
.
(To verify this, compare this horizontal graph drawing with Git's own vertically-oriented drawing as output by git log --all --decorate --oneline --graph
. Note that it is important here that the commit I marked *
be the actual merge base, i.e., the point where the two branches split apart.)
Since your HEAD
denotes commit S
and you wish to merge with all commits up to and including commit C
, find a name that identifies commit C
, such as its raw hash ID or the string mybranchX~2
. The ~2
suffix tells Git to count backwards (leftwards, in this drawing) two commits (following the first parent links, but these commits have only a first parent). Since mybranchX
names commit E
, if we count back twice, we get to commit C
.
Then simply run:
git merge mybranchX~2 # or git merge <hash-id>
which will start the merge process. Git will compare commit *
, the merge base, to commit C
to see what they did. It will compare commit *
to commit S
to see what you did:
git diff --find-renames <hash-of-*> HEAD # what we did: --ours
git diff --find-renames <hash-of-*> <hash-of-C> # what they did: --theirs
Git will now combine these two diffs, applying the changes to commit *
. If all goes well, it will make a new merge commit automatically. The two parents of the new merge commit—I will call it T
here—will be commit S
(as its first parent) and commit C
(as its second):
A---B---C--D--E <-- mybranchX
/ \
...--* \
\ \
P--Q--R--S--T <-- mybranchY (HEAD)
Hence T~1
is S
, T~2
is R
, and so on. You can now name commit C
by either mybranchX~2
(count back two first-parent links) or by mybranchY^2
(take the second parent of commit T
). Commits A
, B
, and C
are now on mybranchY
as well as still being on mybranchX
. Commits D
and E
are only on mybranchX
.