git 入門教程之協同開發

前面咱們已經介紹過遠程倉庫的相關概念,不過那時並無深刻探討,只是講解了如何建立遠程倉庫以及推送最新工做成果到遠程倉庫,實際上遠程倉庫對於團隊協同開發很重要,不只僅是團隊協同開發的基礎,也是代碼備份的保障手段,如今咱們先簡單回憶下相關概念,以便爲接下來的協同開發作好鋪墊!html

遠程倉庫和遠程分支

遠程倉庫

遠程倉庫其實並不複雜,實際上只是本地電腦上的本地倉庫在另外一臺遠程電腦的備份而已.git

相對本地倉庫來講遠程電腦上的版本庫天然就是遠程倉庫,遠程倉庫使得咱們的版本庫更加安全,畢竟遠程電腦可不是通常的電腦,出錯的機率比咱們平時工做所使用的電腦機率要小得多,這樣一來即便不當心丟失了本地倉庫的所有數據,只要遠程倉庫沒有丟失,那咱們就能夠經過遠程倉庫從新取回最新數據!github

還有一點,遠程倉庫讓代碼社交化,由於你們有了一致途徑來訪問遠程倉庫,團隊也好或者陌生人也罷,只有你願意,他們就能夠獲取遠程倉庫的最新代碼並參與開發,這也是 github 的一大亮點!安全

遠程分支

回顧好遠程倉庫的概念後,咱們再來說一下本地倉庫的遠程分支是什麼意思?app

當前你正在工做的電腦上存儲的是本地倉庫,若是沒有遠程倉庫的支持,只能一我的鼓搗,別人沒法共享你的工做成果,如今加入了團隊開發流程,天然再也不一我的獨自開發,須要和團隊其餘人協同開發,共享開發成果.fetch

因此本地倉庫必然保存着遠程倉庫的基本信息,只有區分好本身的工做成果公共成果,才能不亂套,又能作到信息及時共享.網站

實際上,在項目初期剛剛拷貝遠程倉庫(git clone)時,git 已經默認在本地倉庫建立一個遠程分支(origin/master),本地修改提交首先都是在本地倉庫完成的,好比 git add,git commit 等命令,若是須要發佈你的工做成果,那麼就須要使用 git push origin <branch> 命令推送到遠程倉庫,這裏的 origin 指的就是遠程倉庫名稱(由於最初你們都是先從遠程倉庫克隆下來的,因此遠程倉庫存儲的項目至關於原始項目,故而叫origin).spa

git clone 命令幫助本地倉庫的 master 分支和遠程倉庫的 master 分支創建了關聯,通常稱遠程倉庫名稱爲 origin.code

git-clone.png

查看遠程倉庫信息 : git remotegit remote -v

# 查看遠程倉庫名稱
$ git remote
origin

# 查看遠程倉庫詳情 : 拉取和推送連接
$ git remote -v
origin  git@github.com:snowdreams1006/git-demo.git (fetch)
origin  git@github.com:snowdreams1006/git-demo.git (push)
$

本地分支推送到遠程倉庫 : git push origin <branch>

本地倉庫和遠程倉庫的分支理論上應該一一對應,本地倉庫的主幹分支叫作 master ,而遠程倉庫也有相應的分支叫作 master ,這種映射關係是使用 git clone 命令時默認生成的,也是推薦的作法.htm

通常來講,本地倉庫的分支推送到遠程倉庫指的就是推送到遠程倉庫同名的分支上,例如 git push origin master 意思是: 推將本地倉庫的 master 分支推送到遠程倉庫的 master分支,固然你也能夠推送其餘分支到相應的遠程分支上.

按照以前約定的分支管理策略來講,master 分支用於生產環境部署,dev 分支用於收集開發成果,feature 分支用於開發具體功能分支,既然如此,那這些本地分支哪些須要同步推送到遠程倉庫就比較清晰了!

  • 推送本地 master 分支到遠程倉庫的 master 分支 : git push origin master
  • 推送本地 dev 分支到元層倉庫的 dev 分支 : git push origin dev
# 查看當前分支 : `master` 主分支
$ git branch
  dev
* master
  snow

