[git] What's the simplest way to list conflicted files in Git?

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?

This question is related to git git-merge git-merge-conflict

The answer is


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.


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


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

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


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 '^<<<<<<<$'

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.


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


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


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


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

git diff --name-only --diff-filter=U | xargs git status

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.


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


git status --short | grep "^UU "

This works for me:

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

or

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


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

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

Here is a fool-proof way:

grep -H -r "<<<<<<< HEAD" /path/to/project/dir

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


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.


Examples related to git

Does the target directory for a git clone have to match the repo name? Git fatal: protocol 'https' is not supported Git is not working after macOS Update (xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools) git clone: Authentication failed for <URL> destination path already exists and is not an empty directory SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443 GitLab remote: HTTP Basic: Access denied and fatal Authentication How can I switch to another branch in git? VS 2017 Git Local Commit DB.lock error on every commit How to remove an unpushed outgoing commit in Visual Studio?

Examples related to git-merge

Abort a Git Merge Git pull - Please move or remove them before you can merge Git: How configure KDiff3 as merge tool and diff tool Git: How to pull a single file from a server repository in Git? How to resolve git error: "Updates were rejected because the tip of your current branch is behind" error: Your local changes to the following files would be overwritten by checkout Please enter a commit message to explain why this merge is necessary, especially if it merges an updated upstream into a topic branch How to merge specific files from Git branches git remove merge commit from history The following untracked working tree files would be overwritten by merge, but I don't care

Examples related to git-merge-conflict

What I can do to resolve "1 commit behind master"? Choose Git merge strategy for specific files ("ours", "mine", "theirs") Resolve Git merge conflicts in favor of their changes during a pull Git conflict markers How to undo a git merge with conflicts What's the simplest way to list conflicted files in Git? How can I discard remote changes and mark a file as "resolved"? How to resolve merge conflicts in Git repository? I ran into a merge conflict. How can I abort the merge?