版本管理(4)- 简单清晰的分支策略有助于开发(Github)

说起 git,当然不能不提 github,一个伟大的协同工作网站

Github

上面讲的 Gitflow 只是在使用 git 的时候找到了一种比较适合工作的分支模式,而 Github 则重新定义了社会协同工作的模式。

我们知道,在集中式版本管理工具里,如果你想查阅某个代码文件,那么你首先要有这个文件的读取权限;如果你想修改这个文件,你还需要这个文件的写权限。这在企业里被认为是理所当然的,因为每个企业都有很多不便公开,也不便很多人查阅或者修改的代码(虽然很多时候这些代码就是一坨翔)。也就是说做事之前先要获取相应的授权才能去做。公司有各种要求,如产权保护,使我们不得不这样做。带来的一个问题就是不便协作,其实这也不能称作一个问题,因为在公司很少有人除了自己要完成的工作之外,还经常去改别人的代码。不允许是一方面,估计很多人也没那个精力去干这件事。但是社会协同工作模式却不是这样,开源社区走这样的路子是行不通的。开源社区更鼓励大家去参与、去贡献。如果你觉得代码有问题或者可以改进,拿一份自己修改就是了,也不需要授权,所有的东西都是公开的。如果你觉得自己的变更其他人也可能需要,同时你也愿意把自己的代码开源,那么你也可以分享出来。如果你不愿意也没人强迫你去分享(视不同开源许可,会有不同情况发生)。这样渐渐形成一个鼓励大家改代码、大家改后再开源出来的良性循环。

而 Github 的出现,更是鼓励这种协作方式,并把开源、分享、协作的精神发扬光大。下面我们就来看看在 Github 上是如何协作的。

工作方式

简单的说我到 Github 上看到有人创建了一个 repo,里面的内容我非常喜欢,想起来的时候回来看看,关注下动态,这个时候我们 star 一下这个库就可以了(不用 fork), 等自己有空的时候,翻下自己的 star 列表就可以找到这个项目了。如果想在 repo 更新的时候收到一些系统消息,可以利用 watch 这个功能。当有 issue 等变更时,自己还能收到通知。

当我发现一个 repo 写的内容太好了,正是自己想要的东西,并且自己还想有些定制化的内容,或者也同时有意向参与改进这个项目,怎么办呢?很简单,就像把大象装冰箱里一样,仅需要三步。

拿一份代码自己用
  • fork 源仓库。直接从源 repo,比如用户 scmroad 的 abc 库,fork一个库到自己的用户空间。 fork 完之后,我们就可以在自己的小地盘看到了。
laofo / abc
forked from scmroad/abc

使用 fork 功能将在后台会为你创建一个与该项目内容一样的同名项目,你可以在这个新项目里自由的修改内容。建议只在有意向参与改进该项目时使用 fork 功能。

这样我再在自己这个库 laofo/abc 做任何的修改都不会影响到原有的 git 仓库 scmroad/abc, 当然源仓库 scmroad/abc 的任何后续修改也不会自动同步到我的这个仓库里。

  • clone 我的仓库到本地。虽然在 web 端,我可以简单编辑下 README.md 文件,改个错别字,但是终归没有本地爽。所以编辑之前,先要 clone 一份我的仓库到本地。
git clone [email protected]:laofo/abc.git
  • update本地 push 到远程(自己的仓库)。把代码拿到我本地后,我就开始涂鸦了,修改了README.md 文件后,把所有修改commit 到本地。可以多次修改、多次 commit到本地。我本地是有远程仓库的一个完整副本,所以我需要的东西都在本地的仓库里,如果紧紧是针对文件的修改,这个时候完全不需要连接网络。这也是 git 的一大优势,就是可以离线提交。不用连接网络,我也可以提交代码。等有网络后,我再把本地提交提交到远程,使其他人可以看到我的修改。
