gpt4 book ai didi

git - 可以使用我们的/他们的解决单个文件上的Git冲突吗?

转载 作者:太空狗 更新时间:2023-10-29 13:37:02 25 4
gpt4 key购买 nike

我发现了许多关于堆栈溢出和使用ours/theirs动态解决冲突的指令,在您只想用另一个文件(特别是二进制文件)覆盖一个文件的情况下。然而,在我发现的几乎每个示例中,它总是被集体应用于所有冲突,而我只想将它应用于单个冲突文件。
我找到的一个解决方案是使用git mergetool命令。然而,mergetool给了我一些问题,在这里我选择了“choose left”或“choose right”,但什么也没有发生。
不过,不管mergetool是什么,我还是想知道是否有方法可以从命令行执行此操作。我肯定有,如果有人让我知道这个命令,或者把我和那个我一定找不到的问题联系起来,我会非常感激的。
我也试过用…
Git签出--它们的路径/到/冲突/文件
但当我输入“git status”时,它仍然显示文件冲突。
非常感谢你抽出时间。

最佳答案

TL;博士
您需要git add最终分辨率,除非您使用不同的方法提取“我们的”或“他们的”版本。

每个合并工具都独立于git(git只是运行它们并让它们做它们自己的事情),因此对于这个问题的特定子部分,您必须参考合并工具本身。
至于git checkout --oursgit checkout --theirs,这就是Git调用索引显示其复杂程度的地方。请记住,索引,这是一种神秘的东西,也被称为暂存区(staging area),有时被称为缓存(cache),本质上是您和git建立下一次提交的地方。
当你跑步时:

git merge <commit-or-branch-specifier>

Git发现三个提交:
一个是您当前的提交,这是您在任何给定时间都在使用的提交,所以这并不特别,除了您可以使用名称 HEAD或单个字符 @来引用它(例如, git rev-parse HEADgit rev-parse @来获取其散列ID)。
一个是你刚才提到的承诺。如果您运行了 git merge otherbranch,则可以运行 git rev-parse otherbranch来查看其提交哈希ID是什么。(分支名称具有移动的属性:即,现在由分支名称标识的提交不一定是昨天或明天由该名称标识的提交。当然,如果运行 git merge a123456,则另一个提交(即 --theirs的提交)是hash id a123456
最后一次提交是merge base,git会自动为您找到它。它通过使用来自您的提交和另一个提交的父链接来查找此提交,并通过两个分支向后工作,直到找到两个分支首先返回到一起的适当点。
找到这三个提交后,git运行,实际上:
git diff --find-renames <merge-base> <ours>    # see what we changed
git diff --find-renames <merge-base> <theirs> # see what they changed

作为动词合并的合并过程包括查找这三个提交、执行diff和合并更改。当两组更改影响同一行时,将发生合并冲突。
在没有合并冲突的文件中,git将结果放入工作树(作为普通文件)和索引(作为文件的特殊git格式,准备提交)。因此,对于未经许可的文件,通常无需执行其他操作。
但是,当出现合并冲突时,git会做两件不寻常的事情:首先,它将合并冲突版本写入工作树,以便您可以将其编辑为一个普通文件。其次,它写入索引,不是文件的一个版本,而是全部三个版本:合并基版本、“我们的”版本和“他们的”版本。
git将这些额外的版本称为更高的阶段。stage number是合并基,没有访问它的 --base选项,但是可以使用 git show :1:path来查看它。第二阶段是“我们的”版本:有 --ours但是你也可以运行 git show :2:path来查看它。第3阶段是“他们的”版本,可通过 git show :3:path获得。这三个阶段取代了正常的阶段零入口,现在已经丢失了。
实际上,当您运行 git mergetool时,所做的就是在索引中找到这三个版本,将它们提取到常规(非git化)文件中,并对这三个文件运行实际的合并工具。合并工具被假定做了正确的事情(不管结果如何),将三个文件合并成一个合并文件,然后 git mergetool可以对结果运行 git add
在命令行中,尽管这是我进行合并的方式,但您可以编辑工作树文件及其冲突标记,并找出正确的结果。写出来, git add得到的文件,你是好的,因为 git add注意到文件存在于三个阶段的版本形式中,并擦除了这三个版本,而写入了零级。
一旦有了阶段0(不再是阶段1-3),文件就被视为已解析。
现在, git checkout --ours -- path只告诉git:从索引中取出stage-2版本并将其放入工作树中。带有 --theirs的版本告诉git取而代之的是stage-3版本。在这两种情况下,包含三个阶段版本的索引都是单独存在的。这只从索引中提取到工作树。(这里的 --只是为了防止 path部分是一个名为 --theirs的文件。如果文件名与选项不相似,则不需要 --。一直使用 --是一种好习惯,但大多数人不会。)
由于索引仍具有所有三个分阶段版本,因此尚未解析该文件。运行 git add获取工作树文件并将其放在槽0中,删除1到3个条目,现在文件被解析。
奇怪的是,运行 git checkout HEAD -- pathgit checkout otherbranch -- path会导致文件被解析。这是git的一个工件,它允许实现指定接口:在内部,当您使用 git checkout name -- path时,git必须首先在给定的 name中找到文件的git形式(提交散列或类似于 HEADotherbranch的名称)。然后它必须将git表单复制到索引中…这种复制会擦除插槽1-3条目,写入正常的插槽0条目。最后,git将(git form)文件从索引项0提取到工作树。
这种“先写入索引,然后从索引到工作树中提取”的副作用是,如果文件处于冲突状态,并且阶段1-3处于活动状态,则不再冲突!因此:
git checkout --ours -- file

不解析文件(因为它从索引槽2提取),但是:
git checkout HEAD -- file

确实解析该文件(因为它从当前提交中提取,转到索引槽0,删除1-3;然后从它刚刚写入的槽0项中提取)。

关于git - 可以使用我们的/他们的解决单个文件上的Git冲突吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48116019/

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