背景
今天干活時,突然看到大群裡有人艾特我,還甩了一張截圖:
注意!程式碼拉取不要用merge!!你這讓提交歷史變得很複雜,難以追溯問題!
我很火大,群裡艾特我膈應誰呢!
我反駁到:我沒用merge,我用的git pull啊!
同事立即回覆:我知道,你用rebase啊!
到這兒,我沒幹再反駁了,因為我不太清楚rebase
的意思,我開始懷疑是不是自己git pull
用錯了!用了快5年了,也不至於有大問題吧,我還是搜一下吧。
git pull裡的大學問
詳細瞭解完git pull的知識,我才知道,果然是我丟人了!
我想,幾乎所有的開發都知道git pull 命令用於從遠端倉庫獲取最新的更改併合併到當前分支,但估計只有部分知道它其實是 git fetch
和 git merge
的組合。
git fetch
git fetch
命令從遠端倉庫獲取最新的程式碼到本地,但不會自動合併程式碼。
git fetch <remote> <branch>
示例:從名為 origin 的遠端倉庫獲取最新程式碼:
git fetch origin
git merge
git merge
相信大家不陌生,就是將另一個分支的更改合併到當前分支。
通常在使用 git fetch 獲取了最新的遠端更改後,使用 git merge 將這些更改合併到當前分支。
git merge <branch>
git pull 的過程發生了什麼
當我們遠端有程式碼更新,我們需要拉取時
當我們執行git pull的時候,相當於以此執行了
git fetch :從雲端拉取最新程式碼
git merge:將雲端程式碼與原生代碼合併
git pull為什麼會導致git歷史混亂
假設我和我的同事在 master 分支上進行開發,我們都拉取了mater的B節點開發。
同事開發的快,提交了新的分支,現在遠端分支最新是C節點了。
隨後,我們也開發完畢了,但我們的程式碼落後遠端倉庫了,所以我們需要執行git pull拉取程式碼。這會從遠端倉庫獲取最新C節點的程式碼,和我們本地的程式碼合併,產生新的節點D。
最後,我們使用git push推送程式碼,遠端master分支就會產生一個新的D節點。
這種歷史記錄包含了多個分叉點和合並提交,就會導致git歷史看起來非常混亂,就像我這樣。
如何保證git歷史的線性
那麼,我們如何保證git 歷史的線性,像下圖這樣呢?
非常簡單,我們只需要使用rebase(變基)命令即可!在正式的介紹命令的使用前,我們先說說什麼是變基!
rebase變基簡介
簡單來說,rebase的作用就是永遠會讓我們本地的程式碼處於最新狀態。
比如,我們一開始是使用B節點開發程式碼的,開發到B2時,此時遠端已經有人推送了C節點。
在B2節點使用rebase變基,會讓我們的B1節點和B2節點位於C節點上。大概是這樣:
因此,使用rebase變基後,git永遠只有一天線性歷史,非常直觀。
rebase命令使用
rebase
的使用非常簡單,我們只需要在git pull的時候,新增上額外命令即可!
git pull --rebase
自動變基
每次提交程式碼都使用git pull --rebase
命令繁瑣而且容易出錯,我們可以全域性設定git pull預設使用變基的方式,一勞永逸!
// git pull預設使用變基操作 git config --global pull.rebase true
如果你還是執意喜歡merge,那麼使用下面的命令
// git pull預設使用合併操作 git config --global pull.rebase false
自動變基的問題
自動變基會面臨一個額外的問題:就是如果你本地檔案有更改的話,變基會失敗,因為變基前服務區必須是乾淨的。
有兩種方法解決這個問題
git pull前,先使用git commit暫存程式碼
git pull前,先將使用 git stash將儲存
git commit大家肯定在熟悉不過,這裏簡單介紹下git stash
。
git stash
是一個有用的 Git 命令,它允許你將當前工作目錄中的未提交更改(包括已暫存和未暫存的更改)儲存到一個棧(stash)中,並將工作目錄恢復到乾淨的狀態。這在你需要在多個任務之間切換但又不想提交不完整的程式碼時非常有用
它的用法非常簡單:
假設我們程式碼進行了更改,但沒有完全改好,我們git pull前,可以先執行
git stash
此時,我們修改的程式碼就看不見了。
此時,我們可以使用git pull拉取程式碼,拉取完程式碼,我們使用下面的命令
git stash pop
此時,我們修改的程式碼又可以看見了!
衝突問題
如果使用git pull有衝突,則合併完衝突之後,執行一下 git rebase --continue 就好了,其它和原先的用法沒有任何區別。
總結
本篇文章我們介紹了git pull
的用法,明白了它有merge和rebase兩種模式。預設情況下,它使用的是merge。使用merge的方式拉取程式碼會導致git歷史變得複雜,不利於維護和溯源。
因此,建議使用rebase的方式拉取程式碼。我們只需要做如下設定即可
git config --global pull.rebase true
然後,我們就可以開開心心的使用git pull了!