echo 'author: laofo' >> README.md
git add README.md
git commit README.md -m "add author"
date >> README.md
git add README.md
git commit README.md -m "add revision time"
  • push 到我自己的仓库。我本地完成一个功能后,这个时候,我想把我本地的代码提交到我自己的远程仓库,让远程仓库也可以存储一份我的代码,同时也可以让其他人看到我本地的修改(如果是 public 的仓库)。
git push origin master

这样我的代码也保存到我个人的远程仓库了。虽然我仅仅是在源仓库的基础上做了一些个性化的变更,比如改个 logo,换个标题,但我已经很满意了。到此为止,就可以把我的这个远程仓库里的代码部署、上线了,一切都很完美。

fork->clone->update->push,个人仓库修改四部曲。

同步社区到自己的 repo

突然有一天,我发现线上出现了个 bug,而源仓库已经修复了这个 bug,而且我还发现源仓库 scmroad/abc 还换了皮肤,网站相当的漂亮。怎么办呢?同步源仓库代码到我的仓库呗。

  • 首先查看下本地关联的是哪个仓库
git remote -v
origin  [email protected]:laofo/abc.git (fetch)
origin  [email protected]:laofo/abc.git (push)
  • 然后建立与源仓库的联系
git remote add upstream [email protected]:scmroad/abc.git
git remote -v
origin  [email protected]:laofo/abc.git (fetch)
origin  [email protected]:laofo/abc.git (push)
upstream    [email protected]:scmroad/abc.git (fetch)
upstream    [email protected]:scmroad/abc.git (push)
  • 从源仓库的 master 合并代码到我的 master 分支
git pull upstream master
From git.scmroad.com:scmroad/abc
 * branch            master     -> FETCH_HEAD
Current branch master is up to date.

先 fetch 后 merge 也可以。操作如下:

git fetch upstream
git merge upstream/master

经过上面一番折腾,我们把源仓库 scmroad/abc最新的修改和我个性的修改进行了合并,保留了我个性化修改的同时,还合并了源仓库一些新加的功能,以及一些缺陷修复。这样我的仓库在不失个性化的同时其他部分还保持和源仓库最新的版本同步。多么完美,这正是我想要的状态。

反馈自己的变更给社区

日久生情,无论对人还是对物。使用着开源代码带来的好处的同时,自己慢慢的也对 scmroad/abc 这一套源程序有了一定的了解,慢慢的自己也可以修复程序中的一些 bug 了。同时自己还针对这套程序做了一个新的皮肤,很多人都觉得不错,都拿去用了。这个时候,我想把自己的这些修改同步到源仓库,这样使用 scmroad/abc 这个代码库的所有人都受益于我所做的问题修复,也可以看到我做的皮肤。具体怎么做呢?

  • 首先把自己的所有变更提交到自己的远程仓库。这一点怎么做,上面已经说的很清楚了。
  • 其次生成一个 pull request 发送给源仓库
    选择自己仓库的源分支,选择 scmroad/abc 的目标分支, 填写好 pull request 的标题和内容,然后就对源仓库发送了一个 pull request。

当源仓库 scmroad/abc 的作者 scmroad 收到我发出的 pull request 后,就会审查我的代码,评估我的修改是否有必要合并到他的 master 分支。有的时候可能因为我的修改正好修复了一些他正想修复但没修复的 bug而接受我的 pull request;有的时候也可能因为我所做的变更可能引来其他问题、不符合作者设计风格等等原因而被拒绝。不过这不重要,重要的是我得到了原作者的代码并进行了个性化的修改,满足了我的需要;同时我的一些缺陷修复也得到原作者的认可,给更多的人带来了便利,何乐而不为呢。

小结

从一开始的拿份代码自己用,到不时同步源仓库到我的小地盘,到最后把自己的修改贡献给社区,这一圈下来形成了一个我从社区受益同时又回馈社区的双赢局面。

反正闲着也是闲着,做点对自己、对他人都有益的事情吧。生活中不仅仅只有眼前的苟且,还有诗与远方。

你可能感兴趣的:(版本管理(4)- 简单清晰的分支策略有助于开发(Github))