Skip to content

Instantly share code, notes, and snippets.

@jacobvosmaer
Created July 27, 2012 10:35
Show Gist options
  • Select an option

  • Save jacobvosmaer/3187346 to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown
Author

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

@suweller
Copy link
Copy Markdown

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
Copy Markdown
Author

Nice!

@jacobvosmaer
Copy link
Copy Markdown
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
Copy Markdown
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
Copy Markdown

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
Copy Markdown

[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
Copy Markdown

👍 was just about to make this myself

@marcuswu
Copy link
Copy Markdown

[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
Copy Markdown

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
Copy Markdown

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
Copy Markdown

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
Copy Markdown

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
Copy Markdown

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
Copy Markdown

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
Copy Markdown

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
Copy Markdown

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

Copy link
Copy Markdown

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
Copy Markdown

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