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

Posted

技术标签:

【中文标题】在 Git 中列出冲突文件的最简单方法是啥?【英文标题】:What's the simplest way to list conflicted files in Git?在 Git 中列出冲突文件的最简单方法是什么? 【发布时间】:2011-03-05 04:27:03 【问题描述】:

我只需要一个冲突文件的简单列表。

还有什么比这更简单的:

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

或:

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

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

【问题讨论】:

git rebase --continue 会列出有冲突的文件(如果有的话) git状态就够了 在冲突的合并会话中` git merge --continue` 将显示有冲突的文件列表。 git rebase --continue 没有列出冲突,只是告诉我修复它们(git 版本 2.21.0) 【参考方案1】:

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

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

在 Powershell 中我改用了这个:

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

【讨论】:

【参考方案2】:

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

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

【讨论】:

【参考方案3】:

answer by Jones Agyemang 对于大多数用例来说可能就足够了,并且是我解决方案的一个很好的起点。对于Git Bent(我制作的 git 包装库)中的脚本,我需要一些更强大的东西。我正在发布我编写的原型,但它还不是完全适合脚本的

注意事项

链接的答案检查 &lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD 不适用于使用具有 &lt;&lt;&lt;&lt;&lt;&lt;&lt; Updated Upstreamgit stash apply 的合并冲突 我的解决方案确认存在======= & &gt;&gt;&gt;&gt;&gt;&gt;&gt; 链接的答案肯定更高效,因为它不需要做那么多 我的解决方案不提供行号

打印有合并冲突的文件

您需要下面的str_split_line 函数。

# 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

输出

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

按行函数拆分字符串

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

function str_split_line()
# for IFS, see https://***.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"

【讨论】:

【参考方案4】:

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

【讨论】:

【参考方案5】:

这是我用来列出适合在 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 转义或引用空格,输出列表看起来正确,但 $() 替换仍然没有达到预期的效果。

【讨论】:

【参考方案6】:

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

【讨论】:

我发现 git diff --check 也告诉我其他(不太严重的)问题,比如尾随空格,所以 git diff --check | grep -i conflict 可能适合 OP 的情况 git diff --check 使用 core.whitespace 中的空白规则。您可以在 git 调用期间禁用所有空格检查以获取冲突标记:git -c core.whitespace=-trailing-space,-space-before-tab,-indent-with-non-tab,-tab-in-indent,-cr-at-eol diff --check 不错!它还显示诸如尾随 ws 之类的东西 git diff --check 返回空即使git diff --name-only --diff-filter=U 返回文件正常吗?【参考方案7】:

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

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

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

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

【讨论】:

+1 用于使用别名,但这会删除文件路径(仅保留基本名称),这使得管道到其他程序(如 git conflicts | xargs code 不可能。应该只删除 grep,如:@987654321 @【参考方案8】:

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

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

【讨论】:

【参考方案9】:

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

【讨论】:

【参考方案10】:

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

【讨论】:

确实如此。然而,这个特定的问题是关于一个简单的冲突文件列表。这可能是一个 XY 问题(我不记得为什么我实际上需要那个冲突列表,但我不需要它的事实可能表明我应该当时采用了不同的方法。现在不确定..我还在编写脚本来自动解决需要此列表的 java-import 冲突,即非交互式使用).. 哦,我不明白。我以为您想要一个“正常”列表以供“正常”使用。这就是为什么我对你自己的代码和你的自我回答感到害怕......然后我意识到“两者都修改过”对我有用(我假设你只是想要和我一样,你为什么不呢?;- P ) 感谢您的支持:) 也可能存在合并冲突,其中一个分支删除了一个文件,而另一个分支修改了它。 git status | grep "both modified" 不会显示这些。【参考方案11】:

这对我有用:

git grep '&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD'

git grep '&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD' | less -N

【讨论】:

冲突可能包括此解决方案不会涵盖的已修改文件和已删除文件。【参考方案12】:

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

【讨论】:

【参考方案13】:

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

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

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

【讨论】:

【参考方案14】:

Charles Bailey 的回答略有不同,提供了更多信息:

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

【讨论】:

【参考方案15】:

我一直只用git status

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

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

【讨论】:

【参考方案16】:

这是一个万无一失的方法:

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

【讨论】:

没有。即使删除了文件中的文本标记,Git 的索引仍会在内部将某些文件标记为冲突。 除了 Alexander 的评论,将其视为一个选项仍然很有用 :) 请不要删除。 或者在当前工作目录中运行使用点作为路径 - grep -H -r "&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD" . 呵呵,这也是我的做法。添加c 也可以很好地计算冲突数量!一个注意事项是我会使用标志-Hrn 这也将提供行号信息。 如果您使用的是正则表达式,我建议您使用[&lt;=&gt;]7 而不是这个。 (可能需要 -E 标志才能在 grep 中工作。)或者,&lt;7 如果您不担心悬空合并标记或想要计算冲突。 (您也可以使用git grep - 那么您就不需要-r 标志。)【参考方案17】:

试图回答我的问题:

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

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

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

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

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

【讨论】:

我当时也有同样的感觉——想着人们怎么不需要这个,看到解决方法是多么的微不足道。但是,我已经使用 git 2 年了,老实说,我再也没有遇到过这种“限制”。所以也许这毕竟不是常见的用例? 这很简单,你可以为它设置一个别名git config --global alias.conflicts "!git ls-files -u | cut -f 2 | sort -u"(! 表示运行这个 shell 命令,而不仅仅是一个 git 命令)。 值得一提的是,您实际上想要“单引号”而不是“双引号”。否则,! 将由您的 shell 解释:git config --global alias.conflicts '!git ls-files -u | cut -f 2 | sort -u'【参考方案18】:
git diff --name-only --diff-filter=U

【讨论】:

我为此创建了一个别名:git config --global alias.conflicts "diff --name-only --diff-filter=U" @CharlesBailey,我错过了什么吗? git status 有什么错误 @Pacerier,它只是更混乱。如果你有一百万个不冲突的合并和一个冲突的合并,你会想要一些简洁的输出。 @sAguinaga:只需运行git conflicts 即使在解决了冲突之后也会继续显示文件。 git diff --check 效果更好。【参考方案19】:
git status --short | grep "^UU "

【讨论】:

注意:您可能还需要搜索^UA和^UD,因此以下模式更完整:“^U[UAD]” ^U 以获取以 U 开头的所有内容 这还不够。冲突文件可以有以下组合:DD, AU, UD, UA, DU, AA, UU @AnthonySottile:你能解释一下这些场景吗?我发布了适用于我的案例的内容。 @self 还有^(.U|U.|AA|DD)【参考方案20】:

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

【讨论】:

"交互式地,因为当您解决冲突时,列表会变短。"有趣的。为此,我一直使用 mergetool。

以上是关于在 Git 中列出冲突文件的最简单方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

识别印度游客的最简单、最轻松的方法是啥?

在 jQuery 中每 5 秒调用一次函数的最简单方法是啥? [复制]

在文件中存储对象/充满对象的地图的最简单方法是啥?

在 Perl 中写入文件时测试错误处理的最简单方法是啥?

在 Java 中解析 INI 文件的最简单方法是啥?

查找过去一小时内修改的文件的最简单方法是啥?