Git中列出冲突文件的最简单方法是什么?

923
我只需要一个普通的列出冲突文件的列表。
是否有比这更简单的方法:
git ls-files -u  | cut -f 2 | sort -u

或:

git ls-files -u  | awk '{print $4}' | sort | uniq
我想我可以设置一个方便的`alias`来实现这个功能,但是我想知道专业人士是如何做的。我会用它来编写shell循环,例如自动解决冲突等。也许通过插入`mergetool.cmd`来替换该循环?

2
git status就可以了。 - Amruth A
1
在冲突合并会话中,git merge --continue 命令将显示存在冲突的文件列表。 - Jayan
8
git rebase --continue 没有列出冲突,只告诉我需要解决它们 (git 版本 2.21.0) - Gary
如果冲突标记被选中,则似乎所有这些都无效。 - TamusJRoyce
23个回答

1592

使用git diff,配合name-only参数来仅显示文件名,并使用diff-filter=U参数仅包括“未合并”的文件(可选地,relative参数将路径相对于当前工作目录显示)。

git diff --name-only --diff-filter=U --relative

187
我为此创建了一个别名:git config --global alias.conflicts "diff --name-only --diff-filter=U"。意思是创建一个名为“conflicts”的Git别名,以便在执行该命令时可以使用更短的别名来列出在合并过程中出现冲突的文件名。 - Jimothy
4
@CharlesBailey,我有什么遗漏吗?git status有什么问题吗? - Pacerier
13
@Pacerier,这只会让事情更混乱。如果您有一百万个没有冲突的合并请求和一个有冲突的合并请求,您会希望输出简洁明了。 - xster
12
只需运行git conflicts即可。 - Jimothy
14
即使解决了冲突,文件仍会继续显示。使用 git diff --check 效果更好。 - aksanoble
显示剩余8条评论

187

git diff --check

将显示包含冲突标记的文件列表,包括行号

例如:

> 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

来源: https://ardalis.com/detect-git-conflict-markers


6
我发现 git diff --check 还会告诉我其他(不太严重的)问题,比如尾随空格,所以对于 OP 的情况,可能需要使用 git diff --check | grep -i conflict - CCJ
2
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
1
git diff --check 返回空,即使 git diff --name-only --diff-filter=U 返回文件,这是正常的吗? - alper
1
这对于已提交的代码无效。对于需要检查代码的流水线也没有用处。 - TamusJRoyce
@cnlevy 感谢你的澄清。Git仍然不允许拉取和合并,因为在其他地方有一个标记表明存在合并冲突。我猜我期望有一个函数能告诉我为什么它声称存在合并冲突,而实际上并没有。 - undefined
显示剩余4条评论

51

这里有一个万无一失的方法:

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

13
即使移除文件中的文本标记,Git的索引仍会在内部将某些文件标记为冲突状态。 - Alexander Bird
11
除了亚历山大的评论外,把这个看作一种选择仍然有用 :) 请不要删除。 - WoodenKitty
3
若要在当前工作目录中运行,请在路径前使用一个点 - grep -H -r "<<<<<<< HEAD" . - David Douglas
3
如果你正在使用正则表达式,我建议使用[<=>]{7}代替它。(可能需要在grep中使用-E标志才能工作。)或者,如果你不担心悬挂的合并标记或想要计算冲突,则可以使用<{7}。(你也可以使用git grep - 那样就不需要-r标志。) - celticminstrel
H 标志表示显示文件名。r 表示递归,如果你使用 git grep 命令,应该使用 --files-with-matches 选项替代 H 标志。 - Timo
显示剩余4条评论

42

尝试回答我的问题:

不,似乎没有比问题中提到的更简单的方法。

因为多次输入这些命令太麻烦了,我将较短的命令粘贴到一个可执行文件中,命名为“git-conflicts”,并使其对git可用,现在我只需运行git conflicts即可获得想要的列表。

更新:如Richard所建议的,你可以设置一个git别名作为可执行文件的替代方案。

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

使用可执行文件的优势在于,您可以将该脚本与团队成员共享(位于存储库中的 bin 目录中)。


1
我当时也有同感 - 想着人们怎么可能不需要这个,而且看起来绕过它是多么的微不足道。然而,我现在已经使用 Git 两年了,老实说再也没有遇到过那种“限制”。所以也许这并不是那么常见的用例? - inger
4
这很简单,你可以设置一个别名来执行它:“git config --global alias.conflicts"!git ls-files -u | cut -f 2 | sort -u"”(!表示运行这个shell命令,而不仅仅是一个git命令)。 - Richard
1
值得一提的是,您实际上想要使用单引号而不是双引号。否则,! 将被您的 shell 解释:git config --global alias.conflicts '!git ls-files -u | cut -f 2 | sort -u' - umop

28

git status 显示冲突的文件旁边不是 "modified" 或 "new file",而是显示为 "both modified"


3
没错。不过这个问题实际上只是关于一份冲突文件的简单列表...这可能是一个 XY 问题(我不记得当初为什么需要那份冲突列表了,但是我自从那时以后没有再需要它,这可能表明我当时应该采取不同的方法。现在不太确定...我还在编写用于自动解决 Java 导入冲突的脚本,这需要使用这个列表,即非交互式使用)。 - inger
哦,我之前没有理解。我以为你想要一个“普通”的列表来供“普通”使用。这就是我对你的代码和自我回答感到惊慌失措的原因……然后我意识到“两者都修改过”的东西对我很有用(我认为你也想要和我一样的结果,你为什么不呢?;-P)虽然如此,还是谢谢你的赞! :) - Rafa
1
也可能存在合并冲突,其中一个分支删除了文件而另一个修改了它。这些不会显示为 git status | grep "both modified" - Kalinda Pride

23
git status --short | grep "^UU "

4
注意:您可能还需要搜索^UA和^UD,因此以下模式更完整:“^U[UAD]” - mda
或者只需输入“^U”以获取以U开头的所有内容。 - Ascherer
10
这还不够。冲突文件可能有以下组合:DD、AU、UD、UA、DU、AA、UU - anthony sottile
1
@AnthonySottile:你能解释一下情况吗?我发了我这种情况下有效的方法。 - mda
1
@self 还有 ^(.U|U.|AA|DD) - Michael
显示剩余5条评论

18
这对我有用: ``` git grep '<<<<<<< HEAD' ``` 或者 ``` git grep '<<<<<<< HEAD' | less -N ```

2
冲突可能包括修改与删除的文件,而此解决方案将无法涵盖。 - Koenigsberg

16

如果你在命令行上运行git ls-files -u,它会列出存在冲突的文件。


6
如果您在本地git存储库上工作或在应用了patch -p1 --merge < ...的目录中工作,我建议您使用以下命令。
grep -rnw . -e '^<<<<<<<$'

1
这可能是一个可以的解决方案,但在更大的项目中会变得非常缓慢。 - Dogunbound hounds
我正在使用git别名:cf = "! bash -c 'grep --color=always -rnw \"^<<<<<<< HEAD$\"'" - Marslo

5
如果你尝试提交,但出现冲突,git会给你当前未解决冲突的列表...但不是普通的列表。这通常是交互式工作时所需的,因为随着你解决冲突,列表会变得更短。

2
“交互式地进行操作,因为随着您解决冲突,列表会变得更短。”有趣。我一直使用mergetool来完成这个目的。 - inger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接