使用 git 和 meld 进行交互式变基的三向合并中的三个文件是什么?

2023-11-24

假设我做了一个交互式变基git rebase -i。如果出现一些冲突,我可能会遇到合并冲突并被要求进行三向合并。使用meld,我看到三个窗口:LOCAL(左边),???(中),以及REMOTE(正确的)。在这里由???我的意思很简单meld不提供一些特殊名称来附加到文件中。

在正常合并期间,这是有意义的,因为中间是共同祖先,并且您正在合并对该祖先的本地和远程更改。然而,在交互式变基过程中,情况似乎并非如此——不清楚每个文件代表什么。

在交互式变基过程中,三向合并中的这些文件各自代表什么?当编辑这些文件时,我的目标是什么?

Update:根据我看到的评论和实验:

  • Left (LOCAL):提交重播序列中此时文件的本地版本。
  • Right (REMOTE):最初应用当前提交后的文件状态。
  • Middle:原始提交序列中右侧的父级。

因此,我的任务是确定从中到右的增量,然后将该增量应用到左侧。中间应反映当前提交增量应用于新提交序列后文件的状态。

请注意,此配置似乎是特定于融合的,至少在某种程度上是这样。 Git 的三向合并行为对于其他编辑器可能有所不同。


中间版本是合并基础,就像git merge.

(名称“other”可能比“remote”更合适,因为不要求合并的另一端是远程的,而且 Mercurial 始终使用名称“other”,因此 Git 不需要匹配 Mercurial ,但一定的一致性可能会更好。请注意,Git 在这里也使用名称“我们的”和“他们的”,因此我们永远不会从 Git 获得 100% 的一致性。:-) )

但是等等,怎么会有合并基础呢?

always合并基地。

通常我们甚至不必找到它,因为每个补丁在被视为补丁时都会干净地应用(无需尝试三向合并)。但有时补丁无法完全应用,我们do必须退回到三路合并。

(顺便说一句,您可以禁用此后备。请参阅--3way, --no-3way, and am.threeWay in git-am 文档,尽管此处链接的页面已经过时,因为这些控件最近发生了更改。)

$ git rebase -i
pick aaaaaaa first commit
pick bbbbbbb second commit
pick ccccccc third commit

让我们也绘制提交图,这样我们就可以看到我们要变基的内容和变基的内容:

              A - B - C   <-- branch
            /
... - o - *
            \
              G - H       <-- origin/branch

我们将精挑细选提交A, B, and C (A = aaaaaaa等),最终我们得到这个结果:

              A - B - C   [abandoned]
            /
... - o - *           A' - B' - C'   <-- branch
            \       /
              G - H       <-- origin/branch

让我们仔细看看第一个选择,A.

这比较(差异)A针对其父级,即 commit*,并尝试应用生成的差异来提交H.

Commit H然而,与 commit 有所偏离*。事实上,我们可以找到一个合并基础A and H,这是...提交*。这实际上是一个相当不错的合并基础,尽管最好是 Git 可以按原样应用补丁,而不必退回到三向合并代码。

所以,提交*是挑选时的合并基础A onto H。合并完成后我们得到新的提交A'。 (其新的 SHA-1 ID 可能是aaaaaa1例如。可能不会;我们就这样称呼它吧A'.)

现在我们将挑选B。这有区别B与其父级相比,即A,并尝试将差异应用于A'.

Commit A', however, has drifted somewhat from commit B. In fact, we can find a merge base between B and A', and that is ... commit * again. Unfortunately, this is a wretched merge base. Fortunately, Git only falls back on it if the patch cannot be applied as-is, and usually it can. But if it can't, Git will diff * vs B and * vs A' and try to merge those two diffs. Note that * vs B incorporates all of the changes we made in A, but * vs A' also incorporates all of those same A changes, so if we are lucky, Git notices the already-incorporated changes and does not duplicate them. edit Git cheats. (This code has changed recently in version 2.6, although the overall strategy remains the same.)

考虑实际输出git diff当用于仅显示提交后的更改时A承诺B。这包括一个index line:

diff --git a/foo b/foo
index f0b98f8..0ea3286 100644

左侧的值是文件版本的(缩写)哈希值foo提交中A。右侧的值是提交中文件版本的哈希值B.

Git 只是从左侧散列伪造了一个合并基数。换句话说,commit中的文件版本A成为伪造的合并基础。 (Git 通过--build-fake-ancestor to git apply。这要求特定的文件 blob 对象位于存储库中,但它们是因为它们处于提交状态A。对于通过电子邮件发送的补丁,Git 使用相同的代码,但 blob 可能存在也可能不存在。)

请注意,Git 实际上在挑选提交时执行此操作A同样,但这次合并基础文件是提交的版本*,这确实是is合并基地。

Finally, we cherry-pick C. This diffs B vs C, just as we diffed A vs B last time. If we can apply the patch as is, good; if not, we fall back to using commit * as the merge base again. It is once again a pretty wretched merge base. the same way as before, pretending that the version in B was the common base.

