When merging a branch into a branch other than the one it was created from, the merge takes more commits than I want it to. In the scenario below, when I merge bugfix (where I made a single commit) into branch b2, it takes that change plus any changes that were committed to branch b1 as well.
--A----B----C--------------F----G MAIN
\
|\
| \------------D----E-----------------MERGE-b1 b1
| \ /
| \-------------H BUGFIX
\ \
\-----------------------------------MERGE-b2 b2
ie, MERGE-b1 merged commit H into b1. MERGE-b2 merges commits D, E and H into b2 and I just want commit H
My question is, other than using cherry pick, is there a simple way to merge just the changes that were committed to the bugfix branch into branch b2? (the last merge in this script)
Alternatively, is there a different strategy / workflow for branching that would help?
#!/bin/bash
REV=0
Update() {
echo "Revision $REV in $1" >> README.md
REV=$(($REV + 1))
git commit -a -m "Update README.md in $1"
}
cd ~/Projects
( cd merge-test && rm -rf ../merge-test )
mkdir merge-test
cd merge-test
git init
echo > README.md
git add README.md
git commit -a -m 'Initial Commit'
Update main
git branch b1
git branch b2
# ^ created 2 branches from main
Update main
Update main
git checkout b1
Update b1
Update b1
git checkout main
Update main
Update main
# ^ various updates were applied to b1 and main
git checkout b1
git branch bugfix
git checkout bugfix
# ^ a bug is reported in branch b1, but probably also affects branch B
Update bugfix
# ^ make a fix in bugfix branch
git checkout b1
git merge bugfix
echo "README.md after merging bugfix into b1 (ok)"
cat README.md
# ^ merge bugfix branch back into b1
git checkout b2
git merge bugfix
echo "README.md after merging bugfix into b2 (takes too much)"
cat README.md
# ^ merge bugfix branch into b2
What you're asking for is not really possible with git merge
alone. This is because git merge
cannot throw away commits when attempting to merge histories. It must include all commits from the common ancestor of the two branches.
The closest approximation would be to first merge your bugfix
branch into b1
normally, and then perform either a series of cherrypicks, or an interactive rebase and non-fast-forward merge; for example:
git switch b1
git merge bugfix
git rebase -i b2 bugfix
git switch b2
git merge --no-ff bugfix
This would be similar to cherry-picking the commits, but due to the --no-ff
option, it would create a merge commit as well.
What you probably want to do is fix your branching strategy for bugfixes. This issue could have been avoided if the bugfix
branch was based on commit A
instead of commit E
. This is because commit A
is a common ancestor of both b1
and b2
.