Skip to content

Instantly share code, notes, and snippets.

@jacobvosmaer
Created July 27, 2012 10:35
Show Gist options
  • Star 54 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save jacobvosmaer/3187346 to your computer and use it in GitHub Desktop.
Save jacobvosmaer/3187346 to your computer and use it in GitHub Desktop.
Open all files with git merge conflicts in Vim

Open all files with git merge conflicts in MacVim

git diff --name-only | uniq | xargs mvim

When git encounters a merge conflict, e.g. during a rebase, it drops you back into the shell with a dirty working directory. I like this one-liner for opening all files with a merge conflict in MacVim.

Once you're in Vim, you can then switch between the files with :n and :prev, or another favourite: :w | n (save current file and open the next command line-supplied file).

UPDATE: see below for a version that works with real terminal commands.

@jacobvosmaer
Copy link
Author

This will also work if you replace vim with e.g. subl, the command line interface to Sublime Text.

@suweller
Copy link

If you have defined your editor in .bashrc, .zshrc, or .yourrc, you can create an alias.

alias fix=git diff --name-only | uniq | xargs $EDITOR

@jacobvosmaer
Copy link
Author

Nice!

@jacobvosmaer
Copy link
Author

As @suweller pointed out offline, this trick does not work for editors that run in the terminal. I found a nice explanation why on this Emacs mailing list; basically, you cannot use xargs to launch programs that expect to interact with the terminal (/dev/tty).

The following should work:

alias fix='$EDITOR `git diff --name-only | uniq`'

@jacobvosmaer
Copy link
Author

The version using xargs works for mvim and subl because those commands launch GUI apps, that do no care about the shell they were launched from.

@wting
Copy link

wting commented Aug 7, 2013

As a git alias:

[alias]
    fix = "!f() { ${EDITOR} `git diff --name-only`; }; f"

If you prefer opening the files as vim tabs:

[alias]
    fix = "!f() { vim -p `git diff --name-only`; }; f"

@jamielennox
Copy link

[alias]
        edit-unmerged = "!$EDITOR `git diff --name-only --diff-filter=U`"
        add-unmerged = "!git add `git diff --name-only --diff-filter=U`"

@Gerst20051
Copy link

👍 was just about to make this myself

@marcuswu
Copy link

[alias]
    conflicts = diff --name-only --diff-filter=U

Followed by a bash alias for the editor:
alias conflicts="\$EDITOR \$(git conflicts)"

Also, the diff-filter can be easily altered for editing other categories such as modified files (M) or new files (A). See git help diff and search for diff-filter for more options.

@akagr
Copy link

akagr commented Jun 23, 2016

as an alternative, one can always use expansion for this to work. For example

vim $(git diff --name-only | uniq)

This works easily with whatever you wanna do with the output, apart from opening it in vim.

@rdeva31
Copy link

rdeva31 commented Oct 7, 2016

Is there a way to get git diff --name-only to print out the file names using the relative paths instead? Seems cumbersome to have to cwd to project root in order to run this.

--relative isn't reliable:


$ git diff --name-only --relative
[3]    19507 segmentation fault (core dumped)  git diff --name-only --relative
$ git --version
git version 2.7.4

@ti-mo
Copy link

ti-mo commented Oct 10, 2016

@rdeva31 this works for me from any path in the repo (edited example from @wting):

[alias]
    fix = "!f() { ${EDITOR} `git rev-parse --show-toplevel`/`git diff --name-only`; }; f"

@doits
Copy link

doits commented Mar 27, 2017

To define the global alias in the shell:

git config --global alias.fix '!${EDITOR} $(git diff --name-only | uniq)'
# => git fix

@Westacular
Copy link

All of the above solutions choke on paths with spaces in them. The solution for that is to use -z for git diff to output raw null-terminated strings, and xargs -0 to pass them to $EDITOR:

git config --global alias.fix '!git diff --name-only --relative -z --diff-filter=U | xargs -0 ${EDITOR}'

@kernhanda
Copy link

this works for me on linux and in a terminal

git config --global alias.fix '!${EDITOR} $(git diff --name-only --relative --diff-filter=U | uniq)'

@dpapp-hortonworks
Copy link

Using the original command somehow messes with my terminal when I exit vim. For me the following works better:

vim -p `git diff --name-only | uniq`

@krisleech
Copy link

vim `git diff --name-only --diff-filter=U  | uniq` 

Copy link

ghost commented Nov 16, 2019

alias fix='vim +/HEAD `git diff --name-only | uniq`'

will open vim with the cursor at the first merge conflict.

@iFrostizz
Copy link

wrote a vim-compatible plugin that does that within vim ! https://github.com/iFrostizz/vim-conflict

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment