首先要明白的是 git rebase 可以用来解决和 git merge 一样的问题,两个命令都是被设计出来将一个分支的改变合并到另一个分支里,只是两者的实现方式截然不同而已。
原文链接: https://www.atlassian.com/git...
作者: atlassian
merge VS rebase
假设这样的情况,你开始在一个专用的的分支上写一个新的功能,然后团队的其他人在 master 分支上更新的新的 commit。 这导致出现了分叉的历史,这对于使用过 git 的人是经常遇到的事情。
现在,由于 master 上新的 commit 对于当前 feature 分支是有意义的,为了将新的 commit 加入到 feature 分支里,你有两个选择: merging 或者 rebasing
选择 Merging
将 master 合并到 feature 分支最容易的方法:
git checkout feature
git merge master
或者考虑一行合并:
git merge master feature
这样将在 feature 分支创建一个 “合并分支“ 的 commit, 表示将两个分支的历史合并到一起,合并的解构图如下:
因为 merging 是一个非破坏性的操作,所以是个很好的合并方法, 已经存在的分支并不会被修改,它避免了 rebasing 潜在的各种陷阱和问题。但在另一方面,也意味着每次当你需要吸收上游的改变, feature 分支就会有一个外来的代表合并的 commit。 如果 master 分支非常活跃,会对你的 feature 分支造成大量的历史污染。它会让其他开发者难以看懂或者说理解你的项目的历史记录。
选择 rebase
作为合并的另一个选择,你可以使用以下命令实现 rebase feature 分支到 master 分支上:
git checkout feature
git rebase master
这个操作将整个 feature 分支移动到 master 分支上,高效的合并了所有新的 commit。但是,rebase 没有使用一个代表 merging 的 commit,而是通过为原来分支的每一个 commit 创建新的 commit, 重写了项目的历史 commit。
rebaseing 最主要的好处是你的项目历史变得更加清晰。第一,它消除了不必要的代表 merging 的commit;第二,从上面的图你可以看到,整个项目历史是线性而没有分叉的,你不用任何的 forks 只需要从头看到尾。使用 git log, git bisect 和 gitk 可以更清晰地查看和操作你的整个项目
但是,清晰的commit 历史代价是 安全(safety) 和 可追溯性(traceablility)。如果你不遵循 rebasing 的黄金法则,那么重写项目历史记录将会对你的团队合作造成灾难性的破坏,同时,rebasing 也将丢弃代表 merging 的commit,这意味着你无法查看什么时间点将上游的修改吸收进了你的 feature 分支
交互 rebasing
使用交互 rebasing 让你有机会在合并新分支时修改 commit 信息。由于它提供了复杂完整的控制权让你操作分支的 commit 历史,所以比自动 rebasing 更强大。特别地,在将一个 feature 分支合并 master 分支前,它被用来整理混乱的历史 commit
传递 i 参数到 rebase 命令来开始交互 rebasing 操作:
git checkout feature
git rebase -i master
命令会打开一个编辑器,列出所有将被移动修改的 commit
pick 33d5b7a Message for commit #1
pick 9480b3d Message for commit #2
pick 5c67e61 Message for commit #3
这个列表定义了 rebase 之后分支的历史记录的样子, 通过改变 pick 命令和修改入口的顺序,你可以将历史记录修改成你想要的样子。例如,对于第二个 commit, 如果它是用来修复 commit 1 里一个很小的问题,你可以使用 fixup 命令将它们合并成一个:
pick 33d5b7a Message for commit #1
fixup 9480b3d Message for commit #2
pick 5c67e61 Message for commit #3
当你保存并关闭这个文件时, Git 会按照你保存后的结构来进行 rebase,结果如下图:
消除掉无关紧要的 commit,让你的项目历史记录更容易理解,这是 git merge 无法做到的事情
Rebasing 的黄金法则
当你明白了什么是 rebasing,接下来更重要的是清楚什么时候不该使用它。 git rebase 的黄金法则是永远不要在公共分支上使用它。
举个栗子,如果 rebase master 分支到你的 feature 分支上,会发生什么事情?
rebase 操作会将 master 上面所有的 commit 移动到 feature 分支上。问题在于这些改变只发生在你本地版本库上。 其他的开发者仍然在原来的 master 分支上做开发。因为 rebasing 会创建新的 commit, Git 会认为你的 master 分支的历史已经和所有其他人的出现分叉。
把两个master 分支合并到一起的唯一方法是再将它们俩合并到一起,结果会多出一个额外的合并 commit和两组包含相同修改信息的 commit(一组来自原始 master,一组来自你的 reabsed 分支)。
因此,在使用 git rebase 命令前,总是问你自己, “这个分支有其他人在使用吗?”
如果有的话,将你的手从键盘拿开,然后想一个不破坏结构的方式来提交你的修改(例如 git revert command)。如果为否,那么你可以随心所欲地重写项目的历史记录
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。