6

I have two main branches in Git: master and dev.
The structure of my branches look like this:

B-->E-->F-->G (master branch)

B-->C-->D-->H-->I-->J-->K (dev branch)

Before I performed the merge, master and dev had a common parent B.
In commits E, F and G of master, I deleted some files (say foo and bar) incorrectly while they still exist in commits C onwards in dev branch.
As a result, when I performed a three-way merge to join G and K by creating commit L, L does not contain foo and bar anymore! And I was not notified by Git in any way about their disappearance.

It seems to me that because E, F and G were simply replayed after commit C hence foo and bar were gone.

This behavior of Git merge is strange to me. Because I would not be able to know if someone deleted some files from another branch.
Shouldn't I be at least notified about any conflicting modifications while merging?

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
lixiang
  • 1,941
  • 3
  • 20
  • 25
  • `I was not notified by Git in any way about their disappearance.` the output of git merge shows what changes are being applied. – AD7six Jul 05 '15 at 04:50
  • Why do you think there's a conflict between a file that's deleted on one branch and not touched on the other? The whole point of merging is: to wind up with a result that contains all the changes made on either branch. SO the resuliting commit has the deletion from one branch since there was nothing conflicting done to it on the other branch. – jthill Jul 05 '15 at 05:38
  • If that's the case, then what's the difference between merging A to B and merging B to A? Since both merges are to conclude a result that contains all the changes made on either A or B. – lixiang Jul 05 '15 at 05:47

1 Answers1

7

Shouldn't I be at least notified about any conflicting modifications while merging?

In this case, no: merging dev to master reports modifications from dev (since the common ancestor B) to master.
Here foo and bar were not modified in dev since B. And they were deleted in master since B. There is no conflict (if foo and bar where not modified in dev): those two files are not concerned by the merge (nothing to apply from dev), and remains unchanged in master (meaning deleted).

You can preview a merge with:

git checkout master
git diff  --name-status dev

That would list the deleted files.

Can you give me some pointers as to how Git decide which commits to replay during a merge?

Git does not "replay" commits when merging (only when rebasing): it only consider the two branch HEADs (and the common ancestor).

https://git-scm.com/book/en/v2/book/03-git-branching/images/basic-merging-1.png

Git creates a new snapshot that results from this three-way merge and automatically creates a new commit that points to it. This is referred to as a merge commit, and is special in that it has more than one parent.

https://git-scm.com/book/en/v2/book/03-git-branching/images/basic-merging-2.png

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • I was actually merging from `dev` to `master`. Based on your answer, Git should report the modifications from `dev`, but Git did not report to me anything. Are having two additional files in `dev` not considered modifications? – lixiang Jul 05 '15 at 05:23
  • @lixiang "I was actually merging from `dev` to `master`": I have amended the answer accordingly, and explained where `foo` and `bar` are not involved here (and remain deleted in `master`). – VonC Jul 05 '15 at 05:33
  • I got your point! However, I have a extended question about merging. Can you give me some pointers as to how Git decide which commits to replay during a merge? This question is also related to whether there is a difference between merging from A to B and merging from B to A? Thanks! – lixiang Jul 05 '15 at 05:52
  • Thank you! The last question I have is how the direction of a merge affects the final merge result? In your example how merging from "iss53" to "master" differ from the other way around. – lixiang Jul 05 '15 at 22:25
  • 1
    @lixiang you are reporting modification from source to destination when you are merging. Looking at https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging, merging `master` to `iss53` (the feature branch), would have reported the hotfix files (integrated in `master`) to `iss53`. Merging `iss53` to `master` will report the feature files to `master`. – VonC Jul 06 '15 at 05:41