没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
3分布式分布式Git-维护项目维护项目
文章的第一篇 1分布式 Git - 分布式工作流程
文章的第二篇 2 分布式 Git - 向一个项目贡献
维护项目
除了如何有效地参与一个项目的贡献之外,你可能也需要了解如何维护项目。 这包含接受并应用别人使用 format-patch 生成
并通过电子邮件发送过来的补丁,或对项目添加的远程版本库分支中的更改进行整合。 但无论是管理版本库,还是帮忙验
证、审核收到的补丁,都需要同其他贡献者约定某种长期可持续的工作方式。
在特性分支中工作
如果你想向项目中整合一些新东西,最好将这些尝试局限在特性分支——一种通常用来尝试新东西的临时分支中。 这样便于
单独调整补丁,如果遇到无法正常工作的情况,可以先不用管,等到有时间的时候再来处理。 如果你基于你所尝试进行工作
的特性为分支创建一个简单的名字,比如 ruby_client 或者具有类似描述性的其他名字,这样即使你必须暂时抛弃它,以后回
来时也不会忘记。 项目的维护者一般还会为这些分支附带命名空间,比如 sc/ruby_client(其中 sc 是贡献该项工作的人名称
的简写)。 你应该记得,可以使用如下方式基于 master 分支建立特性分支:
或者如果你同时想立刻切换到新分支上的话,可以使用 checkout -b 选项:
现在你已经准备好将别人贡献的工作加入到这个特性分支,并考虑是否将其合并到长期分支中去了。
应用来自邮件的补丁
如果你通过电子邮件收到了一个需要整合进入项目的补丁,你需要将其应用到特性分支中进行评估。 有两种应用该种补丁的
方法:使用 git apply,或者使用 git am。
使用 apply 命令应用补丁
如果你收到了一个使用 git diff 或 Unix diff 命令(不推荐使用这种方式,具体见下一节)创建的补丁,可以使用 git apply 命令
来应用。 假设你将补丁保存在了 /tmp/patch-ruby-client.patch 中,可以这样应用补丁:
这会修改工作目录中的文件。 它与运行 patch -p1 命令来应用补丁几乎是等效的,但是这种方式更加严格,相对于 patch 来
说,它能够接受的模糊匹配更少。 它也能够处理 git diff 格式文件所描述的文件添加、删除和重命名操作,而 patch 则不会。
最后,git apply 命令采用了一种“全部应用,否则就全部撤销(apply all or abort all)”的模型,即补丁只有全部内容都被应用
和完全不被应用两个状态,而 patch 可能会导致补丁文件被部分应用,最后使你的工作目录保持在一个比较奇怪的状态。 总
体来看,git apply 命令要比 patch 谨慎得多。 并且,它不会为你创建提交——在运行之后,你需要手动暂存并提交补丁所引
入的更改。
在实际应用补丁前,你还可以使用 git apply 来检查补丁是否可以顺利应用——即对补丁运行 git apply --check 命令:
如果没有产生输出,则该补丁可以顺利应用。 如果检查失败了,该命令还会以一个非零的状态退出,所以需要时你也可以在
脚本中使用它。
使用 am 命令应用补丁
如果补丁的贡献者也是一个 Git 用户,并且其能熟练使用 format-patch 命令来生成补丁,这样的话你的工作会变得更加轻松,
因为这种补丁中包含了作者信息和提交信息供你参考。 如果可能的话,请鼓励贡献者使用 format-patch 而不是 diff 来为你生
成补丁。 而只有对老式的补丁,你才必须使用 git apply 命令。
要应用一个由 format-patch 命令生成的补丁,你应该使用 git am 命令。 从技术的角度看,git am 是为了读取 mbox 文件而构
建的,mbox 是一种用来在单个文本文件中存储一个或多个电子邮件消息的简单纯文本格式。 其大致格式如下所示:
这其实就是你前面看到的 format-patch 命令输出的开始几行。 而同时它也是有效的 mbox 电子邮件格式。 如果有人使用 git
send-email 命令将补丁以电子邮件的形式发送给你,你便可以将它下载为 mbox 格式的文件,之后将 git am 命令指向该文
件,它会应用其中包含的所有补丁。 如果你所使用的邮件客户端能够同时将多封邮件保存为 mbox 格式的文件,你甚至能够
将一系列补丁打包为单个 mbox 文件,并利用 git am 命令将它们一次性全部应用。
然而,如果贡献者将 format-patch 生成的补丁文件上传到类似 Request Ticket 的任务处理系统,你可以先将其保存到本地,
之后通过 git am 来应用补丁:
你会看到补丁被顺利地应用,并且为你自动创建了一个新的提交。 其中的作者信息来自于电子邮件头部的 From 和 Date 字
段,提交消息则取自 Subject 和邮件正文中补丁之前的内容。 比如,应用上面那个 mbox 示例后生成的提交是这样的:
其中 Commit 信息表示的是应用补丁的人和应用补丁的时间。 Author 信息则表示补丁的原作者和原本的创建时间。
但是,有时候无法顺利地应用补丁。 这也许是因为你的主分支和创建补丁的分支相差较多,也有可能是因为这个补丁依赖于
其他你尚未应用的补丁。 这种情况下,git am 进程将会报错并且询问你要做什么:
该命令将会在所有出现问题的文件内加入冲突标记,就和发生冲突的合并或变基操作一样。 而你解决问题的手段很大程度上
也是一样的——即手动编辑那些文件来解决冲突,暂存新的文件,之后运行 git am --resolved 继续应用下一个补丁:
如果你希望 Git 能够尝试以更加智能的方式解决冲突,你可以对其传递 -3 选项来使 Git 尝试进行三方合并。 该选项默认并没
有打开,因为如果用于创建补丁的提交并不在你的版本库内的话,这样做是没有用处的。 而如果你确实有那个提交的话——
比如补丁是基于某个公共提交的——那么通常 -3 选项对于应用有冲突的补丁是更加明智的选择。
比如上面这种情况,我在之前已经应用过同样的补丁。 如果没有 -3 选项的话,这看起来就像是存在一个冲突。
如果你正在利用一个 mbox 文件应用多个补丁,也可以在交互模式下运行 am 命令,这样在每个补丁之前,它会停住询问你是
否要应用该补丁:
这在你保存的补丁较多时很好用,因为你可以在应用之前查看忘掉内容的补丁,并且跳过已经应用过的补丁。
当与你的特性相关的所有补丁都被应用并提交到分支中之后,你就可以选择是否以及如何将其整合到更长期的分支中去了。
检出远程分支
如果你的贡献者建立了自己的版本库,并且向其中推送了若干修改,之后将版本库的 URL 和包含更改的远程分支发送给你,
那么你可以将其添加为一个远程分支,并且在本地进行合并。
比如 Jessica 向你发送了一封电子邮件,内容是在她的版本库中的 ruby-client 分支中有一个很不错的新功能,为了测试该功
能,你可以将其添加为一个远程分支,并在本地检出:
如果她再次发邮件说另一个分支中包含另一个优秀功能,因为之前已经设置好远程分支了,你就可以直接进行抓取及检出操
作。
这对于与他人长期合作工作来说很有用。 而对于提交补丁频率较小的贡献者,相对于每个人维护自己的服务器,不断增删远
程分支的做法,使用电子邮件来接收可能会比较省时。 况且你也不会想要加入数百个只提供一两个补丁的远程分支。 然而,
脚本和托管服务在一定程度上可以简化这些工作——这很大程度上依赖于你和你的贡献者开发的方式。
这种方式的另一种优点是你可以同时得到提交历史。 虽然代码合并中可能会出现问题,但是你能获知他人的工作是基于你的
历史中的具体哪一个位置;所以Git 会默认进行三方合并,不需要提供 -3 选项,你也不需要担心补丁是基于某个你无法访问的
提交生成的。
对于非持续性的合作,如果你依然想要以这种方式拉取数据的话,你可以对远程版本库的 URL 调用 git pull 命令。 这会执行
一个一次性的抓取,而不会将该 URL 存为远程引用:
确定引入了哪些东西
你已经有了一个包含其他人贡献的特性分支。 现在你可以决定如何处理它们了。 本节回顾了若干命令,以便于你检查若将其
合并入主分支所引入的更改。
一般来说,你应该对该分支中所有 master 分支尚未包含的提交进行检查。 通过在分支名称前加入 --not 选项,你可以排除
master 分支中的提交。 这和我们之前使用的 master..contrib 格式是一样的。 假设贡献者向你发送了两个补丁,为此你创建了
一个名叫 contrib 的分支并在其上应用补丁,你可以运行:
如果要查看每次提交所引入的具体修改,你应该记得可以给 git log 命令传递 -p 选项,这样它会在每次提交后面附加对应的差
异(diff)。
而要查看将该特性分支与另一个分支合并的完整 diff,你可能需要使用一个有些奇怪的技巧来得到正确的结果。 你可能会想到
这种方式:
这个命令会输出一个 diff,但它可能并不是我们想要的。 如果在你创建特性分支之后,master 分支向前移动了,你获得的结
果就会显得有些不对。 这是因为 Git 会直接将该特性分支与 master 分支的最新提交快照进行比较。 比如说你在 master 分支
中向某个文件添加了一行内容,那么直接比对最新快照的结果看上去就像是你在特性分支中将这一行删除了。
如果 master 分支是你的特性分支的直接祖先,其实是没有任何问题的;但是一旦两个分支的历史产生了分叉,上述比对产生
的 diff 看上去就像是将特性分支中所有的新东西加入,并且将 master 分支所独有的东西删除。
而你真正想要检查的东西,实际上仅仅是特性分支所添加的更改——也就是该分支与 master 分支合并所要引入的工作。 要达
到此目的,你需要让 Git 对特性分支上最新的提交与该分支与 master 分支的首个公共祖先进行比较。
从技术的角度讲,你可以以手工的方式找出公共祖先,并对其显式运行 diff 命令:
然而,这种做法比较麻烦,所以 Git 提供了一种比较便捷的方式:三点语法。 对于 diff 命令来说,你可以通过把 ... 置于另一
个分支名后来对该分支的最新提交与两个分支的共同祖先进行比较:
该命令仅会显示自当前特性分支与 master 分支的共同祖先起,该分支中的工作。 这个语法很有用,应该牢记。
剩余6页未读,继续阅读
资源评论
weixin_38628310
- 粉丝: 4
- 资源: 950
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功