出現問題的原因:在github上更新了README.md,沒有更新到本地倉庫。而在本地git倉庫又修改了文件,這時使用 git push origin master 推送到遠程倉庫后就出現了下面的問題:
解決辦法:
使用git pull origin master 命令將遠程倉庫和本地倉庫進行連接。之后可能會出現
Merge branch 'master' of提示問題,編輯不了文字,可直接按 shift+! 進入編輯狀態輸入 wq 后可以了。
產生原因分析
當多人合作開發一個項目時,本地倉庫落后於遠程倉庫是一個非常正常的事情,可參考下圖。
1 A-B-C(master) 2 \ 3 D(origin/master)
具體情境如下:
- 我當前拉取的遠端版本為
B
,此時修改了代碼,並在本地倉庫 commit 一次,但並未 push 到遠端倉庫。 - 另一位開發者在
B
的基礎上,同樣 commit 了一次並 push 到遠端倉庫。那么這個時候,我再 push 自己的代碼就會發生錯誤,如下。
這個時候我們會選擇,先 pull,再 push。Ok,push 成功,但是此時我們查看 log 就會發現除了我們自己提交的那條日志之外,會多出一條 "Merge branch 'master' of ..."。
那么,為什么會出現這種現象呢?其實是與 Git 的工作原理有關,對 Git 比較了解的人應該會知道,無論是 pull
、push
亦或是 merge
操作,其實背后都是有很多的不同的模式的。
在進行 pull 操作的同時,其實就是 fetch+merge 的一個過程。我們從 remote 分支中拉取新的更新,然后再合並到本地分支中去。
- 如果 remote 分支超前於本地分支,並且本地分支沒有任何 commit 的,直接從 remote 進行 pull 操作,默認會采用
fast-forward
模式,這種模式下,並不會產生合並節點,也就是說不會產生多余的那條 log 信息 - 如果想之前那樣,本地先 commit 后再去 pull,那么此時,remote 分支和本地會分支會出現分叉,這個時候使用 pull 操作拉取更新時,就會進行分支合並,產生合並節點和 log 信息。這兩種狀態分別如下圖所示:
1 # fast-forword 2 A-B-D(origin/master) 3 \ 4 C'(master) 5 6 # merge 7 A-B-C-E(master) 8 \ / 9 D(origin/master)
如何避免
為了去除自動生成的 log 信息,有以下幾種解決方案:
- 如果你使用的是 Git Bash,直接使用
git pull --rebase
。如果拉取不產生沖突,會直接 rebase,不會產生分支合並操作,如果有沖突則需要手動 fix 后,自行合並。 - 如果使用的是 GUI,例如 TortoiseGit,可以先 fetch,再手動 rebase 就可以了。
關於 rebase 和 merge
關於什么時候使用 rebase,什么時候使用 merge,開發者總結了幾條規則:
- 從 remote 分支拉取更新到本地時,使用 rebase。
- 當完成 bug 修復或新功能時,使用 merge 將子分支合並到主分支。
- 沒有人應該 rebase 一根共享的分支。