0

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
mkrieger1
  • 19,194
  • 5
  • 54
  • 65
Austin France
  • 2,381
  • 4
  • 25
  • 37
  • It sounds like you meant to cherry-pick `bugfix`? – evolutionxbox Jul 11 '23 at 12:52
  • 1
    A branch has no concept of "when it was created" or "created from another branch". – mkrieger1 Jul 11 '23 at 12:55
  • Please don't tag your titles. See [ask]. – isherwood Jul 11 '23 at 12:56
  • I think you need to check your assumptions about what a branch is... at least in git. When you merge branches, you consider all their changes/commits, regardless of what branch they were committed on.... git actually does not care much about branches. Branches (in git) are just pointers to commits. – eftshift0 Jul 11 '23 at 12:57
  • Cherrypicking _is_ the strategy here. What problem have you encountered with it? – isherwood Jul 11 '23 at 12:58
  • 1
    You could have based commit `H` on `A` instead of `E`. Then you could merge it into both `b1` and `b2`. – mkrieger1 Jul 11 '23 at 13:00
  • @isherwood If cherry picking is the strategy, then that's the answer. I just wondered if there was another way using `git merge` that I was not aware of. – Austin France Jul 11 '23 at 13:01
  • 1
    It can't logically be an answer to a question containing the condition "without cherrypicking". – isherwood Jul 11 '23 at 13:02
  • Then the answer would be, there is no strategy that doesn't involve cherry picking. Or "No" for short. – Austin France Jul 11 '23 at 13:03
  • Does this answer your question? [How can I selectively merge or pick changes from another branch in Git?](https://stackoverflow.com/questions/449541/how-can-i-selectively-merge-or-pick-changes-from-another-branch-in-git) – mkrieger1 Jul 11 '23 at 13:05
  • 3
    Not really. I understand the process of cherry picking. That wasn't my question. I simply wondered if there was a way to do this using merge. It seems the answer is no. – Austin France Jul 11 '23 at 13:07
  • 1
    The concept "just the changes that were committed to the bugfix branch" is meaningless. The bugfix branch "contains" all the commits all the way back to the initial commit on your main branch. – matt Jul 11 '23 at 16:23
  • "the merge takes more commits" is also meaningless. Merges do not "take commits". – matt Jul 11 '23 at 16:24

1 Answers1

4

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.

TonyArra
  • 10,607
  • 1
  • 30
  • 46