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
?
git rebase --continue
will list files with conflicts (if there are any)
git rebase --continue
didn't list the conflicts, just told me to fix them (git version 2.21.0)
Use git diff, with name-only to show only the names, and diff-filter=U to only include 'Unmerged' files (optionally, relative to show paths relative to current working directory) .
git diff --name-only --diff-filter=U --relative
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
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
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
git diff --check
returns empty even git diff --name-only --diff-filter=U
returns files is it normal?
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 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).
!
will be interpreted by your shell: git config --global alias.conflicts '!git ls-files -u | cut -f 2 | sort -u'
Here is a fool-proof way:
grep -H -r "<<<<<<< HEAD" /path/to/project/dir
grep -H -r "<<<<<<< HEAD" .
c
nicely results the count of conflicts too! One note is that I'd use flags -Hrn
this will also supply line number information.
[<=>]{7}
instead of this. (Might need -E
flag for that to work in grep.) Or, <{7}
if you're not worried about dangling merge markers or want to count the conflicts. (You can also use git grep
- then you don't need the -r
flag.)
git status
displays "both modified" next to files that have conflicts instead of "modified" or "new file", etc
git status | grep "both modified"
.
git status --short | grep "^UU "
^U
to get everything starting with U
DD, AU, UD, UA, DU, AA, UU
^(.U|U.|AA|DD)
.
This works for me:
git grep '<<<<<<< HEAD'
or
git grep '<<<<<<< HEAD' | less -N
you may hit git ls-files -u
on your command line it lists down files with conflicts
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 '^<<<<<<<$'
cf = "! bash -c 'grep --color=always -rnw \"^<<<<<<< HEAD$\"'"
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.
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.
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}'
Assuming you know where your git root directory, ${GIT_ROOT}, is, you can do,
cat ${GIT_ROOT}/.git/MERGE_MSG | sed '1,/Conflicts/d'
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 :)
git conflicts | xargs code
impossible. should just drop the grep, like: stackoverflow.com/a/21541490/2788187
git <alias>
. So in this case it would be git conflicts
slight variation of Charles Bailey's answer that gives more information:
git diff --name-only --diff-filter=U | xargs git status
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.
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.
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}"
}
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
As highlighted in other answer(s) we can simply use command git status and then look for files listed under Unmerged paths:
Success story sharing
git config --global alias.conflicts "diff --name-only --diff-filter=U"
git status
?git conflicts
git diff --check
works better.