Git 变基



在 Git 中,将一个分支的更改合并到另一个分支主要有两种方法:**合并** 和 **变基**。

合并是通过生成一个**合并**提交来完成的,这个提交包含两个分支的最新快照(如下图所示的 C3 和 C4)以及它们的共同祖先(C2)。

这种方法会添加一个合并提交,但会保持分支历史的完整性。

git merge 1

或者,通过在另一个分支 (C3) 上重放修改,变基允许我们将提交 (C4) 中引入的补丁应用。

**变基**是将一个分支的提交应用到另一个分支顶部的过程,通常不会生成合并提交,从而创建一个线性历史。

如下图所示,假设我们有一个从 **main** 分支分出的功能分支 (**feature**)。当您在 **feature** 上工作时,其他团队成员对 **main** 分支进行了更改。您可以将分支变基到 **main** 的顶部,而不是将 **main** 合并到您的 **feature** 中并创建合并提交。此过程会重新应用您的提交,就好像它们是在 **main** 的最新更改之后进行的一样,从而保持历史记录的简洁和线性。

git merge 2
$ git checkout feature
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: added staged command

变基的工作原理

执行 **git rebase** 命令时,Git 执行以下步骤:

  • **识别基底:** Git 查找当前分支与我们正在变基到的分支之间的共同祖先。

  • **临时保存您的提交:** Git 保存更改并临时从当前分支中删除提交。

  • **应用目标分支的更改:** Git 更新分支以匹配我们正在变基到的分支的状态。

  • **重新应用您的提交:** Git 将提交一个接一个地应用到新的基底(即目标分支)之上。

  • **更新分支指针:** Git 将分支的指针更新为具有变基提交的新状态。

让我们看下面的例子,假设 **feature** 分支有提交 `C4`,**main** 分支有提交 `C3`。当我们将 **feature** 变基到 **main** 时,Git 将重写历史记录,以便我们的分支现在看起来像是 `C4` 建立在 `C3` 之上。

git merge 3

对于此示例,我们将切换到 feature 分支,然后将其变基到 master 分支,如下所示:

$ git checkout feature
$ git rebase main

使用变基的优势

以下是变基的一些优势:

  • **更清晰的历史记录:** 变基创建一个干净的线性历史记录,使跟踪更改流程更容易。您只需要看到一条直线提交,而不是可能会使历史记录混乱的合并提交。

  • **易于阅读:** 在与大型团队合作时,具有多个分支和合并提交的历史记录可能难以理解。变基通过消除不必要的合并提交来简化此过程。

  • **更好的上下文:** 变基允许您将更改置于主分支上最新代码的上下文中,这可以使您更容易尽早发现集成问题。

Git 中变基的风险

在 Git 中,变基可以是一个非常有用的工具,用于维护整洁有序的提交历史记录。

  • **不要变基公共历史记录:** 使用 Git 变基时最重要的规则之一是**永远不要变基已与他人共享的提交**。将提交推送到远程存储库(如 GitHub)后,变基它们可能会导致与同一分支上工作的其他人出现问题。相反,将变基用于您的本地分支和尚未共享的功能分支。

  • **冲突解决:** 当 Git 尝试将更改应用到新的基底提交之上时,变基经常会导致冲突。发生冲突时,Git 将暂停变基过程并允许用户手动解决冲突。解决冲突后,用户可以使用…

    git rebase --continue
    

    如果用户想要中止变基过程并将分支恢复到其原始状态,可以使用…

    git rebase --abort
    

变基最佳实践

  • **将变基用于本地清理:** 变基是清理本地提交并在将其推送到共享存储库之前的好工具。这确保了提交历史记录保持整洁。

  • **交互式变基用于提交润色:** 使用交互式变基来组合、重新排序或编辑提交。这允许用户在为共享分支做贡献时呈现干净且逻辑的提交历史记录。

  • **避免变基共享分支:** 不要变基已推送到共享分支的提交,因为这可能会导致其他开发人员感到困惑和冲突。

  • **将变基用于功能分支:** 在处理功能分支时,请使用变基使更改与主分支保持最新,尤其是在将其合并到主分支之前。

  • **在测试分支上练习:** 在执行复杂的变基操作之前,请在测试分支上练习或使用 Git 的 reflog 在出错时恢复。

广告