【问题标题】: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)

标签: git git-merge git-merge-conflict


【解决方案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://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}"
      }
      

      【讨论】:

        【解决方案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。
                        猜你喜欢
                        • 2021-04-13
                        • 2015-11-19
                        • 1970-01-01
                        • 2012-08-16
                        • 1970-01-01
                        • 2014-01-28
                        • 1970-01-01
                        • 1970-01-01
                        • 2011-12-09
                        相关资源
                        最近更新 更多