Git push 時如何避免出現 "Merge branch 'master' of ..."

在使用 Git 的進行代碼版本控制的時候,每每會發如今 log 中出現 "Merge branch 'master' of ..." 這句話,以下圖所示。日誌中記錄的通常爲開發過程當中對代碼的改動信息,若是出現過多例如上述描述的信息會形成日誌的污染。git

閱讀了一些外文的博客,下面就來一探究竟。github

產生緣由分析

當多人合做開發一個項目時,本地倉庫落後於遠程倉庫是一個很是正常的事情,可參考下圖。fetch

A-B-C(master)
    \
     D(origin/master)

具體情境以下:url

  1. 我當前拉取的遠端版本爲 B,此時修改了代碼,並在本地倉庫 commit 一次,但並未 push 到遠端倉庫。
  2. 另外一位開發者在 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 比較瞭解的人應該會知道,不管是 pullpush 亦或是 merge 操做,其實背後都是有不少的不一樣的模式的。日誌

在進行 pull 操做的同時,其實就是 fetch+merge 的一個過程。咱們從 remote 分支中拉取新的更新,而後再合併到本地分支中去。code

  1. 若是 remote 分支超前於本地分支,而且本地分支沒有任何 commit 的,直接從 remote 進行 pull 操做,默認會採用 fast-forward 模式,這種模式下,並不會產生合併節點,也就是說不會產生多餘的那條 log 信息
  2. 若是想以前那樣,本地先 commit 後再去 pull,那麼此時,remote 分支和本地會分支會出現分叉,這個時候使用 pull 操做拉取更新時,就會進行分支合併,產生合併節點和 log 信息。這兩種狀態分別以下圖所示:
# fast-forword 
A-B-D(origin/master)
     \
      C'(master)

# merge
A-B-C-E(master)
   \ /
    D(origin/master)

如何避免

爲了去除自動生成的 log 信息,有如下幾種解決方案:blog

  1. 若是你使用的是 Git Bash,直接使用 git pull --rebase。若是拉取不產生衝突,會直接 rebase,不會產生分支合併操做,若是有衝突則須要手動 fix 後,自行合併。
  2. 若是使用的是 GUI,例如 TortoiseGit,能夠先 fetch,再手動 rebase 就能夠了。

關於 rebase 和 merge

關於何時使用 rebase,何時使用 merge,開發者總結了幾條規則:開發

  • 從 remote 分支拉取更新到本地時,使用 rebase。
  • 當完成 bug 修復或新功能時,使用 merge 將子分支合併到主分支。
  • 沒有人應該 rebase 一根共享的分支。

有關這二者具體的操做,能夠參考我在文章最後列出的博客。rem

References

相關文章
相關標籤/搜索