分享 2 條命令讓你的 git 輕松自動變基

作者:張京?
鏈接:https://segmentfault.com/a/1190000040712052
為什么要變基
Git官方文檔中提到:
在 Git 中整合來自不同分支的修改主要有兩種方法:
merge?以及?rebase。
merge也就是合并,這個概念很容易理解,我們從分支上拉取代碼進(jìn)行修改,再提交的時候,如果遇到了別人的修改,則把我們的修改和他們的修改合并一下。那么rebase中文譯為變基是什么意思呢?
首先要理解這個base,base也就是基礎(chǔ)的意思,當(dāng)我們從代碼分支上獲取代碼的時候,我們就有了一個基礎(chǔ),也就是base,此后的修改我們都是在這個基礎(chǔ)之上進(jìn)行的,但是當(dāng)我們需要提交修改的時候,遇到了別人的代碼,變基這個操作就是在這個時候,我們不去合并別人的代碼,而是直接把我們原先的基礎(chǔ)變掉,變成以別人修改過后的新代碼為基礎(chǔ),把我們的修改在這個新的基礎(chǔ)之上重新進(jìn)行?;A(chǔ)變掉了,所以叫作變基。
那么,變基有什么好處呢?好處之一是可以使我們的時間線變得非常干凈,以前采用合并的時候,時間線里完整記錄了我們的代碼是從哪個基礎(chǔ)上拉取出來的,做了哪些修改,然后又在哪個時間點合并回分支去,而采用變基之后,時間線上不再反映拉取的時間點,因為每次提交都是以最新代碼為基礎(chǔ)的,所以時間線就變成了一根直線。
下面拿兩個真實例子給大家更直觀地看一下:
這是采用自動變基之前的時間線,可以看到,各種混亂:

這是采用自動變基之后的時間線,非常整齊,可以很清楚地看到哪一次修改之后又發(fā)生了什么修改,而不是多次修改糾纏在一起:

自動變基
雖然網(wǎng)上關(guān)于變基的教程很多,但是一般初學(xué)者總會感到茫然,不敢輕易下手,怕萬一把時間線弄壞了,一發(fā)不可收拾。而且所有關(guān)于變基的命令都和我們已經(jīng)多年習(xí)慣了的pull/add/commit/push不一樣,很多圖形化的工具例如vscode也不直接支持rebase這樣的命令,都需要手工輸入,繁瑣而且容易出錯。所以我們今天不講太多的rebase命令怎么用,而直接用兩條命令設(shè)置一下,從此以后讓你每次提交都可以自動變基,而不必改變之前的任何操作習(xí)慣。這兩條命令就是:
git?config?--global?pull.rebase?true
git?config?--global?rebase.autoStash?true
這兩條命令在任意一臺電腦上都只需要設(shè)置一次,而且一次設(shè)置,全局生效,所有的項目以后每次pull/push都會自動變基,再也不用擔(dān)心在提交之前忘記變基了。
原理
如果不想了解原理的話,則執(zhí)行完上面兩條命令就可以去開心地變基了,完全沒有問題。如果想了解一些原理,可以接著往下看。下面我們來詳細(xì)解釋一下這兩條命令的原理:
首先,我們要搞清楚一點:什么時機是變基的時機?一般理解是推送的時候,其實不是,而是從拉取的時候就要開始變基了,因為你拉取的時候,服務(wù)器上可能已經(jīng)有新代碼了,所以要變基也是在這個時候,一旦發(fā)現(xiàn)有新基礎(chǔ)了,則立馬變掉。
所以,通常情況下,我們拉取新代碼無非就是一個命令:git pull,但現(xiàn)在我們要變基拉取,就需要用git pull --rebase。但是每次這樣執(zhí)行命令就會很麻煩,而且你在vscode里也沒有辦法自動加這個參數(shù),所以為了方便起見,我們就設(shè)置一下第一條命令,這樣每次拉取它都會自動變基。
但是自動變基往往會帶來一個額外的問題,那就是每次當(dāng)你手頭有正在編輯的文件的時候,它就說它無法變基,因為你的工作區(qū)不干凈。為什么不變基的時候沒有這個問題,而一旦選擇了自動變基,工作區(qū)就必須保持干凈呢?因為變基的操作原理是它需要先把你本地代碼庫里還沒有推送的那部分提交反向釋放到工作區(qū),然后從服務(wù)器拉取新代碼,再以新代碼為基礎(chǔ)把工作區(qū)里的修改附加上去,因為有這個過程,所以它必須要求你的服務(wù)區(qū)是干凈的。
為此git提了兩個建議:要么你把所有修改先全部都commit到本地,要么你把它們都stash保存起來。首先說,commit肯定不是一個好主意,因為很有可能這時候我們的工作做到一半,還不適合commit,如果每次pull都commit一下的話,那么分支樹上會多出很多無用的節(jié)點。
那只剩下最后一個選擇,就是每次pull之前都stash一下,pull完了之后再把stash的內(nèi)容pop出來,但這樣豈不是更麻煩?所以這里我們用第二條命令設(shè)置一下,每次rebase的時候都自動把我們工作區(qū)里的內(nèi)容自動stash進(jìn)去,rebase完成之后再自動恢復(fù)出來。
其余要注意的就是有沖突的時候,如果有沖突,則合并完沖突之后,執(zhí)行一下git rebase --continue就好了,其它和原先的用法沒有任何區(qū)別。
- EOF -
