From b6929d04b6c108219333e6fba0e0d2be7f85c8a7 Mon Sep 17 00:00:00 2001 From: Jerry Lee Date: Sun, 31 Aug 2014 22:30:11 +0800 Subject: [PATCH] revise workflow-forking --- git-workflows-and-tutorials/README.md | 7 +- .../images/git-workflows-forking-3.png | Bin 0 -> 7692 bytes .../workflow-forking.md | 82 ++++++++++-------- 3 files changed, 50 insertions(+), 39 deletions(-) create mode 100644 git-workflows-and-tutorials/images/git-workflows-forking-3.png diff --git a/git-workflows-and-tutorials/README.md b/git-workflows-and-tutorials/README.md index f21142e..0b9023b 100644 --- a/git-workflows-and-tutorials/README.md +++ b/git-workflows-and-tutorials/README.md @@ -8,13 +8,12 @@ 行文中实践原则和操作示例并重,对于`Git`的资深玩家可以梳理思考提升,而新接触的同学,也可以跟着step-by-step操作来操练学习并在实际工作中上手使用。 -对于`Git`工作流主题,目前网上资料很少,多是零散地操作说明,希望这篇文章能让你更深入理解并在工作中灵活有效地使用起来。 - -PS: +对于`Git`工作流主题,目前网上资料不多,并且主要是零散的操作说明,希望这篇文章能让你更深入理解并在工作中灵活有效地使用起来。 +PS: 文中`Pull Request`的介绍用的是`Bitbucket`代码托管服务,由于和`GitHub`基本一样,如果你用的是`GitHub`(我自己也主要使用`GitHub`托管代码),不影响理解和操作。 -[自己](http://weibo.com/oldratlee)理解粗浅,翻译不合适和不对的地方,欢迎建议([提交Issue](https://github.com/quickhack/translations/issues))和指正([Fork后提交代码](https://github.com/quickhack/translations/fork))! +[自己](http://weibo.com/oldratlee)理解粗浅,翻译中不足和不对之处,欢迎建议([提交Issue](https://github.com/quickhack/translations/issues))和指正([Fork后提交代码](https://github.com/quickhack/translations/fork))! `Git`工作流指南 ====================== diff --git a/git-workflows-and-tutorials/images/git-workflows-forking-3.png b/git-workflows-and-tutorials/images/git-workflows-forking-3.png new file mode 100644 index 0000000000000000000000000000000000000000..94e308bf9423d3fa6cf6d6d627404c2d95e0c225 GIT binary patch literal 7692 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 A>;M1& literal 0 HcmV?d00001 diff --git a/git-workflows-and-tutorials/workflow-forking.md b/git-workflows-and-tutorials/workflow-forking.md index 3aa3ea7..880aecd 100644 --- a/git-workflows-and-tutorials/workflow-forking.md +++ b/git-workflows-and-tutorials/workflow-forking.md @@ -3,26 +3,26 @@ `Forking`工作流和前面讨论的几种工作流有根本的不同。 这种工作流不是使用单个服务端仓库作为『中央』代码基线,而让各个开发者都有一个服务端仓库。 -这意味着各个代码贡献者不只有一个而2个`Git`仓库:一个本地私有的,另一个服务端公有的。 +这意味着各个代码贡献者有2个`Git`仓库而不是1个:一个本地私有的,另一个服务端公有的。 ![](images/git-workflows-forking.png) -`Forking`工作流的一个主要优势是,贡献的代码可以被集成,而不需要所有人都`push`代码到仅有的中央仓库中。 +`Forking`工作流的一个主要优势是,贡献的代码可以被集成,而不需要所有人都能`push`代码到仅有的中央仓库中。 开发者`push`到自己的服务端仓库,而只有项目维护者才能`push`到正式仓库。 这样项目维护者可以接受任何开发者的提交,但无需给他正式代码库的写权限。 -效果就是一个发布式的工作流,为大型、自发性的团队(包括了不受信的第三方)提供了灵活的方式来安全的协作。 +效果就是一个分布式的工作流,能为大型、自发性的团队(包括了不受信的第三方)提供灵活的方式来安全的协作。 也让这个工作流成为开源项目的理想工作流。 :beer: 工作方式 --------------------- 和其它的`Git`工作流一样,`Forking`工作流要先有一个公有的正式仓库存储在服务器上。 -但一个新的开发者想要在项目上工作时,不是直接从正式仓库克隆。 +但一个新的开发者想要在项目上工作时,不是直接从正式仓库克隆,而是`fork`正式项目在服务器上创建一个拷贝。 -而是`fork`正式项目在服务器上创建一个拷贝。这个仓库拷贝作为他个人公开仓库 —— -其它开发者不允许`push`到这个仓库,但可以`pull`到修改(后面我们很快就会看这点是很重要的)。 -在创建了自己服务端拷贝之后,开发者执行`git clone`命令克隆仓库到本地机器上,作为私有的开发环境,和之前的工作流一样。 +这个仓库拷贝作为他个人公开仓库 —— +其它开发者不允许`push`到这个仓库,但可以`pull`到修改(后面我们很快就会看这点很重要)。 +在创建了自己服务端拷贝之后,和之前的工作流一样,开发者执行[`git clone`命令](https://www.atlassian.com/git/tutorial/git-basics#!clone)克隆仓库到本地机器上,作为私有的开发环境。 要提交本地修改时,`push`提交到自己公有仓库中 —— 而不是正式仓库中。 然后,给正式仓库发起一个`pull request`,让项目维护者知道有更新已经准备好可以集成了。 @@ -30,19 +30,20 @@ 为了集成功能到正式代码库,维护者`pull`贡献者的变更到自己的本地仓库中,检查变更以确保不会让项目出错, [合并变更到自己本地的`master`分支](https://www.atlassian.com/git/tutorial/git-branches#!merge), -然后`push`到服务器的`master`分支上。 +然后[`push`](https://www.atlassian.com/git/tutorial/remote-repositories#!push)`master`分支到服务器的正式仓库中。 到此,贡献的提交成为了项目的一部分,其它的开发者应该执行`pull`操作与正式仓库同步自己本地仓库。 ### 正式仓库 在`Forking`工作流中,『官方』仓库的叫法只是一个约定,理解这点很重要。 -在技术观点上,各个开发者仓库和正式仓库在`Git`看来没有任何区别。 -事实上,让正式仓库之所以正式是是看公开仓库的维护者是谁。 +从技术上来看,各个开发者仓库和正式仓库在`Git`看来没有任何区别。 +事实上,让正式仓库之所以正式的唯一原因是它是项目维护者的公开仓库。 ### `Forking`工作流的分支使用方式 -所有的个人分开仓库实际上只是为了方便和其它的开发者共享分支。各个开发者应该用分支隔离各个功能,就像在[功能分支工作流](workflow-feature-branch.md) -和 [`Gitflow`工作流](workflow-forking.md)一样。唯一的区别是这些分支被共享了,而功能分支工作流和`Gitflow`工作流是直接`push`到正式仓库中。 +所有的个人公开仓库实际上只是为了方便和其它的开发者共享分支。 +各个开发者应该用分支隔离各个功能,就像在[功能分支工作流](workflow-feature-branch.md)和[`Gitflow`工作流](workflow-forking.md)一样。 +唯一的区别是这些分支被共享了。在`Forking`工作流中这些分支会被`pull`到另一个开发者的本地仓库中,而在功能分支工作流和`Gitflow`工作流中是直接被`push`到正式仓库中。 :beer: 示例 --------------------- @@ -51,11 +52,11 @@ ![](images/git-workflows-forking-1.png) -和任何使用`Git`项目一样,第一步是创建在服务器上一个正式仓库,让团队成功可以访问。 +和任何使用`Git`项目一样,第一步是创建在服务器上一个正式仓库,让所有团队成员都可以访问到。 通常这个仓库也会作为项目维护者的公有仓库。 [公有仓库应该是裸仓库](https://www.atlassian.com/git/tutorial/git-basics#!init),不管是不是正式代码库。 -所以项目维护者会运行你下面的命令来搭建正式仓库: +所以项目维护者会运行像下面的命令来搭建正式仓库: ```bash ssh user@host @@ -64,23 +65,34 @@ git init --bare /path/to/repo.git `Bitbucket`和`Stash`提供了一个方便的`GUI`客户端以完成上面命令行做的事。 这个搭建中央仓库的过程和前面提到的工作流完全一样。 -如果已有代码库,维护者也要`push`到这个仓库中。 +如果有现存的代码库,维护者也要`push`到这个仓库中。 ### 开发者`fork`正式仓库 ![](images/git-workflows-forking-2.png) -下一步,各个开发者会各自的公有仓库,用熟悉的`git clone`命令。 +其它所有的开发需要`fork`正式仓库。 +可以用`git clone`命令[用`SSH`协议连通到服务器](https://confluence.atlassian.com/display/BITBUCKET/Set+up+SSH+for+Git), +拷贝仓库到服务器另一个位置 —— 是的,`fork`操作基本上就只是一个服务端的克隆。 +`Bitbucket`和`Stash`上可以点一下按钮就让开发者完成仓库的`fork`操作。 -在这个示例中,假定用`Bitbucket`托管了仓库。记住,这样的话各个开发者需要各自的`Bitbucket`账号, -使用下面命令克隆服务端仓库: +这一步完成后,每个开发都在服务端有一个自己的仓库。和正式仓库一样,这些仓库应该是裸仓库。 + +### 开发者克隆自己`fork`出来的仓库 + +![](images/git-workflows-forking-3.png) + +下一步,各个开发者要克隆自己的公有仓库,用熟悉的`git clone`命令。 + +在这个示例中,假定用`Bitbucket`托管了仓库。记住,如果这样的话各个开发者需要有各自的`Bitbucket`账号, +使用下面命令克隆服务端自己的仓库: ```bash git clone https://user@bitbucket.org/user/repo.git ``` 相比前面介绍的工作流只用了一个`origin`远程别名指向中央仓库,`Forking`工作流需要2个远程别名 —— -一个指向正式仓库,另一个指向开发者自己的服务端仓库。别名的命名可以任意命名,常见的约定是使用`origin`作为远程克隆的仓库的别名 +一个指向正式仓库,另一个指向开发者自己的服务端仓库。别名的名字可以任意命名,常见的约定是使用`origin`作为远程克隆的仓库的别名 (这个别名会在运行`git clone`自动创建),`upstream`(上游)作为正式仓库的别名。 ```bash @@ -94,13 +106,13 @@ git remote add upstream https://bitbucket.org/maintainer/repo git remote add upstream https://user@bitbucket.org/maintainer/repo.git ``` -在克隆和`pull`正式仓库时,需要提供用户的密码。 +这时在克隆和`pull`正式仓库时,需要提供用户的密码。 ### 开发者开发自己的功能 ![](images/git-workflows-forking-4.png) -在刚克隆的本地仓库中,开发者可以像其它工作流一样的编辑代码、提交修改和新建分支: +在刚克隆的本地仓库中,开发者可以像其它工作流一样的编辑代码、[提交修改](https://www.atlassian.com/git/tutorial/git-basics#!commit)和[新建分支](https://www.atlassian.com/git/tutorial/git-branches#!branch): ```bash git checkout -b some-feature @@ -108,13 +120,13 @@ git checkout -b some-feature git commit -a -m "Add first draft of some feature" ``` -所有的修改都是私有的直到`push`到自己公开仓库中。如果正式项目已经往前走了,可以用`git pull`命令获得: +所有的修改都是私有的直到`push`到自己公开仓库中。如果正式项目已经往前走了,可以用[`git pull`命令](https://www.atlassian.com/git/tutorial/remote-repositories#!pull)获得新的提交: ```bash git pull upstream master ``` -由于开发都应该在专门的功能分支上开发,`pull`操作会是[快进合并](https://www.atlassian.com/git/tutorial/git-branches#!merge)。 +由于开发者应该都在专门的功能分支上工作,`pull`操作结果会都是[快进合并](https://www.atlassian.com/git/tutorial/git-branches#!merge)。 ### 开发者发布自己的功能 @@ -122,34 +134,34 @@ git pull upstream master 一旦开发者准备好了分享新功能,需要做二件事。 首先,通过`push`他的贡献代码到自己的公开仓库中,让其它的开发者都可以访问到。 -他的`origin`远程别名应该已经有了,所以要做就是: +他的`origin`远程别名应该已经有了,所以要做的就是: ```bash git push origin feature-branch ``` -和之前的工作流的差异就在于,`origin`远程别名指向开发者自己的服务端仓库,而不是正式仓库。 +这里和之前的工作流的差异是,`origin`远程别名指向开发者自己的服务端仓库,而不是正式仓库。 -然后,开发者要通知项目维护者,想合并他的新功能到正式库中。 -`Bitbucket`和`Stash`提供了`Pull Request`按钮,弹出表单让你指定哪个分支要合并到正式仓库。 -一般你会想集合你的功能分支到上游远程仓库的`master`分支。 +第二件事,开发者要通知项目维护者,想要合并他的新功能到正式库中。 +`Bitbucket`和`Stash`提供了[`Pull Request`](https://confluence.atlassian.com/display/STASH/Using+pull+requests+in+Stash)按钮,弹出表单让你指定哪个分支要合并到正式仓库。 +一般你会想集成你的功能分支到上游远程仓库的`master`分支中。 ### 项目维护者集成开发者的功能 ![](images/git-workflows-forking-6.png) -当项目维护者收到`pull request`,他要做的是决定是否集成到正式代码库中。有二种方式来做: +当项目维护者收到`pull request`,他要做的是决定是否集成它到正式代码库中。有二种方式来做: 1. 直接在`pull request`中查看代码 1. `pull`代码到他自己的本地仓库,再手动合并 第一种做法更简单,维护者可以在`GUI`中查看变更的差异,做评注和执行合并。 -但如果出现了合并冲突,需要第二种做法来解决。这种情况下,维护者需要从开发者服务端仓库上[`fetch`](https://www.atlassian.com/git/tutorial/remote-repositories#!fetch)功能分支, +但如果出现了合并冲突,需要第二种做法来解决。这种情况下,维护者需要从开发者的服务端仓库中[`fetch`](https://www.atlassian.com/git/tutorial/remote-repositories#!fetch)功能分支, 合并到他本地的`master`分支,解决冲突: ```bash git fetch https://bitbucket.org/user/repo feature-branch -# Inspect the changes +# 查看变更 git checkout master git merge FETCH_HEAD ``` @@ -160,13 +172,13 @@ git merge FETCH_HEAD git push origin master ``` -注意维护者的`origin`是指向他自己公有仓库的,即是项目的正式代码库。到此,开发者的贡献完全集成到了项目中。 +注意,维护者的`origin`是指向他自己公有仓库的,即是项目的正式代码库。到此,开发者的贡献完全集成到了项目中。 ### 开发者和正式仓库做同步 ![](images/git-workflows-forking-7.png) -由于正式代码库往前走了,其它的开发需要做同步: +由于正式代码库往前走了,其它的开发需要和正式仓库做同步: ```bash git pull upstream master @@ -180,9 +192,9 @@ git pull upstream master 不是直接通过单个中央仓库来分享分支,而是把贡献代码发布到开发者自己的服务端仓库中。 示例中解释了,一个贡献如何从一个开发者流到正式的`master`分支中,但同样的方法可以把贡献集成到任一个仓库中。 -比如,如果团队的几个人协作实现一个功能,可以在开发之间用相同的方法分享变更,不涉及路面仓库。 +比如,如果团队的几个人协作实现一个功能,可以在开发之间用相同的方法分享变更,完全不涉及正式仓库。 -这使得`Forking`工作流对于松散组织的团队来说是个很强大的工具。任一开发者可以方便地和另一开发者分享变更,任何分支都能有效地合并到正式代码库。 +这使得`Forking`工作流对于松散组织的团队来说是个非常强大的工具。任一开发者可以方便地和另一开发者分享变更,任何分支都能有效地合并到正式代码库中。 -----------------