gpt4 book ai didi

git - 在源分支中列出冲突文件路径的命令是什么

转载 作者:行者123 更新时间:2023-12-02 19:47:53 26 4
gpt4 key购买 nike

当我尝试将source branch合并到target branch时,git识别出两个文件冲突。但是,这两个文件都对应source branchtarget branch中的不同文件路径(文件已移动和修改)。我需要在source branch中获取此冲突文件的路径。

请注意,我可以使用git diff --name-only --diff-filter=U列出合并冲突下的文件,但这会列出目标分支中的路径(因为我检出target branch并将source branch拖入其中)。

是否有命令列出源分支中冲突文件的路径?

最佳答案

当我尝试将“源分支”合并到“目标分支”时,git识别出两个文件冲突。但是,这两个文件都对应于“源分支”和“目标分支”中的不同文件路径(文件已移动和修改)。


为了更具体地说明这一点,我相信您做到了:

git checkout tgtbranch
git merge srcbranch


并得到:

CONFLICT (rename/delete): orig-filename deleted in HEAD and renamed
to new-filename in A. Version A of new-filename left in tree.
Automatic merge failed; fix conflicts and then commit the result.


(请注意,我用名为 AB的分支代替了分别为 srcbranchtgtbranch的分支来重现此冲突。此外, CONFLICT消息全部在一行上。我将其分为两部分,仅用于发布目的)


我需要在“源分支”中获取此冲突文件的路径。


从上面可以看到,此信息在 CONFLICT打印的 git merge消息中可用。

不幸的是,此信息至少在以后的任何地方都无法直接获得。您必须保存 CONFLICT消息。 (如果您没有保存 CONFLICT消息,请参见下面的两个其他选择。)

可用的是 git status打印的内容:

$ git status --short
UA new-filename
$ git status
On branch B
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)

Unmerged paths:
(use "git add <file>..." to mark resolution)

added by them: new-filename

no changes added to commit (use "git add" and/or "git commit -a")


我们还可以使用 git ls-files --stage来查看Git索引中的内容:

$ git ls-files --stage
100644 4466f6b253fc4b67ec2749befdd29b7c1f573e36 0 README
100644 923932af0c5b6ddc43c116c648cd793759949b66 3 new-filename


仅新文件名存在!

如果没有保存 CONFLICT行,该怎么办

方法1:重复合并

一种选择(可能是最简单的)是重复合并。当然,如果您要解决合并问题,则可能不想弄乱当前索引和工作树,这使操作变得有些棘手。您可以:


克隆存储库,以便拥有一个具有新索引和工作树的新克隆,或者
使用 git worktree add,前提是您拥有 git worktree


然后在新的克隆或工作树中重新合并。使用 git checkout检出 tgtbranch指向原始克隆(如果您是重新克隆的)或当前克隆(如果您使用的是 git worktree)的提交,然后运行 git merge将提交合并到 tgtbranch指向原始克隆(如果重新克隆)或当前克隆(如果使用 git worktree)。那是:

$ git rev-parse tgtbranch
<hash>
$ git rev-parse srcbranch
<hash>
$ cd /tmp && git clone <path> reclone && cd reclone
$ git checkout <hash> && git merge <hash>


如果您正在使用重新克隆过程,或者:

$ git worktree add --detach <path> tgtbranch
$ cd <path> && git merge srcbranch


如果您使用的是 git worktree方法。

此合并将吐出 CONFLICT行。保存!然后删除新的克隆或添加的工作树,其全部目的是获得 CONFLICT行。现在,您的问题已解决:您拥有原始文件名。

方法2:对合并基础使用 git diff

合并操作使用 tgtbranchgit diff --find-renames中检测到重命名。查找重命名的阈值设置为您随 -X find-renames=number参数提供的阈值,如果未指定数字,则设置为50%。

git diff是两个特定提交之间的区别:Git自动找到的合并基础提交和 tgtbranchsrcbranch的尖端提交(无论哪个分支Git“看到”了重命名:一个尖端提交都有一个重命名,与合并基础相比,另一个删除了)。

查找合并基础提交。这里有一个并发症,但是如果有并发症,它将立即显示。跑:

git merge-base --all srcbranch tgtbranch


例如,就我而言,我得到:

$ git merge-base --all A B
3a5c9ae0669e9969f8986810ea03c5283e0ac693


如果只打印一个提交哈希,那您就很好。如果它打印出多个,则可能应改为使用方法1。

既然您知道有一个合并基础,那么您可以运行两个 git diff --find-renames命令。添加 --name-status选项以限制输出量。您可能还想添加 --diff-filter=RD以仅显示重命名或删除的文件。就我而言,我忽略了这些选项,因为重命名或删除是我所做的全部事情:

$ git diff --find-renames --name-status A...B
D orig-filename
$ git diff --find-renames --name-status B...A
R064 orig-filename new-filename


这显示了已重命名/删除的文件:原始名称为 orig-filename,新名称为 new-filename

这种三点语法 A...B(或者在您的情况下为 tgtname...srcnamesrcname...tgtname)具有 git diff专有的一种特殊含义。在 git diff中(但在其他Git命令中则不是1),这意味着找到两个指定提交之间的合并基础,并将其用作diff的左侧。使用右侧的提交说明符作为diff的右侧。由于只有一个合并基础,因此这会使合并基础与右侧参数命名的提交有所不同。



1特殊的三点语法适用于所有常用的Git diff引擎,包括 git diff-tree以及面向用户的 git diff

在许多版本的Git中实施此方法存在一个错误,即如果存在多个合并基础,则结果是不可预测的。因此,请确保只有一个合并基础。



边注

如果我们直接在未合并状态下检查索引文件,则会找到具有原始文件名的 REUC记录:

$ od -c .git/index
0000000 D I R C \0 \0 \0 002 \0 \0 \0 002 ] 264 256 x
0000020 2 270 ) P ] 264 256 x 2 227 221 220 \0 \0 \0 ~
0000040 \0 320 ! a \0 \0 201 244 \0 \0 003 351 \0 \0 003 351
0000060 \0 \0 \0 W D f 366 262 S 374 K g 354 ' I 276
0000100 375 қ ** | 037 W > 6 \0 006 R E A D M E
0000120 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
0000140 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 201 244
0000160 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 222 9 2 257
0000200 \f [ m 334 C 301 026 306 H 315 y 7 Y 224 233 f
0000220 0 \f n e w - f i l e n a m e \0 \0
0000240 \0 \0 \0 \0 T R E E \0 \0 \0 006 \0 - 1
0000260 0 \n R E U C \0 \0 \0 - o r i g - f
0000300 i l e n a m e \0 1 0 0 6 4 4 \0 0
0000320 \0 0 \0 214 354 + 214 330 360 004 N O 355 \b 243 '
0000340 4 331 225 \n W [ 037 026 216 K } 367 ? 373 354 364
0000360 [ ^ 364 b 001 371 6 , 3 370 320
0000373


索引必须以 DIRC幻数开头,然后为我的两个文件都具有普通索引条目(如 git ls-files --stage输出所示,我只有两个)。但是它有一个 TREE记录,我们可以在偏移量 0000240附近看到它,然后在下一行显示 REUC记录。该REUC记录是“撤消”记录,它允许 git checkout -m重现合并冲突。而且,正如我们所看到的,撤消记录实际上存储了原始文件名。

Git实际上应该允许我们通过 git ls-files或更方便地通过 git status访问此信息。 las,事实并非如此。

关于git - 在源分支中列出冲突文件路径的命令是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58572646/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com