在使用 Git 的進行代碼版本控制的時候,每每會發如今 log 中出現 "Merge branch 'master' of ..." 這句話,以下圖所示。日誌中記錄的通常爲開發過程當中對代碼的改動信息,若是出現過多例如上述描述的信息會形成日誌的污染。git
閱讀了一些外文的博客,下面就來一探究竟。github
當多人合做開發一個項目時,本地倉庫落後於遠程倉庫是一個很是正常的事情,可參考下圖。fetch
A-B-C(master) \ D(origin/master)
具體情境以下:url
B
,此時修改了代碼,並在本地倉庫 commit 一次,但並未 push 到遠端倉庫。B
的基礎上,一樣 commit 了一次並 push 到遠端倉庫。那麼這個時候,我再 push 本身的代碼就會發生錯誤,以下。To github.com:maoqyhz/usegit.git ! [rejected] master -> master (fetch first) error: failed to push some refs to 'git@github.com:maoqyhz/usegit.git' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., 'git pull ...') before pushing again.
這個時候咱們會選擇,先 pull,再 push。Ok,push 成功,可是此時咱們查看 log 就會發現除了咱們本身提交的那條日誌以外,會多出一條 "Merge branch 'master' of ..."。版本控制
那麼,爲何會出現這種現象呢?實際上是與 Git 的工做原理有關,對 Git 比較瞭解的人應該會知道,不管是 pull
、push
亦或是 merge
操做,其實背後都是有不少的不一樣的模式的。日誌
在進行 pull 操做的同時,其實就是 fetch+merge 的一個過程。咱們從 remote 分支中拉取新的更新,而後再合併到本地分支中去。code
fast-forward
模式,這種模式下,並不會產生合併節點,也就是說不會產生多餘的那條 log 信息# fast-forword A-B-D(origin/master) \ C'(master) # merge A-B-C-E(master) \ / D(origin/master)
爲了去除自動生成的 log 信息,有如下幾種解決方案:blog
git pull --rebase
。若是拉取不產生衝突,會直接 rebase,不會產生分支合併操做,若是有衝突則須要手動 fix 後,自行合併。關於何時使用 rebase,何時使用 merge,開發者總結了幾條規則:開發
- 從 remote 分支拉取更新到本地時,使用 rebase。
- 當完成 bug 修復或新功能時,使用 merge 將子分支合併到主分支。
- 沒有人應該 rebase 一根共享的分支。
有關這二者具體的操做,能夠參考我在文章最後列出的博客。rem