Git rebase 和 merge 的区别及使用场景


在软件开发的江湖里,Git 是我们每个人的神兵利器。而在 Git 的众多武功招式中,rebasemerge 无疑是处理代码分支时最常用也最容易让人混淆的两种。今天,我们就用最接地气的方式,带你彻底搞懂这两个命令的区别,让你在团队协作中游刃有余,提交历史清晰得像一本小说。

Git Merge:最直接的合并方式

想象一下,你从主分支(比如 main)拉出来一个新分支 feature 来开发新功能。在你埋头苦干的时候,你的同事也向 main 分支提交了一些更新。现在你的新功能开发完了,需要把 feature 分支的代码合并回 main 分支。

git merge 就是最简单直接的办法。它会找到两个分支的共同祖先,然后将 feature 分支上新的提交和 main 分支上新的提交合并在一起,并生成一个新的“合并提交”(merge commit)。.

这个合并提交很特殊,它有两个父提交,分别指向 main 分支和 feature 分支的最新提交。. 这样做的好处是,它完整地保留了所有分支的开发历史,你可以清楚地看到 feature 分支是从哪里来的,又在哪个时间点合并回了主干。

案例:Merge实战

  1. 切换到 main 分支并更新到最新:

    git checkout main
    git pull
  2. 执行合并命令:

    git merge feature

    Git 会自动创建一个新的合并提交。如果顺利的话,你的代码就合并成功了。

  3. 处理冲突:
    如果在合并过程中,main 分支和 feature 分支修改了同一个文件的同一行,就会产生冲突。Git 会暂停合并,并提示你去解决冲突。. 你需要手动打开冲突文件,修改成你想要的样子,然后 git addgit commit 来完成合并。

优点:

  • 保留完整的历史记录:每一次合并都有据可查,对于代码审计和追溯问题非常有用。
  • 简单直观:对于新手来说,merge 的概念更容易理解。

缺点:

  • 复杂的提交历史:如果团队成员频繁地合并分支,提交历史图会变得非常杂乱,充满了各种分叉和合并提交,难以阅读。.

Git Rebase:让历史“变基”

rebase,中文翻译是“变基”,听起来有点玄乎,但其实原理很简单。还是上面的例子,当你开发完 feature 分支后,rebase 会做这样一件事:它会找到 feature 分支和 main 分支的共同祖先,然后把你 feature 分支上的新提交,一个个地在 main 分支最新的提交后面“重放”一遍。.

这个“重放”的过程,实际上是创建了新的提交。虽然提交的内容和你原来的一样,但是它们的 commit ID 是全新的。完成之后,你的 feature 分支就好像是直接从 main 分支最新的地方拉出来的一样,整个提交历史变成了一条直线,非常整洁。.

案例:Rebase实战

  1. 切换到 feature 分支并更新 main 分支:

    git checkout feature
    git fetch origin main
  2. 执行 rebase 命令:

    git rebase main

    或者 git rebase origin/main

  3. 处理冲突:
    rebase 解决冲突的方式是,它会暂停在第一个产生冲突的提交上,让你解决冲突。解决完后,使用 git add 标记为已解决,然后执行 git rebase --continue 继续重放下一个提交。. 如果你想放弃这次 rebase,可以执行 git rebase --abort。.

  4. 合并回主分支:
    rebase 完成后,切换回 main 分支,进行一次“快进式合并”(fast-forward merge),因为此时 feature 分支的所有提交都在 main 分支的前面。

    git checkout main
    git merge feature

优点:

  • 线性的提交历史rebase 最大的好处就是能创造一个非常干净、线性的提交历史,没有不必要的合并提交,阅读起来非常方便。.
  • 保持分支整洁:在开发长周期功能时,可以定期 rebase 主分支的更新,及时解决冲突,保持自己的功能分支与主干同步。.

缺点:

  • 修改了历史rebase 会创建新的提交来代替旧的,这是一种“修改历史”的行为。.
  • 协作风险:**永远不要在一个已经被推送到远程并且有多人协作的分支上执行 rebase**。. 因为这会改变提交历史,当其他团队成员拉取代码时,会造成严重的混乱。

总结:何时使用 Merge,何时使用 Rebase?

场景 推荐操作 原因
将开发完成的功能分支合并到主分支 merge 保留功能分支的完整开发历史,方便代码审查和追溯。
保持本地开发分支与远程主分支同步 rebase 避免在自己的开发分支上产生不必要的合并提交,保持历史记录的整洁。
清理本地未推送的提交 rebase -i (交互式rebase) 可以在推送前,合并、修改或删除一些本地的零散提交,让你的提交记录更有意义。
多人协作的共享分支 绝对不要 rebase 修改共享分支的历史会给其他协作者带来巨大的麻烦。

简单来说,可以遵循一个黄金法则:

rebase 来同步上游(主干)的变更,用 merge 来合并自己的工作到下游(主干)。

希望通过这篇口语化的讲解,你对 git rebasegit merge 有了更清晰的认识。在实际工作中,灵活运用这两个命令,不仅能提高自己的工作效率,也能让整个团队的协作更加顺畅,代码库的历史更加清晰可读。


  目录