2

I have a master branch with some stuff, let's say file README. I also have a dev branch, child of master, with some additional files, let's say file README2. I do the following:

git merge dev

from master and get the file README2 merged into master. Now I remove it:

git rm README2

Now when I merged dev again, I expected that I will get README2 file merged into master, because it's not in the master anymore. But Git reports there are no changes and nothing to merge. This actually suits me, but I don't understand how is this so, since branch dev at this point clearly has README2 file, while master doesn't.

2 Answers2

5

You're misunderstanding what git merge does. It works at the level of the commit tree, not at the level of individual files.

Let's say you started here, with two commits A and B on two branches:

master --- A      # this has *no* README2 file

dev ------ B      # this has README2

Then you merged the dev branch into master.

master --- A ----+--- C
                /
dev ------ B --/

This creates a new merge commit (C) in the master branch. C has the history of its parents, A and B. This is where README2 is brought into the master branch.

Later, you removed README2 from the master branch. This file delete would generate a new commit (D) on the master branch.

master --- A ----+--- C --- D
                /
dev ------ B --/

This new commit D has the history from master and dev (due to merge at C), plus the fact that you deleted the file README2. Let's assume that you have also made a change on dev (commit E below), but it does not involve the file README2.

master --- A ----+--- C --- D
                /
dev ------ B --+--- E

Now you merge dev into master again.

master --- A ----+--- C --- D --+-- F
                /              /
dev ------ B --+--- E --------/

You have a new merge commit F, which has the history from D and E. The master branch does not get a file README2 back again, because the file was already deleted in master (in D), and the new dev commit E contains no updates to README2.


At this point, if you modify the file README2 on the dev branch, then tried to merge it back to master, you would end up with a merge conflict. It would look something like this.

$ git merge dev
CONFLICT (modify/delete): README2 deleted in HEAD and modified in dev. Version dev of README2 left in tree.
Automatic merge failed; fix conflicts and then commit the result.

As the text suggests, there is a conflict between the two states. In one branch, the file has been modified, but in the other it has been deleted. Not sure which one to accept, git gives up and asks you to tell it what to do next.

Dan Lowe
  • 51,713
  • 20
  • 123
  • 112
-2

This happens because by removing the README2 file from the git tracking system it will ignore any changes you may make to it in the future which may also involve merges that would contain the file. If you make git status you will probably see file there as an untracked file.

I hope this was helpful, if you wanted to actually remove the file in that commit instead of doing git rm README2 you could've simply deleted the file and git would register that as a file deletion and not an unfrocking command.

Gustavo Gomes
  • 317
  • 5
  • 13