2

So I'm trying to understand why when I git merge master into a branch, I lose some, but not all of my changes in a commit. It seems to do with a cherry-pick commit on my branch. Here's how to reproduce:

  1. init a repo with an initial commit
  2. Add a line of text to a file and commit
  3. Branch off this, call it "test"
  4. On branch master, revert the second commit
  5. Cherry-pick that commit into the test branch
  6. Go back to master, create a new commit that restores that line of text, plus add additional changes
  7. Go back to test, run git merge master
  8. Notice that the merge automatically removed that line of text (!!!), but kept the additional changes. I expect the merge to not drop that line, so that it matches master.

I uploaded my results on github: https://github.com/terryttsai/testRevertMerge/commits/test

If I never cherry-picked that commit into my test branch, then git merge master does keep that line of text. So how come when I do have that cherry-pick commit, the merge removes it? How can I prevent this from happening in the first place?

moxie1111
  • 21
  • 2

1 Answers1

3

I expect the merge to not drop that line, so that it matches master.

No. git merge master does not mean to match master!

What is a merge? A merge means to play out the contributions of both branches, starting from the point of divergence. What are they?

Well, the point of divergence is after that first line was added. So what happened after that on each branch?

  • On master, the only contribution is the extra stuff. (It removed the first line but later restored it, so that is not a contribution; in that respect nothing happened at all.)

  • On test, the only contribution is deletion of the first line (that is what the cherry picked revert commit does).

So the merge does both of them: the extra lines from master, and the deletion from test.

But if you never do the cherry pick, then neither branch makes a contribution that deletes that line, so obviously it is not deleted by the merge.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Hey Matt, thanks for the response. So on master I delete that line in a revert commit, and I cherry-picked it into the test branch, but then I add it back in later as part of a newer commit on master, which doesn't get carried over when I merge it into the test branch? I would assume if my commit to add the line back in comes after the cherry-pick, `merge` would choose to keep the line in, rather than delete it? – moxie1111 Jan 11 '21 at 23:21
  • Ah, but read exactly what I said. Git knows / cares nothing about what you did later on one branch than another. It cares about the whole of what you did on each. On master, you removed the line and restored it. So in sum you did nothing. – matt Jan 12 '21 at 00:34