复杂合并的临时提交

时间:2016-06-10 17:42:35

标签: git workflow

我有两个分支master,它是主分支,而feature_branch_1是非常老的,许多提交在主人后面。我需要将feature_branch_1合并到master中,所以我做了:

git pull --rebase origin master

正如预期的那样,在需要在新的feature_branch_2上开发另一个功能之后不久就会发生大量冲突,这是针对主人的HEAD的,并且肯定需要在feature_branch_1之前进行{1}}。或多或少处于复杂合并的中间,我如何在feature_branch_1上进行临时提交,以便稍后再回过头来。我知道我可以做一个:

git add <things-that-are-done>
git commit -m 'intermediary commit between merges'
... come back to it later
git checkout 'that-temp-commit-hash'
... after finishing
git add .
git commit -m 'done with feature_branch_1'
git rebase --interactive HEAD~1

进行临时提交然后重新定位以便随后压缩它。

这是处理此问题的最佳方法吗?

1 个答案:

答案 0 :(得分:1)

Git不允许您使用包含未合并条目的索引进行提交。

使用git add将解析未合并的条目,以便您可以提交,但由于多种原因,这种方法可能不能令人满意。没有太多细节:

  • 通过使用索引槽1-3而不是插槽0来指示未解析的路径。这些路径保存文件的合并基础版本,以及两个“边”(--ours--theirs,虽然在rebase期间角色是合并的角色。
  • git add从工作树复制到插槽0,删除插槽1-3,以便现在解析文件(即使工作树文件仍然充满冲突标记)。
  • 此时也会在索引中记录“撤消”(REUC)条目,这样您就可以git checkout -m重新创建冲突的路径(擦除插槽0条目)并恢复1-3条目。)
  • 实际上提交合并结果会永久失去撤消状态。

这意味着,如果您执行提交部分合并,然后想要返回它并希望完成它,一些信息 - 特别是未合并状态,即使它被移动到撤消入口 - 缺失。您最近可以找到最接近哪些文件仍然需要正确合并的方法是搜索冲突标记。 (如果你没问题,这种方法毕竟可能是令人满意的。)

除此之外,rebase还会复制多次提交,而您还没有提到在最后一次提交时是否发生了此特定合并冲突。在进行其他操作之前,您需要完成或中止rebase。 (技术上可以在rebase中间做一些事情,但这很棘手。)

至于这一部分:

... come back to it later
git checkout 'that-temp-commit-hash'
... after finishing
git add .
git commit -m 'done with feature_branch_1'
git rebase --interactive HEAD~1

因为这个特殊的未合并状态(你很快就解决了“错误”,以便做其他事情并稍后再回来)是一个rebase而不是一个合并的结果,这个序列可以起作用。但是,用git commit --amend替换最后两个步骤会更简单,更普遍适用。 --amend选项告诉git commit使用当前提交的父代(而不是当前提交本身)进行新的提交。这适用于普通(单父,非合并)提交和实际合并(两个或更多父母)。

替代

你最好的选择可能就是单独留下这个工作树,然后另外一个处理其他问题。

最简单的方法是使用Git的每个版本,这是另一种克隆。

您可以通过克隆正在进行的rebase来制作额外的克隆。在具有硬链接的敏感系统上,如果您将存储库克隆到同一文件系统上的另一个存储库,使用本地路径(例如,git clone work/repo work/new-clone-for-fast-fix,从您工作的某个级别开始),Git将使用硬盘链接到底层包和对象,因此您只需要工作树空间。

如果您的Git相对较新(我建议至少使用Git 2.6,尽管2.5中有该功能),您可以使用git worktree add创建一个新的“链接工作树”。链接的工作树会记住其原始存储库(反之亦然),但也有一个私有索引/暂存区域。你可以将它放在你想要的任何分支上,并在那里做任何你喜欢的事情,包括创建其他分支或做其他的rebase,所有这些都不会打扰你的“主要”工作树和“主要”索引。