# 推送本地 `master` 分支到遠程倉庫 `origin` 上相應的 `master` 分支 
$ git push origin master
Counting objects: 15, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (15/15), done.
Writing objects: 100% (15/15), 1.31 KiB | 1.31 MiB/s, done.
Total 15 (delta 9), reused 0 (delta 0)
remote: Resolving deltas: 100% (9/9), completed with 3 local objects.
To github.com:snowdreams1006/git-demo.git
   e60c8ad..dcce09c  master -> master
$

git-branch-remote-github.png

正常來講,本地倉庫的 master 分支應該領先遠程倉庫 origin 上的 master 分支若干個版本.

git-branch-remote-commit.png

一旦咱們已經將本地分支上的工做成果推送到遠程倉庫上相應分支時,本地倉庫和遠程倉庫這時候就保持一致了.

$ git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean
$

git-branch-remote-master.png

遠程倉庫下載到本地分支 : git fetch

遠程倉庫的操做能夠簡單概括爲兩部分: 上傳和下載.

本地倉庫推送到遠程倉庫是上傳,而遠程倉庫拉取到本地倉庫就是下載.

團隊多人協做開發時,你們都會按期或不按期往 masterdev 等分支上推送各自的更改,相應的咱們就須要下載別人的最新工做成果.

如今模擬其餘夥伴正在往 master 分支上推送更改,最好在另外一個電腦另外一個帳戶,固然模擬的話也能夠是同一個電腦下其餘目錄,或者最簡單的方式,直接登陸 github 更改 master 分支上某個文件內容,簡單起見,咱們採用最後一種方式.

其餘夥伴已往遠程倉庫上的 master 分支提交了新的版本: 建立 git-remote.txt 文件

git-branch-remote-new-commit.png

如今咱們想要下載其餘人的最新工做成果,接下來讓咱們看看本地倉庫的 master 還能和遠程倉庫的 master 分支保持一致嗎?

git-branch-remote-fetch.png

# 下載遠程倉庫的 `master` 分支
$ git fetch origin master
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From github.com:snowdreams1006/git-demo
 * branch            master     -> FETCH_HEAD
   dcce09c..10942ff  master     -> origin/master
$

git-branch-remote-fetch-master.png

執行 git fetch 命令後,遠程倉庫上的最新提交記錄已經下載到本地倉庫,同時更新了本地倉庫的遠程分支origin/master ,值得注意的是本地倉庫的 master 分支並無更新!

那你可能會有疑問了,我想要的結果是下載其餘人的最新工做成果,怎麼我本地倉庫的 master 分支並無更新呢?

# 查看工做區
$ ls
LICENSE     README.md   test.txt

# 查看版本庫狀態
$ git status
On branch master
Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded.
  (use "git pull" to update your local branch)

nothing to commit, working tree clean
$

既然 git fetch 並無更新本地倉庫的 master 分支,那它到底作了哪些工做呢?

git fetch 會作的事情

實際上, git fetch 完成了僅有的可是很重要的兩步操做:

  • 從遠程倉庫下載本地倉庫中缺失的提交記錄
  • 更新本地倉庫的遠程分支(好比origin/master)

經過上述兩步操做完成的效果是: 將本地倉庫中的遠程分支更新成了遠程倉庫相應分支最新的狀態.

遠程分支其實是反映了遠程倉庫在你最後一次與它通訊時的狀態,而git fetch 就是你與遠程倉庫通訊的方式了!

git fetch 不會作的事情

git fetch 並不會改變你本地倉庫的狀態,因此也就不會更新你的 master分支,天然也不會修改你磁盤上的文件.

理解這一點很重要,由於許多開發人員誤覺得執行了 git fetch 之後,他們本地倉庫就與遠程倉庫同步了.

實際上它可能已經將進行這一操做所需的全部數據都下載了下來,可是並無修改你本地的文件.

既然本地倉庫的遠程分支已更新,那麼想要更新本地倉庫的 master 分支該如何作呢?很簡單,能夠 git merge 啊!

遠程倉庫更新到本地分支 : git pull

其實經過 git fetch 命令咱們已經下載了遠程倉庫的最新版本,只不過尚未合併到本地倉庫而已,如何合併分支相信你們已經輕車熟路了,有不少方法:

  • git merge origin/master
  • git rebase origin/master
  • git cherry-pick origin/master

