775

I just need a plain list of conflicted files.

Is there anything simpler than:

git ls-files -u  | cut -f 2 | sort -u

or:

git ls-files -u  | awk '{print $4}' | sort | uniq

I guess I could set up a handy alias for that, however was wondering how pros do it. I'd use it to write shell loops e.g. to auto-resolve conflict, etc. Maybe replace that loop by plugging into mergetool.cmd?

Paulo Mattos
  • 16,310
  • 10
  • 64
  • 73
inger
  • 17,374
  • 9
  • 45
  • 51

20 Answers20

1362
git diff --name-only --diff-filter=U
CB Bailey
  • 648,528
  • 94
  • 608
  • 638
  • 152
    I created an alias for this: `git config --global alias.conflicts "diff --name-only --diff-filter=U"` – Jimothy Mar 29 '13 at 14:23
  • 2
    @CharlesBailey, Am I missing something? What's *wrong* with `git status`? – Pacerier Oct 20 '15 at 08:36
  • 10
    @Pacerier, it's just messier. If you had a million unconflicting merges and one conflicting merge, you'd want something succinct for output. – xster Jan 07 '16 at 20:50
  • @Jimothy how do you use that alias? – sAguinaga Jul 12 '16 at 11:49
  • 9
    @sAguinaga: Simply run `git conflicts` – Jimothy Jul 13 '16 at 18:14
  • @QZSupport You must first set up the alias, as indicated in my earlier comment: `git config --global alias.conflicts "diff --name-only --diff-filter=U"` – Jimothy Nov 29 '17 at 17:44
  • @ChristianMatthew `diff-filter=U` asks to show only files that are unmerged, the option can use other options like `A` for added files, `M` for modified files and so on. See doc for more info: https://git-scm.com/docs/git-diff#Documentation/git-diff.txt---diff-filterACDMRTUXB82308203 – Charles Duporge Jun 27 '19 at 11:39
  • 6
    This continues to show the file even after resolving the conflict. `git diff --check` works better. – aksanoble Aug 20 '19 at 14:32
  • 2
    It's worth noting that this only works when items haven't been staged (or unstaged) after arriving at the conflict. @cnlevy's [answer](https://stackoverflow.com/a/49382772/2521092) (`git diff --check`) will find conflict markers for unstaged files. – Amory Feb 27 '20 at 11:36
  • @Pacerier nothing is wrong really. But there are situations, where you might want *only* the names of conflicting files. E.g. the command ```vim `git diff --name-only --diff-filter=U` ``` will open all conflicting files in vim, so you can fix the conflicts one by one. – zefciu Apr 15 '20 at 06:56
100

git diff --check

will show the list of files containing conflict markers including line numbers.

For example:

> git diff --check
index-localhost.html:85: leftover conflict marker
index-localhost.html:87: leftover conflict marker
index-localhost.html:89: leftover conflict marker
index.html:85: leftover conflict marker
index.html:87: leftover conflict marker
index.html:89: leftover conflict marker

source : https://ardalis.com/detect-git-conflict-markers

cnlevy
  • 8,112
  • 3
  • 17
  • 18
  • 2
    I've found `git diff --check` telling me about other (less serious) problems too, like trailing whitespace, so a `git diff --check | grep -i conflict` might be in order for OP's case – CCJ Dec 06 '19 at 00:51
  • 1
    `git diff --check` uses the whitespace rules from core.whitespace. You can disable all of the whitespace checks during `git` invocation to just get conflict markers: `git -c core.whitespace=-trailing-space,-space-before-tab,-indent-with-non-tab,-tab-in-indent,-cr-at-eol diff --check` – Josh Cooley Sep 01 '20 at 16:51
  • nice! it also shows stuff like trailing ws <3 – CervEd Mar 26 '21 at 11:07
38

Trying to answer my question:

No, there doesn't seem to be any simpler way than the one in the question, out of box.

After typing that in too many times, just pasted the shorter one into an executable file named 'git-conflicts', made accessible to git, now I can just: git conflicts to get the list I wanted.

Update: as Richard suggests, you can set up an git alias, as alternative to the executable

git config --global alias.conflicts '!git ls-files -u | cut -f 2 | sort -u'

An advantage of using the executable over the alias is that you can share that script with team members (in a bin dir part of the repo).

inger
  • 17,374
  • 9
  • 45
  • 51
  • 1
    I felt the same at that point - thinking how the hell people don't need this, and seeing how trivial it was to workaround. However, I've been using git for 2 years now and honestly haven't run into that "limitation" once more. So maybe that's not that much of common usecase after all? – inger Oct 19 '11 at 14:35
  • 4
    This is simple enough that you could set up an alias for it `git config --global alias.conflicts "!git ls-files -u | cut -f 2 | sort -u"` (the ! means run this shell command, rather than just a git command). – Richard Apr 09 '12 at 04:57
  • 1
    Worth mentioning that you actually want 'single-quotes' instead of "double-quotes." Otherwise, the `!` will be interpreted by your shell: `git config --global alias.conflicts '!git ls-files -u | cut -f 2 | sort -u'` – umop Jun 02 '12 at 02:12
35

Here is a fool-proof way:

grep -H -r "<<<<<<< HEAD" /path/to/project/dir
Jones Agyemang
  • 929
  • 13
  • 14
  • 11
    No. Git's index will still internally mark certain files as being in conflict even after the textual markers in the files are removed. – Alexander Bird Apr 24 '14 at 18:48
  • 8
    Alongside Alexander's comment, it's still useful to see this as an option :) Please don't delete. – WoodenKitty Oct 12 '14 at 22:59
  • 3
    Or to run within current working dir use a dot for path - `grep -H -r "<<<<<<< HEAD" .` – David Douglas Mar 03 '16 at 10:40
  • Hehe, this is my way of doing it too. Adding a `c` nicely results the count of conflicts too! One note is that I'd use flags `-Hrn` this will also supply line number information. – ShellFish Apr 18 '16 at 11:06
  • 3
    If you're using regex, I'd suggest `[<=>]{7}` instead of this. (Might need `-E` flag for that to work in grep.) Or, ` – celticminstrel Aug 06 '16 at 16:27
  • The `H` Flag means that the file name will be shown. `r` means recursive, If you do `git grep`, you put `--files-with-matches` instead of the `H` flag. – Timo Sep 24 '17 at 19:21
  • It's much faster to use git's grep command for large codebases because it will follow the rules configured in the .gitignore file. `git grep -H -r "<<<<<< HEAD"` – wyattis Mar 26 '20 at 19:42
  • For `git stash apply`, `<< HEAD` will not be there. Instead `<< Updated Upstream – Reed Sep 25 '20 at 22:41
  • If you're IN your git dir, use `grep -Hrn "<<<<<<< " "$(git rev-parse --show-toplevel)"`, and it will search from the root of your project – Reed Sep 25 '20 at 22:43
23

git status displays "both modified" next to files that have conflicts instead of "modified" or "new file", etc

Vadim Kotov
  • 7,103
  • 8
  • 44
  • 57
Rafa
  • 1,161
  • 13
  • 17
  • 3
    That's true. However this particular question was about a plain list of conflicted files.. this might be an XY problem (I can't remember why I actually needed that conflict list, but the fact that I haven't needed it since might suggest that I should have followed a different approach back then. Not sure now.. I also was writing scripts for autoresolving java-import conflicts which needed this list, ie. non-interactive use).. – inger Oct 25 '11 at 17:35
  • Oh, I hadn't understood that. I thought you wanted a "normal" list for "normal" use. Which is why I freaked out with your own code and your self-answer... then I realized the "both modified" thingy worked for me (and I assumed you just wanted the same as me, why shouldn't you? ;-P ) Thanks for the upvote though :) – Rafa Oct 26 '11 at 14:13
  • There can also be merge conflicts where one branch deleted a file and the other modified it. These won't show up with `git status | grep "both modified"`. – Kalinda Pride Oct 11 '20 at 23:38
19
git status --short | grep "^UU "
mda
  • 1,048
  • 13
  • 18
  • 4
    Note: You may need to search for ^UA and ^UD also, so the following pattern is more complete: "^U[UAD] " – mda Feb 11 '12 at 00:18
  • or just `^U` to get everything starting with U – Ascherer Jan 24 '14 at 18:04
  • 8
    This isn't sufficient. Conflicting files can have the following combinations: `DD, AU, UD, UA, DU, AA, UU` – Anthony Sottile Apr 14 '14 at 06:25
  • 1
    @AnthonySottile: Can you explain the scenarios? I posted what worked for my case. – mda Jun 21 '14 at 22:49
  • @mda One example: Conflict where upstream modified, I deleted will have status `DU` – Anthony Sottile Jun 22 '14 at 01:15
  • @AnthonySottile, Am I missing something? Why even bother with `grep` in the first place? – Pacerier Oct 20 '15 at 08:36
  • My usecase was supporting older versions of git (I believe <1.5) which do not have the `--diff-filter` option. – Anthony Sottile Oct 20 '15 at 15:19
  • @AnthonySottile, are all those combinations _guaranteed_ to be conflicted, or are some of them just "possibly" conflicted? **Edit:** The chart at Mateusz's link seems to indicate that they are guaranteed to be conflicts. – Michael May 14 '19 at 14:58
  • I don't know if it's the _shortest_ regex, but this gets all the conflicted combinations and none of the unconflicted combinations: `grep -E "^([AUD][AU]|[UD]D) "`. See https://regex101.com/r/Wh1fUi/1 – Michael May 14 '19 at 15:13
  • 1
    @self Also `^(.U|U.|AA|DD)`. – Michael Aug 20 '19 at 20:44
14

This works for me:

git grep '<<<<<<< HEAD'

or

git grep '<<<<<<< HEAD' | less -N

Matthias
  • 3,833
  • 11
  • 36
  • 74
user218867
  • 16,252
  • 12
  • 112
  • 156
13

you may hit git ls-files -u on your command line it lists down files with conflicts

Emil Reña Enriquez
  • 2,572
  • 1
  • 26
  • 30
3

