gitmergegit-merge-conflict

git automerge result is unsatisfaying on a single file amongst others, I'd rather resolve that one with a three-way diff manually


I'm using git to merge all the time. I'm getting annoyed with what comes next and I'd like to know if there's a better way for the work flow (a command I'm missing, another way to do it, whatever).

When I git merge towards my/branch like git merge --no-ff --no-commit that/other-branch, I usually resolve conflicts. Now that this is done, I inspect all the changes in case an auto-merge went wrong (hence the --no-commit if you wondered).

Last time, I discovered an auto-merge, that -you're gonna laugh- I'd rather have had as a conflict. Indeed, the auto-merge dropped something I would have liked it not to.

A quick parenthesis here: I'm not discussing whether git was right or wrong auto-merging how it did in regards to the most recent common base. I'm just telling, well: I'd rather have git replay the game for that single file amongst the others of that big merge and mark that as a conflict for me to edit manually.

So, the current setup is:

  1. git merge --no-ff --no-commit
  2. Got conflict(s) to resolve, edited them, added them. Done. Let's move on.
  3. I inspect diffs (auto-merges included): git diff HEAD
  4. I find file foobar that was auto-merged in a way that displeases me.

So what is command #5 that:

  1. Replay merge of single file foobar in the middle of the big merge of step #1 to force it to be marked as a conflict with a three-way diff friendly file i.e., with <<<<<<< ======= >>>>>>> instead of the result of the auto-merge.

Thanks.


Solution

  • First : you did the right thing. Reviewing merges is definitely a wise thing to do.


    As far as edition goes : note that any way to edit the file before committing is ok, you don't specifically need to "trigger and solve a conflict" before committing your content as the result of the merge.

    You can get the value of either side of the merge :

    git show HEAD:that/file > that/file.ours
    # during a merge, git creates a MERGE_HEAD reference that points to the incoming commit
    git show MERGE_HEAD:that/file > that/file.theirs
    # since you know what you merged in, the above is the same as:
    git show that/other-branch:that/file > that/file.theirs
    

    and copy the chunks you want, or use git difftool :

    git difftool HEAD -- that/file
    git difftool MERGE_HEAD -- that/file
    

    If you are more confortable with a 3 way merge, once you have file.ours and file.theirs, use your diff editor to open a 3 way merge.