實際上,先抓取更新(git fetch)再合併(git merge)這個流程很經常使用,所以 git 是有專門的命令來完成這兩步操做的,這就是拉取更新git pull --- 恰好與推送更新 git push 相反!

# 拉取最新版本
$ git pull
Updating dcce09c..10942ff
Fast-forward
 git-remote.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 git-remote.txt

# 查看版本庫狀態
$ git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

# 查看工做區內容: 文件已更新
$ ls
LICENSE     README.md   git-remote.txt  test.txt
$

git-branch-remote-pull.gif

團隊協做

掌握了遠程倉庫和遠程分支的相關概念後,如今開始真正模擬團隊協做開發了,爲了簡單起見,仍然以直接操做 github 上的 master 分支爲例說明如何協同開發.

(1). 其餘人已往遠程倉庫推送2個版本

git-branch-remote-teamworks.png

(2). 你正在本地倉庫提交1個版本

$ echo "learn teamwork" >> test.txt
$ git commit -am "learn teamwork"
[master f971647] learn teamwork
 1 file changed, 1 insertion(+)
$

git-branch-remote-teamwork-local-commit.png

(3). 你推送到遠程倉庫前先拉取最新版本

# 拉取最新版本,並嘗試合併
$ git pull
remote: Enumerating objects: 8, done.
remote: Counting objects: 100% (8/8), done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 6 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (6/6), done.
From github.com:snowdreams1006/git-demo
   10942ff..612e08a  master     -> origin/master
Merge made by the 'recursive' strategy.
 git-remote.txt | 2 ++
 1 file changed, 2 insertions(+)

# 查看版本庫狀態
$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

# 查看其餘人工做成果
$ cat git-remote.txt
git remote
git clone
git commit -am "fake second teamwork"

# 查看本身即將推送的工做成果
$ cat test.txt
add test.txt
see https://snowdreams1006.github.io/git/usage/remote-repository.html
learn git branch
see https://snowdreams1006.github.io/git/usage/branch-overview.html
git commit c1
git commit c2 and c3
git checkout -b dev
fast forward not recommend
Happy coding
learn git stash
learn git rebase
learn teamwork
$

git-branch-remote-teamwork-pull.png

(4). 你將本地倉庫更改內容推送到遠程倉庫

# 推送到遠程倉庫
$ git push origin master
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 564 bytes | 564.00 KiB/s, done.
Total 5 (delta 3), reused 0 (delta 0)
remote: Resolving deltas: 100% (3/3), completed with 3 local objects.
To github.com:snowdreams1006/git-demo.git
   612e08a..8fe5aba  master -> master
$

如今前往 github 網站確認咱們已經推送成功,咱們的工做成果和其餘人的工做成果同時存在於遠程倉庫中,這樣就完成了一次團隊協同開發的案例.

git-branch-remote-teamwork-myself.png

git-branch-remote-teamwork-push.png

如今簡單回顧一下整個協同開發流程:

  1. 其餘人先於咱們提交2個版本
  2. 咱們本地提交1個版本
  3. 本地版本推送前拉取遠程倉庫
  4. 本地倉庫推送到遠程倉庫

git-branch-remote-teamwork.gif

小結

  • 查看遠程倉庫信息: git remote -v
  • 本地倉庫推送到遠程倉庫: git push origin <branch>
  • 遠程倉庫抓取到本地倉庫: git fetch
  • 遠程倉庫拉取到本地倉庫: git pull 至關於 git fetchgit merge
  • 本地建立和遠程倉庫一致的分支: git checkout -b <branch> origin/<branch>,本地和遠程分支名稱最好一直,好比本地 master 和 遠程 origin/master,本地 dev 和遠程 origin/dev
  • 本地分支和遠程分支創建關聯: git branch --set-upstream <branch> origin/<branch> ,足夠任性的話,本地 dev 能夠關聯遠程 remote-dev 等,不過建議名稱最好一致.
  • 團隊協同開發時,不只平時要按期拉取(git pull),推送到遠程倉庫前更應先拉取(git pull)再推送(git push),如出現衝突,解決衝突後再推送.
相關文章
相關標籤/搜索