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

我只需要一个普通的冲突文件列表。

有什么比这更简单:

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

或:

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

我想我可以为此设置一个方便的alias,但是想知道专业人士是如何做到的。我会用它来编写shell循环,例如自动解决冲突等。也许通过插入mergetool.cmd来替换该循环?

542325 次浏览

试图回答我的问题:

不,似乎没有比问题中的方法更简单的方法了,开箱即用。

在输入了太多次之后,只是将较短的一个粘贴到一个名为“git-冲突”的可执行文件中,使git可以访问,现在我可以:git conflicts获取我想要的列表。

更新:正如Richard建议的那样,您可以设置一个git别名,作为可执行文件的替代

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

使用可执行文件而不是别名的一个优点是您可以与团队成员共享该脚本(在repo的bin dir部分中)。

如果您尝试提交,并且存在冲突,那么git将为您提供当前未解决冲突的列表…但不是普通列表。这通常是您在交互式工作时想要的,因为当您修复冲突时,列表会变短。

git status在有冲突的文件旁边显示“已修改”,而不是“已修改”或“新文件”等

git status --short | grep "^UU "

使用git diff,只有名字仅显示名称,diff-filter=U仅包含“未合并”文件(可选地,相对显示相对于当前工作目录的路径)。

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

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

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

我总是使用git status

可以在末尾添加awk来获取文件名

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

查尔斯·贝利的回答略有变化,提供了更多信息:

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

也许这已经添加到Git中,但尚未解决的文件在状态消息(git状态)中列出,如下所示:

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

请注意,这是未合并路径部分。

您可以在命令行上点击git ls-files -u,它会列出有冲突的文件

这对我有用:

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

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

git diff --check

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

例如:

> git diff --checkindex-localhost.html:85: leftover conflict markerindex-localhost.html:87: leftover conflict markerindex-localhost.html:89: leftover conflict markerindex.html:85: leftover conflict markerindex.html:87: leftover conflict markerindex.html:89: leftover conflict marker

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

正如其他答案中强调的那样,我们可以简单地使用命令git状态,然后查找未合并路径下列出的文件:

假设您知道git根目录${GIT_ROOT}在哪里,您可以这样做,

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

我在这里的2美分(即使有很多很酷/有效的回复)

我在我的.gitconfig中创建了这个别名

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

这将只向我显示有冲突的文件的名称……而不是它们的整个路径:)

这是我用来列出适用于bash中命令行替换的修改文件的内容

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

要编辑列表,请使用$(cmd)替换。

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

如果文件名有空格,则不起作用。我尝试使用sed转义或引用空格,输出列表看起来正确,但$()替换仍然没有按预期运行。

实用程序git向导https://github.com/makelinux/git-wizard分别计算未解决的冲突更改(冲突)和未合并的文件。冲突必须手动或使用mergetool解决。已解决的未合并更改可以我添加并提交,通常使用git rebase—继续。

Jones Agyemang的回答对于大多数用例来说可能已经足够了,并且是我解决方案的一个很好的起点。对于gitbent中的脚本,我制作的git包装器库,我需要更健壮的东西。我正在发布我编写的原型,它还不完全脚本友好

备注

  • 链接的答案检查<<<<<<< HEAD,它不适用于使用git stash apply的合并冲突,其中<<<<<<< Updated Upstream
  • 我的解决方案确认了=======>>>>>>>的存在
  • 链接的答案肯定更具性能,因为它不必做那么多
  • 我的解决方案不提供行号

打印有合并冲突的文件

您需要下面的str_split_line函数。

# Root git directorydir="$(git rev-parse --show-toplevel)"# Put the grep output into an array (see below)str_split_line "$(grep -r "^<<<<<<< " "${dir})" filesbn="$(basename "${dir}")"for i in "${files[@]}"; do# Remove the matched string, so we're left with the file namefile="$(sed -e "s/:<<<<<<< .*//" <<< "${i}")"
# Remove the path, keep the project dir's namefileShort="${file#"${dir}"}"fileShort="${bn}${fileShort}"
# Confirm merge divider & closer are presentc1=$(grep -c "^=======" "${file}")c2=$(grep -c "^>>>>>>> " "${file}")if [[ c1 -gt 0 && c2 -gt 0 ]]; thenecho "${fileShort} has a merge conflict"fidone

产出

projectdir/file-nameprojectdir/subdir/file-name

按行函数拆分字符串

如果您不想将其作为单独的函数,则可以复制代码块

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-backspacIFS=""declare -n lines=$2while read line; dolines+=("${line}")done <<< "${1}"}

如果您在本地git存储库或应用patch -p1 --merge < ...的目录中工作,我还建议使用以下命令。

grep -rnw . -e '^<<<<<<<$'

对我来说,公认的答案不起作用。为了防止捕获

警告:[]中的LF将被CRLF替换。该文件将在您的工作目录中具有其原始行结尾

在PowerShell中,我使用了这个:

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