鍍金池/ 教程/ Java/ 多人協(xié)作
操作標簽
多人協(xié)作
解決沖突
Git 的誕生
工作區(qū)和暫存區(qū)
搭建 Git 服務器
Bug 分支
配置別名
從遠程庫克隆
分支
添加遠程庫
分支管理策略
撤銷修改
安裝 Git
管理修改
生成 SSH key
GitHub
倉庫狀態(tài)
忽略特殊文件
刪除文件
Feature 分支
創(chuàng)建與合并分支
創(chuàng)建版本庫
創(chuàng)建標簽
版本回退
集中式 vs 分布式

多人協(xié)作

當你從遠程倉庫克隆時,實際上 Git 自動把本地的 master 分支和遠程的 master 分支對應起來了,并且,遠程倉庫的默認名稱是 origin。

要查看遠程庫的信息,用git remote

$ git remote
origin

或者,用git remote -v顯示更詳細的信息:

$ git remote -v
origin  git@github.com:michaelliao/learngit.git (fetch)
origin  git@github.com:michaelliao/learngit.git (push)

上面顯示了可以抓取和推送的 origin 的地址。如果沒有推送權限,就看不到 push 的地址。

推送分支

推送分支,就是把該分支上的所有本地提交推送到遠程庫。推送時,要指定本地分支,這樣,Git 就會把該分支推送到遠程庫對應的遠程分支上:

$ git push origin master

如果要推送其他分支,比如 dev,就改成:

$ git push origin dev

但是,并不是一定要把本地分支往遠程推送,那么,哪些分支需要推送,哪些不需要呢?

  • master 分支是主分支,因此要時刻與遠程同步;

  • dev 分支是開發(fā)分支,團隊所有成員都需要在上面工作,所以也需要與遠程同步;

  • bug 分支只用于在本地修復bug,就沒必要推到遠程了,除非老板要看看你每周到底修復了幾個bug;

  • feature 分支是否推到遠程,取決于你是否和你的小伙伴合作在上面開發(fā)。

總之,就是在 Git 中,分支完全可以在本地自己藏著玩,是否推送,視你的心情而定!

http://wiki.jikexueyuan.com/project/git-tutorial/images/git-push-origin.gif" alt="" />

抓取分支

多人協(xié)作時,大家都會往 master 和 dev 分支上推送各自的修改。

現(xiàn)在,模擬一個你的小伙伴,可以在另一臺電腦(注意要把 SSH Key 添加到 GitHub)或者同一臺電腦的另一個目錄下克隆:

$ git clone git@github.com:michaelliao/learngit.git
Cloning into 'learngit'...
remote: Counting objects: 46, done.
remote: Compressing objects: 100% (26/26), done.
remote: Total 46 (delta 16), reused 45 (delta 15)
Receiving objects: 100% (46/46), 15.69 KiB | 6 KiB/s, done.
Resolving deltas: 100% (16/16), done.

當你的小伙伴從遠程庫 clone 時,默認情況下,你的小伙伴只能看到本地的 master 分支。不信可以用git branch命令看看:

$ git branch
* master

現(xiàn)在,你的小伙伴要在 dev 分支上開發(fā),就必須創(chuàng)建遠程 origin 的 dev 分支到本地,于是他用這個命令創(chuàng)建本地 dev 分支:

$ git checkout -b dev origin/dev

現(xiàn)在,他就可以在 dev 上繼續(xù)修改,然后,時不時地把 dev 分支 push 到遠程:

$ git commit -m "add /usr/bin/env"
[dev 291bea8] add /usr/bin/env
 1 file changed, 1 insertion(+)
$ git push origin dev
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 349 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@github.com:michaelliao/learngit.git
   fc38031..291bea8  dev -> dev

http://wiki.jikexueyuan.com/project/git-tutorial/images/git-push-by-xiaohuoban.gif" alt="" />

你的小伙伴已經(jīng)向 origin/dev 分支推送了他的提交,而碰巧你也對同樣的文件作了修改,并試圖推送:

$ git add hello.py 
$ git commit -m "add coding: utf-8"
[dev bd6ae48] add coding: utf-8
 1 file changed, 1 insertion(+)
$ git push origin dev
To git@github.com:michaelliao/learngit.git
 ! [rejected]        dev -> dev (non-fast-forward)
error: failed to push some refs to 'git@github.com:michaelliao/learngit.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.

推送失敗,因為你的小伙伴的最新提交和你試圖推送的提交有沖突,解決辦法也很簡單,Git 已經(jīng)提示我們,先用git pull把最新的提交從 origin/dev 抓下來,然后,在本地合并,解決沖突,再推送:

$ git pull
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 3 (delta 0)
Unpacking objects: 100% (3/3), done.
From github.com:michaelliao/learngit
   fc38031..291bea8  dev        -> origin/dev
There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details

    git pull <remote> <branch>

If you wish to set tracking information for this branch you can do so with:

    git branch --set-upstream dev origin/<branch>

git pull也失敗了,原因是沒有指定本地 dev 分支與遠程 origin/dev 分支的鏈接,根據(jù)提示,設置 dev 和 origin/dev 的鏈接:

$ git branch --set-upstream dev origin/dev
Branch dev set up to track remote branch dev from origin.

再 pull:

$ git pull
Auto-merging hello.py
CONFLICT (content): Merge conflict in hello.py
Automatic merge failed; fix conflicts and then commit the result.

這回git pull成功,但是合并有沖突,需要手動解決,解決的方法和分支管理中的解決沖突完全一樣。解決后,提交,再 push:

$ git commit -m "merge & fix hello.py"
[dev adca45d] merge & fix hello.py
$ git push origin dev
Counting objects: 10, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (6/6), 747 bytes, done.
Total 6 (delta 0), reused 0 (delta 0)
To git@github.com:michaelliao/learngit.git
   291bea8..adca45d  dev -> dev

http://wiki.jikexueyuan.com/project/git-tutorial/images/git-pull-push-fix.gif" alt="" />

因此,多人協(xié)作的工作模式通常是這樣:

  • 首先,可以試圖用git push origin branch-name推送自己的修改;

  • 如果推送失敗,則因為遠程分支比你的本地更新,需要先用git pull試圖合并;

  • 如果合并有沖突,則解決沖突,并在本地提交;

  • 沒有沖突或者解決掉沖突后,再用git push origin branch-name推送就能成功!

如果git pull提示“no tracking information”,則說明本地分支和遠程分支的鏈接關系沒有創(chuàng)建,用命令git branch --set-upstream branch-name origin/branch-name

這就是多人協(xié)作的工作模式,一旦熟悉了,就非常簡單。

小結

  • 查看遠程庫信息,使用git remote -v;

  • 本地新建的分支如果不推送到遠程,對其他人就是不可見的;

  • 從本地推送分支,使用git push origin branch-name,如果推送失敗,先用git pull抓取遠程的新提交;

  • 在本地創(chuàng)建和遠程分支對應的分支,使用git checkout -b branch-name origin/branch-name,本地和遠程分支的名稱最好一致;

  • 建立本地分支和遠程分支的關聯(lián),使用git branch --set-upstream branch-name origin/branch-name;

  • 從遠程抓取分支,使用git pull,如果有沖突,要先處理沖突。
上一篇:生成 SSH key下一篇:添加遠程庫