1

I am new to git and trying to understand merge conflicts. I start with this program on the master branch, in file helloworld.c:

#include <stdio.h>

int main () {
  printf("Hello world!\n");
}

I then create a new branch called dev2:

$ git checkout -b dev2

I then edit the file helloworld.c and introduce a bug, to create the file:

#include <stdio.h>

int main () {
  printf("Hello world!\n")
}

I then commit the change:

$ git commit -am "Bug"

I then go back to branch master:

$ git checkout master

I would expect that a merge would create conflict. Instead, the merge command just blithely sucks in the bug to my master branch:

$ git merge dev2
Updating 0379d43..b10cde3
Fast-forward
 helloworld.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

The bug is now in master branch:

$ git status
On branch master
Your branch is ahead of 'origin/master' by 17 commits.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

$ cat helloworld.c
#include <stdio.h>

int main () {
  printf("Hello world!\n")
}

It would seem to me that the merging should complain that a line in the file from the dev2 branch is not the same as that line in the same file from the master branch. Why does this merge not create a conflict?

Anthony Mannucci
  • 277
  • 2
  • 12
  • You expect that *every* change to an existing line of code would be a *conflict*? That would be completely unmanageable. Git doesn't know removing that semicolon is a bug, it's just dealing with the text. It's doing **exactly what you told it to** - applying the changes from one branch to another. – jonrsharpe Jun 12 '20 at 07:24
  • You made a commit which introduces a change that updates `printf("Hello world!\n");` to `printf("Hello world!\n")`. Now you merge/apply the commit to the branch whose line is `printf("Hello world!\n");`. Of course it is updated to `printf("Hello world!\n")` naturally. Why would you expect a conflict? If the `master` line is something else, for example `printf("Hello world!\n");;;`, it would cause a conflict. – ElpieKay Jun 12 '20 at 07:33

1 Answers1

1

A merge conflict occurs when the branches that are about to get merged modify the same line in different ways. More specifically, it occurs when git doesn't know which version to keep and which to discard. In this case, the change did not conflict with any other change (thanks to @jonrsharpe).

Git also doesn't evaluate any of the code, therefore there is no way for git to know what is a bug and what is not a bug.

bhristov
  • 3,137
  • 2
  • 10
  • 26
  • 1
    Not that it was insignificant, just that it didn't conflict with any other change. – jonrsharpe Jun 12 '20 at 07:25
  • Let me try to understand the git logic. It's something like this: the file had a semi-colon, then it was removed. So the dev2 branch says "remove the semicolon". In other words, git looks at the current commit, and the commit before that and says "the difference is remove a semicolon". Since that same logic can be applied to the master branch, it merges the change in. If the master branch had changed in the meantime, it might not have been able to see a path towards a conflict-free merge. I'll have to ponder this. Some concerns about "state"... – Anthony Mannucci Jun 12 '20 at 07:44
  • I just verified that git is not doing what I said it was doing in the above comment. Git is not comparing changes in the commit history. I understand the answer, but not really. I remain baffled. – Anthony Mannucci Jun 12 '20 at 07:52
  • @AnthonyMannucci there is a really good explanation of the concept [here](https://www.quora.com/How-does-Git-merge-work?share=1) – bhristov Jun 12 '20 at 07:56
  • 1
    @bhristov Thanks for the suggestion. I think that git tutorials do not emphasize the appropriate workflow. The workflow should be: do a git diff and understand the branch being merged in. Do the merge when it does not introduce a problem. If a merge conflict occurs, do not "resolve the conflict". Look at the diff and figure out what's wrong. The fact that a conflict occurred means "something is wrong" and it could extend far beyond where git detects the conflict. Conversely, if no merge conflict occurs, something could still be wrong. Understanding the diff is paramount. – Anthony Mannucci Jun 12 '20 at 08:31
  • @AnthonyMannucci No problem. I completely agree with you. I like your idea. You can definitely create a git tutorial that will be very helpful! – bhristov Jun 12 '20 at 08:36
  • 1
    @AnthonyMannucci there isn't one "appropriate workflow". You had a problem on master after the merge because you had a problem on dev2 before the merge, then told git to merge that branch into master. You shouldn't have to review every single merge line by line; if you'd *tested* dev2 you'd know it didn't work. You can also use rebasing of branches to ensure that the merge is a simple fast forward (which is what happened in this case anyway), then you know what you've tested on the branch is exactly what you'll get on master after the merge. – jonrsharpe Jun 12 '20 at 09:50