This also explains, incidentally, why you tend to see the same merge conflicts over and over again for these rebases: we're using the same merge-base each time. (Enabling git rerere can help.)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 git 和 meld 进行交互式变基的三向合并中的三个文件是什么? 的相关文章

  • 重新打包存储库对于大型二进制文件有用吗?

    我正在尝试将大量历史记录从 Perforce 转换为 Git 并且一个文件夹 现在是 git 分支 包含大量大型二进制文件 我的问题是运行时内存不足git gc aggressive 我的主要问题是重新打包存储库是否可能对大型二进制文件产生
  • 分支明显不同,但提交历史是相同的

    git status告诉我我的分支和我在另一个存储库上开始的分支已经分歧 On branch master Your branch and origin master have diverged and have 13 and 13 dif
  • 如何解决 VSTS 中拉取请求中的合并冲突?

    我已经创建了拉取请求 我进入了这个 批准 按钮不执行任何操作 并且 完成 被禁用 如何解决拉取请求中的冲突 Update 微软刚刚添加了基于浏览器的合并 这可能会让你摆脱小冲突的困境 并提供自 Sprint 150 起改进了不同场景的可视化
  • 如何从 android.googlesource.com 或 github.com 下载单个目录?

    我想下载 https android googlesource com platform frameworks base git master tools aapt https android googlesource com platfo
  • 有谁知道类似于 SVN Time-Lapse View 的 Git 工具 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 SVN Time Lapse View 是一个跨平台查看器 可以下载文件的所有修订版本 并允许您通过拖
  • git reset 命令中的 ~1 是什么意思?

    git 重置 HEAD 1 我的印象是 1 的意思是 从 HEAD 开始 遵循 1 链接 并将 HEAD 标签设置为新的提交节点 我正期待着 git 重置 HEAD 2 跟随 2 个链接 然后设置 HEAD 标签 但是 如果我尝试它 我会收
  • git 显示已添加到 gitignore 的文件中的更改?

    我已经将 log2 文件夹和 main js 文件添加到 gitignore 如屏幕截图所示 但即使执行后git rm cached r我仍然可以看到 git 正在检测 main js 和 log2 文件夹内文件的更改 怎么会 这些的常见问
  • Git:发送电子邮件而不提交

    我有一个项目 我做了更改 并想使用 git send email 功能将它们发送给另一个用户 我发现它可以通过发送补丁来工作 由git format patch每次提交 是否可以只发送diff的 我不想先提交 然后发送补丁 是否有gitfo
  • Composer 用于下载私有 GitHub 存储库

    我无法使用 Composer 下载 github 私人存储库 php composer phar update 我收到以下错误 The https api github com repos company private1 https ap
  • 格里特:! [远程拒绝] HEAD -> refs/publish/master (没有新的更改)

    我做了一些更改 提交了它们并将分支推送到 Gerrit git push gerrit 现在我的更改没有出现在 Gerrit 中 我认为这是因为我手动推送更改而不是使用git 审查 https github com openstack in
  • Ansible bitbucket 克隆存储库配置 ssh 错误

    我之前发布过这个问题 但那里的答案不再有效 总之 当使用 Ansible 配置我的 vagrant box 时 在尝试使用 ssh 克隆我的 bitbucket 私有存储库时 我遇到了一个神秘的错误 该错误指出 权限被拒绝 公钥 然而 如果
  • VS 2015 + Bower:在防火墙后面不起作用

    Problem 在 Visual Studio 2015 中 使用 Bower 我的包在防火墙后面时恢复失败 并出现类似以下内容的错误 ECMDERR 无法执行 git ls remote tags heads git github com
  • 使用终端时 Git 推送在总计后卡住了?

    我尝试将一些文件推送到Github 总大小只有22 2M 我不知道为什么它在总行之后卡住了 我读过推送到 Github 时 Git 推送挂起 https stackoverflow com questions 16906161 git pu
  • apt-get 无法在 ubuntu dockerfile 中工作

    我对 docker 相当陌生 正在尝试通过编写自己的镜像来学习 并且目前正在阅读 Docker 的实际操作 ISBN 1633430235 在我自己的代码和书中的示例 第 146 页 中 我想通过 dockerfile 安装 git My
  • 如何使用 Git 跟踪目录而不是文件?

    我最近开始使用 Git 但只有一件事遇到了麻烦 如何在不跟踪目录内容的情况下跟踪目录 例如 我正在开发的网站允许上传 我想跟踪上传目录 以便在分支等时创建它 但显然不是其中的文件 在开发分支中的测试文件或主控中的真实文件 在我的 gitig
  • 使当前提交成为 Git 存储库中唯一(初始)提交?

    我目前有一个本地 Git 存储库 我将其推送到 Github 存储库 本地存储库有约 10 次提交 Github 存储库是其同步副本 我想要做的是从本地 Git 存储库中删除所有版本历史记录 以便存储库的当前内容显示为唯一提交 因此存储库中
  • 仅使用 Git grep 的文件名

    我只想查看文本中包含特定单词的不同文件 current directory git grep word 显示文件中具有匹配单词的每一行 所以我尝试了这个 current directory git grep word files with
  • 显示 master 之前/之后有多少提交分支的别名

    新的 Bitbucket Branches 页面非常棒 它显示每个分支领先 落后于 master 的提交数量 是否有显示相同信息的 Git 别名 信息应显示 分店名称 上次更新是什么时候 其背后有多少提交 有多少提交领先于 master 看
  • 如何在不在存储库中的情况下执行 Git 命令?

    有没有一种方法可以在不位于存储库的情况下对存储库执行 Git 命令 例如这样的事情 git home repo log 请不要告诉我cd到它 我正在通过一个exec call Use C作为 git 的第一个参数 git C home re
  • Git 无法识别重命名和修改的包文件

    我有一个名为的java文件package old myfile java 我已经通过 git 提交了这个文件 然后我将我的包重命名为new所以我的文件在package new myfile java 我现在想将此文件重命名 和内容更改 提交

随机推荐