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个回答

3
也许Git已经添加了这个功能,但是未解决的文件会在状态消息(git status)中列出,如下所示:
#
# Unmerged paths:
#   (use "git add/rm <file>..." as appropriate to mark resolution)
#
#   both modified:      syssw/target/libs/makefile
#

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

2
假设您知道您的git根目录${GIT_ROOT}的位置,您可以执行以下操作:
 cat ${GIT_ROOT}/.git/MERGE_MSG | sed '1,/Conflicts/d'

1

我一直只使用git status

可以在末尾加上awk以仅获取文件名。

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


1

以下是 Charles Bailey 回答的略微变化,提供更多信息:

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

1

即使有很多酷炫/有效的回答,我也想在这里贡献一下我的看法。

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

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

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


1
使用别名是个好主意,但这会移除文件路径(只保留基本名称),这使得将其传输到其他程序(如 git conflicts | xargs code)变得不可能。应该放弃使用 grep,像这样:https://dev59.com/m3A75IYBdhLWcg3w3NBe#21541490 - Connor Clark
1
创建别名是个好主意。提供一个信息给其他人,运行别名需要在 git 前面加上 <alias>。所以在这种情况下,应该输入 git conflicts - Saurabh Bajaj

0

实用的Git向导https://github.com/makelinux/git-wizard可以单独计算未解决的冲突更改(碰撞)和未合并的文件。冲突必须手动解决或使用合并工具。已解决的未合并更改通常可以使用git rebase --continue添加并提交。


0

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

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

在Powershell中,我使用了这个替代方案:

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

0
这是我用来列出适合于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来转义或引用空格,并且输出列表看起来是正确的,但是$()替换仍然不能按照预期工作。


0

Jones Agyemang的答案可能已经足够满足大多数使用情况,并且是我的解决方案的很好起点。对于我编写的Git包装库Git Bent的脚本,我需要更强大的东西。我发布了我编写的原型,它还不完全适用于脚本友好型

注释

  • 链接的答案检查<<<<<<< HEAD,这对于使用git stash apply引起的合并冲突不起作用,其中有<<<<<<< Updated Upstream
  • 我的解决方案确认=======>>>>>>>的存在
  • 链接的答案肯定更有效率,因为它不必做太多事情
  • 我的解决方案不提供行号

打印有合并冲突的文件

您需要下面的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://dev59.com/SWQn5IYBdhLWcg3wcWzM
IFS="
"
    declare -n lines=$2
    while read line; do
        lines+=("${line}")
    done <<< "${1}"
}

0

你可以尝试一下

$ git status | grep both

一个示例输出可能是:

    both modified:   package.json

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