一臭挽、集中式工作流
有兩個(gè)開(kāi)發(fā)者小明和小紅,看他們是如何開(kāi)發(fā)自己的功能并用git工作流來(lái)協(xié)作的
有人先初始化好中央倉(cāng)庫(kù)
所有人克隆(fork
)中央倉(cāng)庫(kù)
下一步哩都,各個(gè)開(kāi)發(fā)者通過(guò)git clone
命令創(chuàng)建整個(gè)項(xiàng)目的本地拷貝
小明開(kāi)發(fā)功能
在小明的本地倉(cāng)庫(kù)中贱枣,他使用標(biāo)準(zhǔn)的Git過(guò)程開(kāi)發(fā)功能:編輯典徊、暫存(Stage)和提交。
git status # 查看本地倉(cāng)庫(kù)的修改狀態(tài)
git add # 暫存文件
git commit # 提交文件
git diff #查看本地的所有修改
git checkout file/. ##撤銷文件更改
這些命令生成的是本地提交撵术,小明可以按自己需求反復(fù)操作多次背率,而不用擔(dān)心中央倉(cāng)庫(kù)上有了什么操作。
小紅開(kāi)發(fā)功能
與此同時(shí),小紅在自己的本地倉(cāng)庫(kù)中用相同的編輯退渗、暫存和提交過(guò)程開(kāi)發(fā)功能移稳。和小明一樣,她也不關(guān)心中央倉(cāng)庫(kù)有沒(méi)有新提交会油; 當(dāng)然更不關(guān)心小明在他的本地倉(cāng)庫(kù)中的操作个粱,因?yàn)樗斜镜貍}(cāng)庫(kù)都是私有的。
小明發(fā)布功能
一旦小明完成了他的功能開(kāi)發(fā)翻翩,會(huì)發(fā)布他的本地提交到中央倉(cāng)庫(kù)中都许,這樣其它團(tuán)隊(duì)成員可以看到他的修改。他可以用下面的[git push
命令]:
git push origin master
注意嫂冻,origin是在小明克隆倉(cāng)庫(kù)時(shí)Git創(chuàng)建的遠(yuǎn)程中央倉(cāng)庫(kù)別名胶征。master參數(shù)告訴Git推送的分支。 由于中央倉(cāng)庫(kù)自從小明克隆以來(lái)還沒(méi)有被更新過(guò)桨仿,所以push操作不會(huì)有沖突睛低,成功完成。
小紅試著發(fā)布功能
一起來(lái)看看在小明發(fā)布修改后服傍,小紅push修改會(huì)怎么樣钱雷?她使用完全一樣的push
命令:
git push origin master
但她的本地歷史已經(jīng)和中央倉(cāng)庫(kù)有分岐了,Git拒絕操作并給出下面很長(zhǎng)的出錯(cuò)消息:
error: failed to push some refs to '/path/to/repo.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
這避免了小紅覆寫(xiě)正式的提交吹零。她要先pull小明的更新到她的本地倉(cāng)庫(kù)合并上她的本地修改后罩抗,再重試。
小紅在小明的提交之上rebase
小紅用[git pull
]合并上游的修改到自己的倉(cāng)庫(kù)中灿椅。 ——拉取所有上游提交命令到小紅的本地倉(cāng)庫(kù)套蒂,并嘗試和她的本地修改合并:
git pull --rebase origin master
--rebase
選項(xiàng)告訴Git把小紅的提交移到同步了中央倉(cāng)庫(kù)修改后的master分支的頂部,如下圖所示:
如果你忘加了這個(gè)選項(xiàng)茫蛹,pull操作仍然可以完成操刀,但每次pull操作要同步中央倉(cāng)庫(kù)中別人修改時(shí),提交歷史會(huì)以一個(gè)多余的『合并提交』結(jié)尾婴洼。 對(duì)于集中式工作流骨坑,最好是使用rebase而不是生成一個(gè)合并提交。
小紅解決合并沖突
rebase
操作過(guò)程是把本地提交一次一個(gè)地遷移到更新了的中央倉(cāng)庫(kù)master分支之上窃蹋。 這意味著可能要解決在遷移某個(gè)提交時(shí)出現(xiàn)的合并沖突卡啰,而不是解決包含了所有提交的大型合并時(shí)所出現(xiàn)的沖突。 這樣的方式讓你盡可能保持每個(gè)提交的聚焦和項(xiàng)目歷史的整潔警没。反過(guò)來(lái)匈辱,簡(jiǎn)化了哪里引入Bug的分析,如果有必要杀迹,回滾修改也可以做到對(duì)項(xiàng)目影響最小亡脸。
如果小紅和小明的功能是不相關(guān)的,不大可能在rebase過(guò)程中有沖突。如果有浅碾,Git
在合并有沖突的提交處暫停rebase過(guò)程大州,輸出下面的信息并帶上相關(guān)的指令:
CONFLICT (content): Merge conflict in <some-file>
Git很贊的一點(diǎn)是,任何人可以解決他自己的沖突垂谢。在這個(gè)例子中厦画,小紅可以簡(jiǎn)單的運(yùn)行[git status
]命令來(lái)查看哪里有問(wèn)題。 沖突文件列在Unmerged paths
(未合并路徑)一節(jié)中:
Unmerged paths:
(use "git reset HEAD <some-file>..." to unstage)
(use "git add/rm <some-file>..." as appropriate to mark resolution)
both modified: <some-file>
接著小紅編輯這些文件滥朱。修改完成后根暑,用老套路暫存這些文件,并讓[git rebase
]完成剩下的事:
git add <some-file> git rebase --continue
要做的就這些了徙邻。Git會(huì)繼續(xù)一個(gè)一個(gè)地合并后面的提交排嫌,如其它的提交有沖突就重復(fù)這個(gè)過(guò)程。
如果你碰到了沖突缰犁,但發(fā)現(xiàn)搞不定淳地,不要驚慌。只要執(zhí)行下面這條命令帅容,就可以回到你執(zhí)行[git pull --rebase
]命令前的樣子:
git rebase --abort
小紅成功發(fā)布功能
小紅完成和中央倉(cāng)庫(kù)的同步后颇象,就能成功發(fā)布她的修改了:
git push origin master
更多請(qǐng)查看my-git