1.操作步驟需要嚴格執行如下順序:commit->pull->push
2.commit:將代碼提交到本地倉庫。
3.pull:將遠程倉庫代碼同步到本地倉庫。如遇沖突,解決沖突,重復commit->pull,直到沒有沖突。
4.push:將本地倉庫代碼提交到遠程倉庫。
具體討論如下:
-
本地和遠程的關系相當於兩個分支,你感覺一樣是因為你
git pull
的時候已經自動給綁定好對應關系了, set-upstream..balbala -
你遠程新建了一個分支拉到本地的道理是一樣的,屬於復制了一份,但是本地分支和遠程分支已經是兩個東西了
-
本地分支屬於本地倉庫里,是包含關系,一個倉庫里可以有很多分支, 如果是 tag 的話可以分離出獨立的倉庫
-
肯定不會全量推送到遠程的,是通過對比 commit 的記錄,如果本地高於遠程就直接把多出來的
commit
給懟上去,如果本地的這幾個commit
和遠程的commit
有沖突的部分就merge
,然后根據提交時間排序再新建一個merge 的 commit 記錄再懟上去 -
這個先 commit 再 pull 再 push 的情況就是為了應對多人合並開發的情況,
-
commit
是為了告訴 git 我這次提交改了哪些東西,不然你只是改了但是 git 不知道你改了,也就無從判斷比較; -
pull
是為了本地 commit 和遠程commit 的對比記錄,git 是按照文件的行數操作進行對比的,如果同時操作了某文件的同一行那么就會產生沖突,git 也會把這個沖突給標記出來,這個時候就需要先把和你沖突的那個人拉過來問問保留誰的代碼,然后在git add && git commit && git pull
這三連,再次 pull 一次是為了防止再你們協商的時候另一個人給又提交了一版東西,如果真發生了那流程重復一遍,通常沒有沖突的時候就直接給你合並了,不會把你的代碼給覆蓋掉 -
出現代碼覆蓋或者丟失的情況:比如A B兩人的代碼pull 時候的版本都是1,A在本地提交了2,3並且推送到遠程了,B 進行修改的時候沒有
commit
操作,他先自己寫了東西,然后git pull
這個時候 B 本地版本已經到3了,B 在本地版本3的時候改了 A 寫過的代碼,再進行了git commit && git push
那么在遠程版本中就是4,而且 A 的代碼被覆蓋了,所以說所有人都要先 commit 再 pull,不然真的會覆蓋代碼的
-
-
兩個互相合並的唯一區別就是 A->B 的時候 B 分支上會產生一個 merge_commit 的信息,這個時候 B 是合並狀態而 A 未合並狀態,如果現在沒有發生任何改動執行 B->A 就直接切換過去了,連 merge_commit 都不會生成了
比如你從一個git log
為1,2,3,4,5,6
的遠程庫拉取到了本地,
另一個同事也拉取了同樣的代碼,而且你的同事先於你提交到遠程了,
此時遠程的版本是1,2,3,4,5,6,7_new,8_new
,
而你當前只是本地的版本1,2,3,4,5,6,7_local,8_local,9_local
從這里你就能看出你前一部分和遠程的一樣,后一部分和遠程的不一樣,
這個時候你不能正常推送上去的,如果你采取git push origin master --force
那么遠程的版本就變成了1,2,3,4,5,6,7_local,8_local,9_local
之前你同事推送的7_new,8_new
這兩次推送被覆蓋了,這不是大家想要的情況
因此需要git pull
來將本地的版本合並成這樣1,2,3,4,5,6,7_new,7_local,8_local,8_new,9_local,10_commit_merge
遠程和本地的排序是按當時 commit 的時間來排的,最后一個10_commit_merge
就是你本地和遠程合並的標志,最后你推送到遠程倉庫的應該也是這個,
因為你們操作的是同一個庫始終要保持代碼的同步,所以一旦版本庫發生改動同一分支下的所有人都要跟着去同步他,因為各開發各的直接往上推 git 還沒智能到幫你處理沖突的地步