Forking 工作流

學習完整課程請移步 互聯網 Java 全棧工程師

Forking 工作流和前面討論的幾種工作流有根本的不同。這種工作流不是使用單個服務端倉庫作為『中央』代碼基線,而讓各個開發者都有一個服務端倉庫。這意味著各個代碼貢獻者有 2 個 Git 倉庫而不是 1 個:一個本地私有的,另一個服務端公開的。

Forking 工作流的一個主要優勢是,貢獻的代碼可以被集成,而不需要所有人都能 push 代碼到僅有的中央倉庫中。開發者 push 到自己的服務端倉庫,而只有項目維護者才能 push 到正式倉庫。這樣項目維護者可以接受任何開發者的提交,但無需給他正式代碼庫的寫權限。

效果就是一個分布式的工作流,能為大型、自發性的團隊(包括了不受信的第三方)提供靈活的方式來安全的協作。也讓這個工作流成為開源項目的理想工作流。

工作方式

和其它的 Git 工作流一樣,Forking 工作流要先有一個公開的正式倉庫存儲在服務器上。但一個新的開發者想要在項目上工作時,不是直接從正式倉庫克隆,而是 fork 正式項目在服務器上創建一個拷貝。

這個倉庫拷貝作為他個人公開倉庫 —— 其它開發者不允許 push 到這個倉庫,但可以 pull 到修改(后面我們很快就會看這點很重要)。在創建了自己服務端拷貝之后,和之前的工作流一樣,開發者執行 git clone 命令克隆倉庫到本地機器上,作為私有的開發環境。

要提交本地修改時,push 提交到自己公開倉庫中 —— 而不是正式倉庫中。然后,給正式倉庫發起一個 pull request,讓項目維護者知道有更新已經準備好可以集成了。對于貢獻的代碼,pull request 也可以很方便地作為一個討論的地方。

為了集成功能到正式代碼庫,維護者 pull 貢獻者的變更到自己的本地倉庫中,檢查變更以確保不會讓項目出錯,合并變更到自己本地的 master 分支,然后 push master 分支到服務器的正式倉庫中。到此,貢獻的提交成為了項目的一部分,其它的開發者應該執行 pull 操作與正式倉庫同步自己本地倉庫。

正式倉庫

在 Forking 工作流中,『官方』倉庫的叫法只是一個約定,理解這點很重要。從技術上來看,各個開發者倉庫和正式倉庫在Git看來沒有任何區別。事實上,讓正式倉庫之所以正式的唯一原因是它是項目維護者的公開倉庫。

Forking 工作流的分支使用方式

所有的個人公開倉庫實際上只是為了方便和其它的開發者共享分支。各個開發者應該用分支隔離各個功能,就像在功能分支工作流和 GitFlow 工作流一樣。唯一的區別是這些分支被共享了。在 Forking 工作流中這些分支會被 pull 到另一個開發者的本地倉庫中,而在功能分支工作流和 GitFlow 工作流中是直接被 push 到正式倉庫中。

示例

項目維護者初始化正式倉庫

和任何使用 Git 項目一樣,第一步是創建在服務器上一個正式倉庫,讓所有團隊成員都可以訪問到。通常這個倉庫也會作為項目維護者的公開倉庫。

公開倉庫應該是裸倉庫,不管是不是正式代碼庫。所以項目維護者會運行像下面的命令來搭建正式倉庫:

ssh user@host
git init --bare /path/to/repo.git

Bitbucket 和 Stash 提供了一個方便的 GUI 客戶端以完成上面命令行做的事。這個搭建中央倉庫的過程和前面提到的工作流完全一樣。如果有現存的代碼庫,維護者也要 push 到這個倉庫中。

開發者 fork 正式倉庫

其它所有的開發需要 fork 正式倉庫。可以用 git clone 命令用 SSH 協議連通到服務器,拷貝倉庫到服務器另一個位置 —— 是的,fork 操作基本上就只是一個服務端的克隆。Bitbucket 和 Stash 上可以點一下按鈕就讓開發者完成倉庫的 fork 操作。

這一步完成后,每個開發都在服務端有一個自己的倉庫。和正式倉庫一樣,這些倉庫應該是裸倉庫。

開發者克隆自己 fork 出來的倉庫

下一步,各個開發者要克隆自己的公開倉庫,用熟悉的 git clone 命令。

在這個示例中,假定用 Bitbucket 托管了倉庫。記住,如果這樣的話各個開發者需要有各自的 Bitbucket 賬號,使用下面命令克隆服務端自己的倉庫:

git clone https://user@bitbucket.org/user/repo.git

相比前面介紹的工作流只用了一個 origin 遠程別名指向中央倉庫,Forking 工作流需要 2 個遠程別名 —— 一個指向正式倉庫,另一個指向開發者自己的服務端倉庫。別名的名字可以任意命名,常見的約定是使用 origin 作為遠程克隆的倉庫的別名(這個別名會在運行 git clone 自動創建),upstream(上游)作為正式倉庫的別名。

git remote add upstream https://bitbucket.org/maintainer/repo

需要自己用上面的命令創建 upstream 別名。這樣可以簡單地保持本地倉庫和正式倉庫的同步更新。注意,如果上游倉庫需要認證(比如不是開源的),你需要提供用戶:

git remote add upstream https://user@bitbucket.org/maintainer/repo.git

這時在克隆和 pull 正式倉庫時,需要提供用戶的密碼。

開發者開發自己的功能

在剛克隆的本地倉庫中,開發者可以像其它工作流一樣的編輯代碼、提交修改和新建分支:

git checkout -b some-feature
// Edit some code
git commit -a -m "Add first draft of some feature"

所有的修改都是私有的直到 push 到自己公開倉庫中。如果正式項目已經往前走了,可以用 git pull 命令獲得新的提交:

git pull upstream master

由于開發者應該都在專門的功能分支上工作,pull 操作結果會都是快進合并。

開發者發布自己的功能

一旦開發者準備好了分享新功能,需要做二件事。首先,通過push他的貢獻代碼到自己的公開倉庫中,讓其它的開發者都可以訪問到。他的 origin 遠程別名應該已經有了,所以要做的就是:

git push origin feature-branch

這里和之前的工作流的差異是,origin 遠程別名指向開發者自己的服務端倉庫,而不是正式倉庫。

第二件事,開發者要通知項目維護者,想要合并他的新功能到正式庫中。Bitbucket 和 Stash 提供了 Pull Request 按鈕,彈出表單讓你指定哪個分支要合并到正式倉庫。一般你會想集成你的功能分支到上游遠程倉庫的 master 分支中。

項目維護者集成開發者的功能

當項目維護者收到 pull request,他要做的是決定是否集成它到正式代碼庫中。有二種方式來做:

  • 直接在 pull request 中查看代碼
  • pull 代碼到他自己的本地倉庫,再手動合并

第一種做法更簡單,維護者可以在 GUI 中查看變更的差異,做評注和執行合并。但如果出現了合并沖突,需要第二種做法來解決。這種情況下,維護者需要從開發者的服務端倉庫中 fetch 功能分支,合并到他本地的 master 分支,解決沖突:

git fetch https://bitbucket.org/user/repo feature-branch
// 查看變更
git checkout master
git merge FETCH_HEAD

變更集成到本地的 master 分支后,維護者要 push 變更到服務器上的正式倉庫,這樣其它的開發者都能訪問到:

git push origin master

注意,維護者的 origin 是指向他自己公開倉庫的,即是項目的正式代碼庫。到此,開發者的貢獻完全集成到了項目中

開發者和正式倉庫做同步

由于正式代碼庫往前走了,其它的開發需要和正式倉庫做同步:

git pull upstream master

總結

如果你之前是使用 SVN,Forking 工作流可能看起來像是一個激進的范式切換(paradigm shift)。但不要害怕,這個工作流實際上就是在功能分支工作流之上引入另一個抽象層。不是直接通過單個中央倉庫來分享分支,而是把貢獻代碼發布到開發者自己的服務端倉庫中。

示例中解釋了,一個貢獻如何從一個開發者流到正式的 master 分支中,但同樣的方法可以把貢獻集成到任一個倉庫中。比如,如果團隊的幾個人協作實現一個功能,可以在開發之間用相同的方法分享變更,完全不涉及正式倉庫。

這使得 Forking 工作流對于松散組織的團隊來說是個非常強大的工具。任一開發者可以方便地和另一開發者分享變更,任何分支都能有效地合并到正式代碼庫中。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 多種多樣的工作流使得在項目中實施Git時變得難以選擇。這份教程提供了一個出發點,調查企業團隊最常見的Git工作流。...
    JSErik閱讀 4,483評論 2 8
  • 這里用github作演示,一般公司內部都有用自己搭建的項目管理平臺,比如gitlab等,不管是哪種管理平臺,功能上...
    一顆老鼠屎閱讀 1,269評論 0 3
  • 今天偶然遇到VS2015打開某個工程文件卡死,一直等待無響應; 關閉VS,打開另外一個工程文件是正常的; 開始懷疑...
    小瀅閱讀 1,805評論 0 0
  • 第六章:想象力 綜合型想象力和創造型想象力,包括訓練想象力和對想象力的運用,相信并訓練自己的想象力,為自己的夢想勾...
    殷藝芳閱讀 131評論 0 0
  • 《冰忠融化,細落三親情》 靜物素描系列 圓珠筆畫系列 耗時:2.5個小時 尺寸:A4紙 工具:一只圓珠筆 2017...
    春城怡景閱讀 320評論 3 9