1、Merge命令
merge
命令會保留所有提交的歷史時間。每個人對代碼的提交是各式各樣的,儘管這些時間對於程序本身並沒有任何意義,但是merge
的命令初衷就是爲了保留這些時間不被修改。
這樣也就形成了以merge
時間爲基準的網狀歷史結構。每個分支上都會繼續保留各自的代碼記錄, 主分支上只保留merge
的歷史記錄,子分支隨時都有可能被刪除。
子分子刪除以後,你能夠看到的記錄也就是,merge
(合併)某branch
(分支)到某branch
(分支)上了。這個歷史記錄描述基本上是沒有意義的。
(也就是子分支的歷史提交,在該分支刪除後,不能被保留。回退或者charry-pick
的時候,選擇性變少了。)
2、Rebase命令
rebase
命令會始終把你最新的修改放到最前頭,你會更有信心保證你的代碼運行暢通無阻,通過你自己的測試以後,你就可以放心的把代碼合併到主的branch
裏面了。
這裏值得一提的是,rebase
通常是發生在自己的個人branch
上的。它的基礎就是現有的主branch
,這樣做的好處就是保證每個人的代碼都可以運行在當前最新的主branch
的代碼上。
3、總結
rebase
命令好處:
-
rebase
命令是沒有合併操作的,它只是將當前分支所做的修改,重放到了目標分支的最後一次提交上。 -
rebase
命令最大的好處是你的項目歷史會非常整潔 ,最後的項目歷史呈現出完美的線性。你可以從項目終點到起點瀏覽而不需要任何的 fork。
rebase
命令壞處:
-
rebase
過程中,一個commit出現衝突,下一個commit也極有可能出現衝突,一次rebase
操作可能要解決多次衝突,同時合併的歷史脈絡(衝突)被物理消滅了。 - 安全性,如果你違反了 rebase 黃金法則,重寫項目歷史可能會給你的協作工作流帶來災難性的影響。
- 可跟蹤性,
rebase
操作不會有合併提交中附帶的信息,你看不到 feature(特徵) 分支中,併入了上游的哪些更改。
merge
命令:
-
merge
是一個合併操作,提交歷史記錄會出現分叉,顯得不是那麼簡潔。 -
merge
命令合併結果不好看,一堆線交錯,但合併有衝突的話,只要解一次就行了。
4、個人推薦
情況一
如果你想擁有一套穩定的,健壯的代碼,永遠要使用rebase
。不爲別的,就爲了可以給你提供一套清晰的代碼歷史記錄。
rebase
操作永遠不會導致多個歷史分支進行交織。它永遠都是一條線,純潔而又幹脆,輕輕爽爽的,從不拖泥帶水。
相反的,merge
操作會給你一套亂七八糟的代碼歷史。當你看到這樣的代碼歷史的時候,那個畫風我相信對你一定很熟悉。想着那個畫風感覺到一切都好無助,有個詞兒比較合適,叫做欲仙欲死。
情況二
但是從中國特色的敏捷開發情況(瘋狂改方案,迭代):
如果只是在本地修改一兩個commit,然後馬上提交到主要分支上,跑完所有unit test
(單元測試),integration test
(集成測試),regression test
(迴歸測試)等,直接發佈。也就是continuous integration
(持續集成)的理想狀態,那麼rebase
操作是極好的。保證了主線分支的線性,且萬一出事了可以準確的revert
(回退)。
那麼如上所述:
- 本地開發,如果經常需要
rollback
回滾,就用rebase
操作。 - 本地開發,靈活創建分支,也可以使用merge合併分支,方便解決衝突。
5、注意點
如果你違反了 rebase
黃金法則,重寫項目歷史可能會給你的協作工作流帶來災難性的影響。
rebase
的黃金法則:永遠不要在公共分支上使用rebase
操作。
在你運行 git rebase
命令之前,一定要問問你自己「有沒有別人正在這個分支上工作?」。如果答案是肯定的,那就不能進行rebase
操作。
一般來說,執行rebase
命令的分支都是自己的本地分支,千萬不要在與其他人共享的遠程分支上使用rebase
操作。
這不難理解,遠程分支上的代碼可能已經被其他人克隆到本地了,如果通過rebase
操作修改了遠程分支的提交歷史,這樣其他人每次拉取代碼到本地時,就都需要進行復雜的合併。
注意:git merge和git rebase的顯著區別是,前者不會修改git的提交記錄,而後者會!
提示:與遠程倉庫進行同步時,也可以執行命令
git pull --rebase origin master
參考: