拉取远程仓库的贡献
如果你的贡献者建立了自己的版本库,并且向其中推送了若干修改, 之后将版本库的 URL 和包含更改的远程分支发送给你,那么你可以将其添加为一个远程分支,并且在本地进行合并。
比如 Jessica 向你发送了一封电子邮件,内容是在她的版本库中的 ruby-client
分支中有一个很不错的新功能, 为了测试该功能,你可以将其添加为一个远程分支,并在本地检出:
$ git remote add jessica git://github.com/jessica/myproject.git
$ git fetch jessica
$ git checkout -b rubyclient jessica/ruby-client
这对于与他人长期合作工作来说很有用。 而对于提交补丁频率较小的贡献者,相对于每个人维护自己的服务器,不断增删远程分支的做法,使用电子邮件来接收可能会比较省时。 况且你也不会想要加入数百个只提供一两个补丁的远程分支。 然而,脚本和托管服务在一定程度上可以简化这些工作——这很大程度上依赖于你和你的贡献者开发的方式。
这种方式的另一种优点是你可以同时得到提交历史。 虽然代码合并中可能会出现问题,但是你能获知他人的工作是基于你的历史中的具体哪一个位置;所以 Git 会默认进行三方合并,不需要提供 -3
选项,你也不需要担心补丁是基于某个你无法访问的提交生成的。
仅拉取而不添加远程仓库
对于非持续性的合作,如果你依然想要以这种方式拉取数据的话,你可以对远程版本库的 URL 调用 git pull
命令。 这会执行一个一次性的抓取,而不会将该 URL 存为远程引用:
$ git pull https://github.com/onetimeguy/project
From https://github.com/onetimeguy/project
* branch HEAD -> FETCH_HEAD
Merge made by the 'recursive' strategy.
查看贡献内容
你已经有了一个包含其他人贡献的主题分支。 现在你可以决定如何处理它们了。
首先,应该查看非 master
分支即主题分支的内容,因为对方如果也遵守git规范,那么特性都是放在分支上的。假设贡献者向你发送了两个补丁,为此你创建了一个名叫 contrib
的分支并在其上应用补丁,你可以运行:
$ git log contrib --not master
commit 5b6235bd297351589efc4d73316f0a68d484f118
Author: Scott Chacon <schacon@gmail.com>
Date: Fri Oct 24 09:53:59 2008 -0700
seeing if this helps the gem
commit 7482e0d16d04bea79d0dba8988cc78df655f16a0
Author: Scott Chacon <schacon@gmail.com>
Date: Mon Oct 22 19:38:36 2008 -0700
updated the gemspec to hopefully work better
如果要查看每次提交所引入的具体修改,你应该记得可以给 git log
命令传递 -p
选项,这样它会在每次提交后面附加对应的差异(diff)。
其次是查看和 master
分支的差异,通过使用 ...
语法可以实现将 主题分支 与 和master
分支的最近公共祖先 的差异显示出来:
$ git diff master...contrib
该命令仅会显示自当前主题分支 contrib
与 master
分支的共同祖先起,该分支中的工作。
整合贡献内容
合并工作流
将所有的工作直接合并到 master
分支。 在这种情况下,master
分支包含的代码是基本稳定的。 当你完成某个主题分支的工作,或审核通过了其他人所贡献的工作时,你会将其合并进入 master
分支,之后将主题分支删除,如此反复。
例如有主题分支 ruby_client
和 php_client
:
将其贡献整合到自己的
master
分支中可能如下:
但在更大更稳定的项目中,这么做很可能带来问题,现在更推崇两阶段合并循环,即维护两个长期分支,分别是 master
存放非常稳定的版本 和 develop
存放整合新代码的版本。
例如:
觉得
ruby_client
不错的话就先整合到 develop
在经过长期测试之后再发布到 master
中:
大项目合并工作流
这里以 Git 项目举例
变基与挑拣工作流
通过变基来合并可以保持主分支的线性历史,将主题分支变基到主分支上后再进行向前合并。
具体参见 202501161656 git rebase。
另一种将引入的工作转移到其他分支的方法是拣选。 Git 中的拣选类似于对特定的某次提交的变基。 它会提取该提交的补丁,之后尝试将其重新应用到当前分支上。 这种方式在你只想引入主题分支中的某个提交,或者主题分支中只有一个提交,而你不想运行变基时很有用。 举个例子,假设你的项目提交历史类似:
如果你希望将提交 e43a6
拉取到 master
分支,你可以运行:
$ git cherry-pick e43a6
Finished one cherry-pick.
[master]: created a0a41a9: "More friendly message when locking the index fails."
3 files changed, 17 insertions(+), 3 deletions(-)
这样会拉取和 e43a6
相同的更改,但是因为应用的日期不同,你会得到一个新的提交 SHA-1 值。 现在你的历史会变成这样: