Git 私有的小型團隊

私有的小型團隊

我們從最簡單的情況開始,一個私有項目,與你一起協作的還有另外一到兩位開發者。這裏說私有,是指源代碼不公開,其他人無法訪問項目倉庫。而你和其他開發者則都具有推送數據到倉庫的權限。

這種情況下,你們可以用 Subversion 或其他集中式版本控制系統類似的工作流來協作。你仍然可以得到 Git 帶來的其他好處:離線提交,快速分支與合併等等,但工作流程還是差不多的。主要區別在於,合併操作發生在客戶端而非服務器上。讓我們來看看,兩個開發者一起使用同一個共享倉庫,會發生些什麼。第一個人,John,克隆了倉庫,作了些更新,在本地提交。(下面的例子中省略了常規提示,用 ... 代替以節約版面。)

# John's Machine
    $ git clone john@githost:simplegit.git
    Initialized empty Git repository in /home/john/simplegit/.git/
    ...
    $ cd simplegit/
    $ vim lib/simplegit.rb
    $ git commit -am 'removed invalid default value'
    [master 738ee87] removed invalid default value
    1 files changed, 1 insertions(+), 1 deletions(-)

第二個開發者,Jessica,一樣這麼做:克隆倉庫,提交更新:

# Jessica's Machine
    $ git clone jessica@githost:simplegit.git
    Initialized empty Git repository in /home/jessica/simplegit/.git/
    ...
    $ cd simplegit/
    $ vim TODO
    $ git commit -am 'add reset task'
    [master fbff5bc] add reset task
    1 files changed, 1 insertions(+), 0 deletions(-)

現在,Jessica 將她的工作推送到服務器上:

# Jessica's Machine
    $ git push origin master
    ...
    To jessica@githost:simplegit.git
    1edee6b..fbff5bc master -> master

John 也嘗試推送自己的工作上去:

# John's Machine
    $ git push origin master
    To john@githost:simplegit.git
    ! [rejected] master -> master (non-fast forward)
    error: failed to push some refs to 'john@githost:simplegit.git'

John 的推送操作被駁回,因爲 Jessica 已經推送了新的數據上去。請注意,特別是你用慣了 Subversion 的話,這裏其實修改的是兩個文件,而不是同一個文件的同一個地方。Subversion 會在服務器端自動合併提交上來的更新,而 Git 則必須先在本地合併後才能推送。於是,John 不得不先把 Jessica 的更新拉下來:

$ git fetch origin
    ...
    From john@githost:simplegit
    + 049d078...fbff5bc master -> origin/master

此刻,John 的本地倉庫如圖 5-4 所示:


圖 5-4. John 的倉庫歷史

雖然 John 下載了 Jessica 推送到服務器的最近更新(fbff5),但目前只是 origin/master 指針指向它,而當前的本地分支 master 仍然指向自己的更新(738ee),所以需要先把她的提交合並過來,才能繼續推送數據:

$ git merge origin/master
    Merge made by recursive.
    TODO | 1 +
    1 files changed, 1 insertions(+), 0 deletions(-)

還好,合併過程非常順利,沒有衝突,現在 John 的提交歷史如圖 5-5 所示:


圖 5-5. 合併 origin/master 後 John 的倉庫歷史

現在,John 應該再測試一下代碼是否仍然正常工作,然後將合併結果(72bbc)推送到服務器上:

$ git push origin master
    ...
    To john@githost:simplegit.git
    fbff5bc..72bbc59 master -> master

最終,John 的提交歷史變爲圖 5-6 所示:


圖 5-6. 推送後 John 的倉庫歷史

而在這段時間,Jessica 已經開始在另一個特性分支工作了。她創建了 issue54 並提交了三次更新。她還沒有下載 John 提交的合併結果,所以提交歷史如圖 5-7 所示:


圖 5-7. Jessica 的提交歷史

Jessica 想要先和服務器上的數據同步,所以先下載數據:

# Jessica's Machine
    $ git fetch origin
    ...
    From jessica@githost:simplegit
    fbff5bc..72bbc59 master -> origin/master

於是 Jessica 的本地倉庫歷史多出了 John 的兩次提交(738ee 和 72bbc),如圖 5-8 所示:


圖 5-8. 獲取 John 的更新之後 Jessica 的提交歷史

此時,Jessica 在特性分支上的工作已經完成,但她想在推送數據之前,先確認下要並進來的數據究竟是什麼,於是運行 git log 查看:

$ git log --no-merges origin/master ^issue54
    commit 738ee872852dfaa9d6634e0dea7a324040193016
    Author: John Smith <jsmith@example.com>
    Date: Fri May 29 16:01:27 2009 -0700

    removed invalid default value

現在,Jessica 可以將特性分支上的工作併到 master 分支,然後再併入 John 的工作(origin/master)到自己的 master 分支,最後再推送回服務器。當然,得先切回主分支才能集成所有數據:

$ git checkout master
    Switched to branch "master"
    Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded.

要合併 origin/master 或 issue54 分支,誰先誰後都沒有關係,因爲它們都在上游(upstream)(譯註:想像分叉的更新像是匯流成河的源頭,所以上游 upstream 是指最新的提交),所以無所謂先後順序,最終合併後的內容快照都是一樣的,而僅是提交歷史看起來會有些先後差別。Jessica 選擇先合併 issue54

$ git merge issue54
    Updating fbff5bc..4af4298
    Fast forward
    README | 1 +
    lib/simplegit.rb | 6 +++++-
    2 files changed, 6 insertions(+), 1 deletions(-)

正如所見,沒有衝突發生,僅是一次簡單快進。現在 Jessica 開始合併 John 的工作(origin/master):

$ git merge origin/master
    Auto-merging lib/simplegit.rb
    Merge made by recursive.
    lib/simplegit.rb | 2 +-
    1 files changed, 1 insertions(+), 1 deletions(-)

所有的合併都非常乾淨。現在 Jessica 的提交歷史如圖 5-9 所示:


圖 5-9. 合併 John 的更新後 Jessica 的提交歷史

現在 Jessica 已經可以在自己的 master 分支中訪問 origin/master 的最新改動了,所以她應該可以成功推送最後的合併結果到服務器上(假設 John 此時沒再推送新數據上來):

$ git push origin master
    ...
    To jessica@githost:simplegit.git
    72bbc59..8059c15 master -> master

至此,每個開發者都提交了若干次,且成功合併了對方的工作成果,最新的提交歷史如圖 5-10 所示:


圖 5-10. Jessica 推送數據後的提交歷史

以上就是最簡單的協作方式之一:先在自己的特性分支中工作一段時間,完成後合併到自己的 master 分支;然後下載合併 origin/master 上的更新(如果有的話),再推回遠程服務器。一般的協作流程如圖 5-11 所示:


圖 5-11. 多用戶共享倉庫協作方式的一般工作流程時序



git 在線學習地址:http://git.oschina.net/progit/5-%E5%88%86%E5%B8%83%E5%BC%8F-Git.html#5.2-%E4%B8%BA%E9%A1%B9%E7%9B%AE%E4%BD%9C%E8%B4%A1%E7%8C%AE

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章