8

When merging branches it is common to get merge conflicts which are listed on the command prompt. I know how to get the issues fixed by looking at the files that have conflicts and making the appropriate changes. We also have "mergetool" which can be very useful (not very good at using it though). From what I've read from different sources the steps to get this resolved are:

  • fix conflicts
  • add
  • push

This seems pretty simple. But what if I miss something and don't fix it? Does Git provide a way to check if there is something else to be fixed other than using mergetool?

Scott Weldon
  • 9,673
  • 6
  • 48
  • 67
polaris
  • 339
  • 2
  • 14
  • 33
  • 1
    What do you mean by not fixed? Do you mean what if there are still conflicts? If you are able to complete the merge the conflicts must have been resolved. – dave Dec 20 '16 at 16:06
  • Once you `add` and `commit` a merge, you're telling Git that there are no more changes you need to make. If you miss something, then that's your problem. Fix it and recommit or `--amend` your merge commit. – J. Titus Dec 20 '16 at 16:21
  • 1
    Possible duplicate of [How to resolve merge conflicts in Git?](http://stackoverflow.com/questions/161813/how-to-resolve-merge-conflicts-in-git) – J. Titus Dec 20 '16 at 16:21
  • 1
    @J.Titus That's what I'm referring to. If I add and commit I'm telling git that I fixed my errors and move on. But if by any chance I miss something I will still be able to add and commit without git telling me that I missed something, or at least I don't know how. – polaris Dec 20 '16 at 20:50

4 Answers4

8

Do:

git diff -S "<<<<<<< HEAD" -S "=======" -S ">>>>>>> $(git name-rev --name-only MERGE_HEAD)" HEAD

This compares the contents of the worktree with HEAD, but only shows any output if one or more of the three types of merge marks is included in the change.

For example, if you are merging from a branch called develop, an unmerged file might look like this:

public void fooTheBar(Bar input) {
<<<<<<< HEAD
  if (input == null) {
    throw new Exception("input cannot be null!");
  }
=======
  Console.WriteLine("preparing to foo the bar");
>>>>>>> develop
  input.foo();
}

So to ensure all files have been merged, you need to search for any of the following three lines:

<<<<<<< HEAD
=======
>>>>>>> develop

And that is what the -S arguments in the command do. Since it won't always be develop, we use the command:

git name-rev --name-only MERGE_HEAD

to get the name of the branch that you are merging into your current branch.

(You could probably search for just one of those lines, but searching for all three is more robust, and will show you cases where e.g. you forgot to remove just one of the lines.)

Since the command compares the worktree to HEAD, and not just to the staged changes, this will work even if you have git added a file that still contains conflicts.

Scott Weldon
  • 9,673
  • 6
  • 48
  • 67
  • this seems more like what I was referring to when trying to check my merge conflicts before add and commit. To be honest I'm not really sure what expect from git having this kind of capability but this seems to be a good way to avoid committing unresolved merges. – polaris Dec 20 '16 at 20:56
  • 1
    That `git name-rev` trick is pretty clever! One minor issue though, if you use `git checkout -m` to re-create merge conflicts, it tends to lose the original symbolic names, especially during cherry-picks from rebasing. It might be safer to just look for the marker chevrons (though even these are tunable). – torek Dec 20 '16 at 21:45
3

Of course:

git merge --continue

will choke if you have still conflicts or have fixed conflicts without having add or rm the files yet.

For fresh merges:

git grep -En '<{7} HEAD'

A custom command is even more flexible. The following example will ignore binary files:

find -exec grep -EIHn --color=auto '<{7}' {} \;

Or limit the search to C++ files:

find \( -name '*.cpp' -or -name '*.h' \) -exec grep -EHn --color=auto '<{7}' {} \;

To turn such a script into a real git command save as git-conflicts in the path. Now you should be able to use:

git conflicts

An advantage of a custom command is the option to make git-conflicts repository-aware, specialize the set of files further or even find "TODO" or "BUG" tags etc.

Git custom commands

Andreas Spindler
  • 7,568
  • 4
  • 43
  • 34
0

I think what the question is alluding to is - how does the developer know when all manual merges have been finished? For example, you might run a simple merge like so:

git checkout master
git merge dev

and then you get:

CONFLICT blah blah 
CONFLICT blah blah  
CONFLICT blah blah

sometimes there are more conflicts than you can count, (when you have been irresponsible).

what I do is resolve all the manual merges that I can find, and then I do a global search for "<<<<<" and ">>>>>" character sequences in the codebase. Seems to have worked for me in the past just fine. If you don't have any of these character strings, then it's highly likely you have taken care of all the manual merging that needs taking care of. As long as you don't use the -Xtheirs and -Xours options of git merge, then it's is a pretty safe bet that you have merged the code successfully, on your own terms.

Alexander Mills
  • 90,741
  • 139
  • 482
  • 817
0

Before adding a file, make sure you can't find any '====' inside your file. You can easily achieve this on the command prompt with vim :

vim yourFile
/====
Enter

If you find nothing, then you're good to add it!

Hope it helps

rmTheZ
  • 66
  • 1
  • 11