How resolve multiple conflicts with "git mergetool" without having to close the editor between files?
Asked Answered
C

4

53

I've found git mergetool to be a handy utility for merging diffs visually, but the way I'm going about it seems really wonky. Essentially, my process looks like this when conflicts are reported:

  1. Execute a git mergetool
  2. At the prompt, hit Enter to launch my diff tool (Meld or FileMerge, depending on which computer)
  3. Resolve the conflicts
  4. Save the changes
  5. Close the diff tool

If I have more than one conflict, rinse, repeat. Yep, that's me opening and closing my diff viewer once for each conflict in the merge. Since it's launched from the command line, closing it is the only way I know of to tell git mergetool that I've resolved this particular conflict and that it can move on to the next.

Surely there's a better way, but I have no idea. Li'l help, please? This process seems crazy inefficient.

Credo answered 25/2, 2009 at 12:44 Comment(4)
You can also run git mergetool -y to skip the prompts in between. You might still have to close the mergetool, but you won't have to go back to the terminal and hit return for each new merge.Aviator
If you're doing a git merge of a bunch of files and this is all you have to worry about, you have nothing to worry about.Naranjo
@Aviator this is the best answer to speed up the merge conflicts process.Animator
Related for vimdiff: stackoverflow.com/questions/1220309/…Ide
C
34

At first glance, it does not seem possible to reuse an external diff tool session.

The git-mergetool documentation clearly states:

If the custom merge tool correctly indicates the success of a merge resolution with its exit code, then the configuration variable mergetool.<tool>.trustExitCode can be set to true.
Otherwise, git-mergetool will prompt the user to indicate the success of the resolution after the custom tool has exited.

So the exit code (or the validation of the user after the exit of the diff tool) is needed, implying that the user first close the external diff tool.

That seems a great incentive to reduce the number of conflicts on each merge/rebase one attempts ;) (whatever the VCScs tool used)

Note:
Two other git external diff tools settings ("Setting up diff and merge tools for Git on Windows" and "Setting up SourceGear DiffMerge with Git") do not give more hopes when it come to not closing the external diff tool...

Corpus answered 25/2, 2009 at 13:31 Comment(2)
True enough. :-) Thanks for the sanity check. What are you and others using to do merges? Just opening files in your editor of choice?Credo
I use WinMerge on Windows, but I have to close it after each resolution like you do.Corpus
T
22

If your mergetool of choice supports opening files in an existing instance, you can specify the command in your git config:

% git config mergetool.whatever_you_want.cmd 'exec /path/to/merge/tool $LOCAL $MERGED $REMOTE'
% git config merge.tool whatever_you_want

git mergetool will then execute your custom command and then prompt you as to whether the file was merged successfully (in lieu of looking at an exit code).

An example I just hacked together for vimdiff:

% git config mergetool.persistent.cmd 'gvim --remote-tab-silent "+set buftype=nowrite" "$PWD/$BASE" && sleep 1; gvim --remote-send ":split $PWD/$REMOTE<CR>:set buftype=nowrite<CR>:vertical diffsplit $PWD/$MERGED<CR>:vertical diffsplit $PWD/$LOCAL<CR>:set buftype=nowrite<CR><C-W>l"'

This works well enough, I may start using it myself!

Tomcat answered 25/2, 2009 at 16:26 Comment(4)
Interesting. I will try that with WinMerge. +1Corpus
I have to admit, that's pretty awesome. Will definitely have to see what I can hack up for Meld.Credo
Looks like there's a pending patch and bug ticket to allow meld to be used in this way: bugzilla.gnome.org/show_bug.cgi?id=453670Tomcat
this is how I set it up on one of our office Windows systems, using beyond compareEmber
J
12

The problem for mergetool is that it deliberately uses a command line interface to initiate a merge session and then waits for the invoked command to return to determine when the user driven merge has completed.

Most merge tools don't provide a command line mechanism for starting a merge session in an already running process with a way for determining when the resolution has been completed and whether successful or not.

It is conceivable that some merge tools could provide this functionality through a separate wrapper command and some sort of IPC, but it would be exceedingly tool specific and difficult to implement in the generic mergetool program.

Jodoin answered 25/2, 2009 at 14:39 Comment(6)
I agree with this analysis. +1Corpus
Git could determine the "merge success status" based on whether the merge target was updated (changed). Then if I "save the merge", it implies I completed successfully. Otherwise it did not. But maybe a 2-stage merge is needed for this use case.Royce
@phord: It does do this for tools that don't report a status via their return values but that doesn't help in this case as there would still be no indication when it's appropriate for git to check the status as the tools session was already started and may carry on after the merge is completed.Jodoin
@Charles: That's what I mean by a 2-stage merge process. For example, Step1: "git mergetool -t=mygui" launches my GUI merge tool for all merge sets. I manually fix the conflicts and save them. Step2: "git mergetool -t=finish" examines my edits to confirm merge success, and decides what to do with each file as a result (add/checkout).Royce
@phord: The second step already exists because git add <file> where <file> has merge conflicts means "I have resolved this merge". To get a diff before accepted changes you can already do git add -p .Jodoin
@Charles: Really? git-mergetool-help isn't clear on where $MERGED lives, but I suppose it could/should be in the normal working tree. Still, someone has to cleanup the three temp files, $BASE, $LOCAL and $REMOTE.Royce
L
1

I've been looking for this answer for a very, very, very long time. Now I finally get this simple solution (amazingly):

meld .

This will open meld in version control view. In this way, you can solve conflicts in tabs and mark them as resolved whenever you click the "Marked as resolved" button.

Laos answered 3/9, 2020 at 3:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.