說明,為了制圖方便,因此將版本快照用
普通的數字
來表示,實際上不嚴謹,應該像官網用SHA-1
值如92ec2
來表示版本快照更加合適。
現在有兩個人協作開發一個項目,master分支是穩定版,隨時可發布,develop分支是開發版,是平時開發用的分支。
由Peter和Tony負責開發這個項目,兩個人各自完成開發,測試后,push
到服務器就可以下班。
此時在github或者gitlab上的.git
表示的代碼倉庫版本情況如圖
image.png
現在Peter和Tony兩人各自打開git bash輸入
git clone 服務器地址
git clone
指令做了4個事情:
- git自動將整個代碼倉庫包括
.git
文件夾下載下來。 - 自動將服務器的
master
和develop
分支分別修改為origin/master
和origin/develop
,并創建一個master分支指向origin/master
分支指向的分支。 - 并自動執行了
git branch --set-upstream-to master origin/master
來設置本地master
分支跟蹤origin/master
分支。 - 并將
HEAD
指向master,使得工作目錄全部切換到master指向的版本快照-->3
注意:除非執行
git fetch
或者git pull
來更新兩個遠程分支origin/master
和origin/develop
,否則遠程分支將永遠不變,分別指向版本快照3
和5
現在單獨看向Peter的操作:
Peter在執行了git clone 服務器地址
之后,因為要在換到develop分支上開發,而不是在master分支上開發,因此執行如下指令:
//創建一個develop分支指向origin/develop分支指向的版本快照,
//HEAD指向develop分支(即切換到develop分支)。
git checkout -b develop origin/develop
此時Peter可以開始在develop分支上用
git add
和git commit
繼續開發了,現在Peter開發到了一個滿意的階段,經過測試后,打算git push
到遠程分支。Peter開發到了滿意的版本快照<7>的階段
執行
git push origin develop
原本develop指向5,現在將7作為5的下一個結點,并將develop指向7
push成功,因為服務器的版本沒有更新,因此直接push即成功了,現在看向Tony開發的怎么樣了
Tony做的怎么樣了
Tony從5開始,開發到了11
現在Tony也打算將自己的新的開發提交到服務器上去。(我們知道這會失敗,但是來看看發生了什么)
執行
$ git push origin develop
To github.com:這個項目的包名.git
! [rejected] dev -> dev (non-fast-forward)
error: failed to push some refs to 'git@github.com:這個項目的包名.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
英文提示說Tony提交的push被拒絕了,因為Tony的遠程分支origin/develop
落后于服務器的develop
分支。且可以考慮用git pull
來更新合并本地分支。
而git pull
其實是兩個命令git fetch
和git merge
按順序執行。
我們執行
git fetch origin
origin/develop原本指向5,現在和服務器的develop同步,指向7
執行
git merge origin/develop
merge成功后會生成一個新的版本快照,它由11和7合并而來,因此有兩個父結點,此處定義它為12
現在已經同步好了,執行
git push origin develop
12作為7的子節點被添加,并且develop指向12
好了,現在Tony和Peter都完成了提交,改下班了。