git rebase 实现细节

git rebase implementation details

我想搞清楚git-rebase的工作机制。 Documentation 提供了有关 git-rebase 做什么的信息,但没有评论它是如何做的?

我研究了 source code,制定了一些测试用例,到目前为止了解以下内容:
1. Git 维护 .git/rebase-apply 中的 rebase 状态(包含 patch、final-commit、head-name 等文件)
2. Git 使用 git-format-patch 创建所有必要的补丁文件(在 rebase-apply 中)
3. Git 使用 git-am 一个一个应用那些补丁

我想我遗漏了很多细节。我在哪里可以找到实施细节?是不是直接把补丁丢了就天真地打了?

你的总结基本完成了。 Rebase其实比较简单

  1. 首先,计算要做的工作。这基本上是 git rev-list <upstream>..<branch> 来识别所有需要移动的提交。
  2. 执行变基所需的信息在 .git 目录的状态文件夹中创建。有两个主要的变基后端,每个后端使用不同的文件夹:
    • 对于应用变基(基于补丁,目前默认),每个提交的补丁将被生成并保存在.git/rebase-apply
    • 对于合并变基(用于例如交互式变基),将在 .git/rebase-merge
    • 中生成包含提交列表以及如何应用它们的待办事项列表
    • 对于两个后端,包含目标引用和原始提交等信息的其他文件将生成并存储在状态文件夹中。
  3. 接下来,HEAD 被分离并设置为 onto 提交(新的基本分支,您将在其中应用这些更改)。
  4. 应用程序发生,直到无法应用提交。
    • 对于基于补丁的变基,补丁会按顺序应用。如果补丁应用失败,那么 Git 将尝试 cherry-pick 有问题的提交。这是因为 cherry-pick 能够将合并冲突写入索引和工作目录。
    • 对于基于合并的 rebase,提交是 cherry-picked。
  5. 如果 cherry-pick 因冲突而失败,变基将停止,您(用户)必须解决任何冲突并将它们 git add 到索引。解决所有冲突后,您可以 git rebase --continue.
  6. 应用所有冲突后,原始分支将更新为指向最终的重新提交的提交。

关于后端的一些关闭细节: 合并后端最初只是交互式 rebase 后端。它可以使用 --merge 选项手动调用,并且还用作 --onto 等的默认后端。 apply 后端较旧,最终可能会被 merge 后端完全取代。