Maybe this has been added to Git, but the files that have yet to be resolved are listed in the status message (git status) like this:

#
# Unmerged paths:
#   (use "git add/rm <file>..." as appropriate to mark resolution)
#
#   both modified:      syssw/target/libs/makefile
#

Note that this is the Unmerged paths section.

Patrick O'Hara
  • 517
  • 5
  • 17
3

If you attempt to commit, and if there are conflicts, then git will give you the list of the currently unresolved conflicts... but not as a plain list. This is usually what you want when working interactively because the list gets shorter as you fix the conflicts.

Tel
  • 31
  • 1
  • 2
    "interactively because the list gets shorter as you fix the conflicts." Interesting. I've always used mergetool for that purpose. – inger Oct 25 '11 at 17:35
2

I would also suggest the following command if you are working on a local git repository or in a directory in which patch -p1 --merge < ... was applied.

grep -rnw . -e '^<<<<<<<$'
Deniz da King
  • 178
  • 1
  • 2
  • 11
1

Assuming you know where your git root directory, ${GIT_ROOT}, is, you can do,

 cat ${GIT_ROOT}/.git/MERGE_MSG | sed '1,/Conflicts/d'
0

I've always just used git status.

can add awk at the end to get just the file names

git status -s | grep ^U | awk '{print $2}'

Ascherer
  • 7,864
  • 3
  • 39
  • 60
0

My 2 cents here (even when there are a lot of cool/working responses)

I created this alias in my .gitconfig

[alias]
 ...
 conflicts = !git diff --name-only --diff-filter=U | grep -oE '[^/ ]+$'

which is going to show me just the names of the files with conflicts... not their whole path :)

Manu
  • 6,365
  • 4
  • 43
  • 58
0

Here's what I use to a list modified files suitable for command line substitution in bash

git diff --numstat -b -w | grep ^[1-9] | cut -f 3

To edit the list use $(cmd) substitution.

vi $(git diff --numstat -b -w | grep ^[1-9] | cut -f 3)

Doesn't work if the file names have spaces. I tried to use sed to escape or quote the spaces and the output list looked right, but the $() substitution still did not behave as desired.

Michael
  • 5,910
  • 4
  • 52
  • 74
Darrel Lee
  • 1,991
  • 18
  • 19
0

Utility git wizard https://github.com/makelinux/git-wizard counts separately unresolved conflicted changes (collisions) and unmerged files. Conflicts must be resolved manually or with mergetool. Resolved unmerged changes can me added and committed usually with git rebase --continue.

Costa
  • 442
  • 6
  • 11
0

The answer by Jones Agyemang is probably sufficient for most use cases and was a great starting point for my solution. For scripting in Git Bent, the git wrapper library I made, I needed something a bit more robust. I'm posting the prototype I've written which is not yet totally script-friendly

Notes

  • The linked answer checks for <<<<<<< HEAD which doesn't work for merge conflicts from using git stash apply which has <<<<<<< Updated Upstream
  • My solution confirms the presence of ======= & >>>>>>>
  • The linked answer is surely more performant, as it doesn't have to do as much
  • My solution does NOT provide line numbers

Print files with merge conflicts

You need the str_split_line function from below.

# Root git directory
dir="$(git rev-parse --show-toplevel)"
# Put the grep output into an array (see below)
str_split_line "$(grep -r "^<<<<<<< " "${dir})" files
bn="$(basename "${dir}")"
for i in "${files[@]}"; do 
    # Remove the matched string, so we're left with the file name  
    file="$(sed -e "s/:<<<<<<< .*//" <<< "${i}")"

    # Remove the path, keep the project dir's name  
    fileShort="${file#"${dir}"}"
    fileShort="${bn}${fileShort}"

    # Confirm merge divider & closer are present
    c1=$(grep -c "^=======" "${file}")
    c2=$(grep -c "^>>>>>>> " "${file}")
    if [[ c1 -gt 0 && c2 -gt 0 ]]; then
        echo "${fileShort} has a merge conflict"
    fi
done

Output

projectdir/file-name
projectdir/subdir/file-name

Split strings by line function

You can just copy the block of code if you don't want this as a separate function

function str_split_line(){
# for IFS, see https://stackoverflow.com/questions/16831429/when-setting-ifs-to-split-on-newlines-why-is-it-necessary-to-include-a-backspac
IFS="
"
    declare -n lines=$2
    while read line; do
        lines+=("${line}")
    done <<< "${1}"
}
Reed
  • 13,861
  • 6
  • 61
  • 102
0

For me the accepted answer didn't work. To prevent from capturing

warning: LF will be replaced by CRLF in []. The file will have its original line endings in your working directory

In Powershell I used this instead:

git ls-files -u| ForEach{($_.Split("`t"))|Select-Object -Last 1}| get-unique
Mariusz
  • 131
  • 1
  • 5
-1

slight variation of Charles Bailey's answer that gives more information:

git diff --name-only --diff-filter=U | xargs git status
taj
  • 421
  • 5
  • 4
-2

As highlighted in other answer(s) we can simply use command git status and then look for files listed under Unmerged paths: