Skip to content

Instantly share code, notes, and snippets.

Created July 27, 2012 10:35
Show Gist options
  • 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.

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

Copy link


Copy link

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`'

Copy link

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.

Copy link

wting commented Aug 7, 2013

As a git alias:

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

If you prefer opening the files as vim tabs:

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

Copy link

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

Copy link

👍 was just about to make this myself

Copy link

    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.

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.

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

Copy link

ti-mo commented Oct 10, 2016

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

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

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

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}'

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)'

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`

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.

Copy link

wrote a vim-compatible plugin that does that within vim !

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