git rebase 介紹


git rebase是對commit history的改寫。當你要改寫的commit history還沒有被提交到遠程repo的時候,也就是說,還沒有與他人共享之前,commit history是你私人所有的,那么想怎么改寫都可以。

而一旦被提交到遠程后,這時如果再改寫history,那么勢必和他人的history長的就不一樣了。git push的時候,git會比較commit history,如果不一致,commit動作會被拒絕,唯一的辦法就是帶上-f參數,強制要求commit,這時git會以committer的history覆寫遠程repo,從而完成代碼的提交。雖然代碼提交上去了,但是這樣可能會造成別人工作成果的丟失,所以使用-f參數要慎重。

要解決這個問題,就要從提交流程上做規范。

舉個正確流程的栗子:

假設樓主的team中有兩個developer:tom和jerry,他們共同使用一個遠程repo,並各自clone到自己的機器上,為了簡化描述,這里假設只有一個branch:master

這時tom機器的repo有兩個branch
master, origin/master
而jerry的機器上也是有兩個branch
master, origin/master

均如下圖所示

tom和jerry分別各自開發自己的新feature,不斷有新的commit提交到他們各自私有的commit history中,所以他們的master指針不斷的向前推移,分別指向不同的commit。而又由於他們都沒有git fetchgit push,所以他們的origin/master都維持不變。

jerry的repo如下

tom的repo如下,注意T1和上圖的J1,分別是兩個不同的commit

這時Tom首先把他的commit提交的遠程repo中,那么他本機origin/master指針則會前進,和master指針保持一致,如下

遠程repo如下

現在jerry也想把他的commit提交到遠程repo上去,運行git push,毫無意外的失敗了,所以他git fetch了一下,把遠程repo,也就是之前tom提交的T1給拉到了他本機repo中,如下

commit history出現了分叉,要想把tom之前提交的內容包含到自己的工作中來,有一個方法就是git merge,它會自動生成一個commit,既包含tom的提交,也包含jerry的提交,這樣就把兩個分叉的commit重新又合並在一起。但是這個自動生成的commit會有兩個parent,review代碼的時候必須要比較兩次,很不方便。

jerry為了保證commit history的線性,決定采用另外一種方法,就是git rebase。jerry的提交J1這時還沒有被提交到遠程repo上去,也就是他完全私有的一個commit,所以使用git rebase改寫J1的history完全沒有問題,改寫之后,如下

注意J1被改寫到T1后面了,變成了J1`

git push后,本機repo

而遠程repo

異常的輕松,一條直線,沒有-f

所以,在不用-f的前提下,想維持樹的整潔,方法就是:在git push之前,先git fetch,再git rebase

git fetch origin master git rebase origin/master git push 

強烈推薦閱讀

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM