ChatGPT解决这个技术问题 Extra ChatGPT

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

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

有什么比以下更简单的:

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 status 就够了
在冲突的合并会话中` git merge --continue` 将显示有冲突的文件列表。
git rebase --continue 没有列出冲突,只是告诉我修复它们(git 版本 2.21.0)
如果签入冲突标记,这些似乎都不起作用

J
Jimothy

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

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

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

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 <3 之类的东西
git diff --check 返回空,即使 git diff --name-only --diff-filter=U 返回文件是否正常?
这不适用于提交的代码。对签入代码的管道没有用
i
inger

试图回答我的问题:

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

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

更新:正如理查德建议的那样,您可以设置一个 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'
J
Jones Agyemang

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

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

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

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


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

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

这对我有用:

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

或者

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


冲突可能包括此解决方案不会涵盖的已修改文件和已删除文件。
E
Emil Reña Enriquez

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


D
Deniz da King

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

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

这可能是一个不错的解决方案,但对于更大的项目确实会减慢速度。
我正在使用 git 别名:cf = "! bash -c 'grep --color=always -rnw \"^<<<<<<< HEAD$\"'"
T
Tel

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


“交互式,因为当您解决冲突时,列表会变短。”有趣的。我一直为此目的使用mergetool。
P
Patrick O'Hara

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

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

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


A
Ascherer

我一直只使用 git status

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

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


T
Tzunghsing David Wong

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

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

M
Manu Artero

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

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

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

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


+1 用于使用别名,但这会删除文件路径(仅保留基本名称),这使得管道到其他程序(如 git conflicts | xargs code 不可能。应该只删除 grep,如:stackoverflow.com/a/21541490/2788187
创建别名的好主意。只是给其他人的信息,要运行别名,您需要像 git <alias> 一样为 git 添加前缀。所以在这种情况下,它将是 git conflicts
t
taj

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

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

M
Michael

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


C
Costa

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


R
Reed

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

笔记

链接的答案检查 <<<<<<< HEAD 不适用于使用具有 <<<<<<< 更新上游的 git stash apply 的合并冲突

我的解决方案确认存在 ======= & >>>>>>>

链接的答案肯定更高效,因为它不必做太多

我的解决方案不提供行号

打印有合并冲突的文件

您需要下面的 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://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}"
}

M
Mariusz

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

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

在 Powershell 中,我使用了这个:

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

s
sandesh

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