`
fw0124
  • 浏览: 5477 次
文章分类
社区版块
存档分类
最新评论

Git工作流 - 分支的策略

 
阅读更多
Git提供异常灵活的分支操作,但是在实践中也是需要制定良好的分支策略才能保证有效的利用Git来管理代码。
最近发现了一篇很好的英文文章,https://www.atlassian.com/git/tutorials/comparing-workflows,根据其内容作了整理。

关于分支策略,有如下几种好的实践方式。


Centralized Workflow / 集中式工作流

集中式工作流非常类似于SVN,但是你也可以享受到Git带来的好处,比如可以完全在本地工作直到你要提交,在比如利用Git强壮的分支和合并模型。

How It Works / 如何工作

中央仓库上只有一个master分支,类似于SVN中的trunk。所有的改变都提交到master分支。

Managing Conflicts / 合并提交和管理冲突

如果提交的时候中央库上已经有了新的提交,产生了冲突,需要pull中央库的最新提交,然后rebase自己的修改到最新提交之上。

例如上图所示,中央库的master分支origin/master上有了新的提交,本地的master分支上也有了新的提交。
这个时候,如果直接git push,git会报告需要合并修改。通过以下的几步合并修改并解决冲突。

1)git pull --rebase
加上--rebase选项是为了把本地的提交移动到中央库分支的master之上,如下图所示。rebase相当于先获取中央库的提交,然后把本地的提交一个一个应用上去。

如果不加上rebase选项,也可以完成合并,但是每次会生成一个“Merge branch ...”的提交。
比如A和B各自添加了文件0,1,分别提交,合并修改的时候没有用rebase选项;之后A和B又分别提交了文件2和3,使用rebase选项解决冲突。
下面是通过”git log --graph --oneline“命令观察分支图的结果,可以很清楚的看出其中的区别。
* dc5fbe2 3
* 98eda49 2
*   cfc8ea7 Merge branch 'master' of https://github.com/gitworkflow/learngit
|\
| * a3aa78c 0
* | 90cc835 1
|/
* b2d5caf new

2)如果中央库的提交和本地提交没有修改相同文件,那么现在可以直接push了。否则的话,git会在合并有冲突的地方暂停。
比如现在A修改了文件0和1,A的提交历史如下并且已经提交到了中央库。
* a014fa1 vi 1
* fb1193a vi 0
* dc5fbe2 3
* 98eda49 2

B也修改了文件0和1,B的本地提交历史如下
* 57e6473 edit 1
* d0ea63e edit 0
* dc5fbe2 3
* 98eda49 2

现在B运行”git pull --rebase“命令,git会先拉取到中央库的最新提交a014fa1,然后在其之上应用本地的提交d0ea63e和57e6473。
由于有冲突,git会报告下面错误并暂停rebase。
......
CONFLICT (content): Merge conflict in 0
......
When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".

这里git给出的提示也非常直接和详细。
这个时候也可以运行git status获取到详细冲突信息。

那接下来,我们需要
2.1) 编辑冲突文件,解决冲突。
2.2) git add --all
2.3) git rebase --continue

这个时候git会报告 CONFLICT (content): Merge conflict in 1,接下来冲突上面的操作直到解决全部冲突。
在这个过程中的任何时候,如果我们需要放弃这次合并,可以运行“git rebase --abort”命令,就会回到第一步运行”git pull --rebase"之前的状态。
2.4) git push
最后别忘记push提交到中央库。


Feature Branch Workflow / 特性分支工作流

如果习惯了上面的集中式工作流,就很容易添加特性分支来在开发者之间鼓励合作和提高交流效率。

特性分支工作流的核心思想是所有的特性开发都必须在一个独立分支上进行。这也意味着master分支上永远不应该包含未完成的代码。这对于持续集成来说是非常重要的。


How It Works / 如何工作

中央仓库上也有一个master分支,代表正式的项目历史。
但是开发者不能把修改提交到本地的master分支。开发者每次开发一个新的特性之前,必须创建一个新的分支,注意给分支取一个有意义的名字。
此外特性分支也需要push到中央仓库,这样才能和其他开发者分享代码。当然这样也便于备份本地提交。

Pull Request

特性分支也使得通过pull request来讨论变更成为可能。
一旦某个开发者完成一个feature,不能马上合并到master分支,必须把feature分支push到中央库,然后发起一个pull request来请求合并到master分支。这样其他开发者就可以review修改。
其实除了进行code review,pull request也是进行讨论的一个方式。
比如在Github的pull request发起界面,你可以填写comment提出问题,收到request的开发者可以review代码提出意见,也可以填写comment来回答问题。
讨论中,开发者可以对这个feature 分支再提交修改,这些提交历史以及讨论内容都会显示在这个pull request的历史记录中。
最终,如果这个pull request得到认可,就可以合并到master分支上。
可以通过Github等工具提供的类似[Merge pull request]按钮来完成合并,也可以通过下面的命令行合并。
git checkout master
git pull origin master
git merge origin/feature-xxx --no-ff
git push
首先pull master分支的最新修改,然后合并feature分支到master分支。
加上--no-ff选项,可以确保不使用fast forward合并,这样虽然上面的过程会产生一个合并提交,但是保留了feature分支的提交历史,这样通过git log --graph可以看到feature分支的历史信息。
(如果要保证线性的提交历史,可以去掉--no-ff选项,但是对于feature分支工作流,不建议这么做)


Gitflow Workflow / Gitflow工作流

Gitflow工作流围绕着项目发布定义了严格的分支模型。虽然比较复杂,但是对于大型项目管理提供了一个健壮的框架。
和feature分支工作流相比,它使用了独立的分支来管理发布。

参考下图,Gitflow工作流涉及到2个主分支(master,develop)和3个支持分支(feature,release,hotfix)。


具体介绍可以看这篇文章http://blog.csdn.net/fw0124/article/details/50426740

Forking Workflow / Forking工作流

前面介绍的几种工作流都是只有一个服务器端仓库(中央仓库)。Forking工作流和上面的几种工作流之间有一个根本性的区别是每个开发者有自己的服务端仓库。这意味着每个开发者有两个服务器端仓库,一个是公共的仓库(offical repo),一个是开发者自己的仓库。
开发者只有权限提交修改到私有服务器端仓库,只有项目维护者有权限push修改到公共仓库。
从技术的角度,对于Git 来说,这两种服务器端仓库没有区别,称作正式仓库只是因为它是项目维护者的服务器端仓库。


How It Works / 如何工作

使用Forking工作流,项目进展方式如下:
1)项目维护者创建公共仓库(offical repo)
2)项目开发者fork公共仓库,创建私有服务器仓库拷贝。
其他的开发者不能push到这个仓库,但是可以pull其修改。
开发者可以使用分支以便于和其他开发者分享修改。
3)项目开发者clone私有服务器仓库到本地。
4)项目开发者进行开发。
5)项目开发者push修改到私有服务器仓库。
6)项目开发者发起一个pull request通知维护者需要提交修改到正式仓库。
如上面所说,pull request也在开发者之间提供了一个便利的讨论方式。
7)项目维护者pull开发者的提交到本地,merge到本地的master分支上,并进行检查,如果没有问题,push到正式仓库的master分支。
维护者可以在Github等工具提供的pull request的界面中直接审查修改,评论和执行合并。
不过如果出现了合并冲突,需要到命令行执行如下命令来解决冲突。
git fetch https://bitbucket.org/user/repo feature-branch
# Inspect the changes
git checkout master
git merge FETCH_HEAD
git push origin master
8)其他的开发者可以同步正式仓库的修改到私有仓库中。
git pull upstream master

对于开源项目,Fork工作流是一个非常理想的工作方式。
Forking工作流对于松散组织的团队来说是个非常强大的工具。任和开发者可以方便地和其他开发者分享变更,任何分支都能够有效地合并到正式代码库中。











分享到:
评论

相关推荐

    Git使用说明书-v2.1.55

    5. 多种分布式工作流的细节,以及如何使用 Git 实现它们 6. 介绍 GitHub 托管服务以及深层次的工具 7. 关于 Git 的高级命令 8. 关于 Git 环境的自定义配置,包括设置用于增强或促进自定义策略的钩子脚本, 以及按照...

    Git权威指南PDF完整版

    26.2.2 Git工作分支和 Subversion 如何对应/ 388 26.2.3 其他辅助文件/ 390 26.3 多样的 git-svn 克隆模式/ 390 26.4 共享 git-svn 的克隆库/ 393 26.5 git-svn 的局限/ 394 第5篇 搭建Git服务器 第27章 使用 HTTP ...

    progit(git中文文档)

    *第五章*将阐述多种分布式工作流的细节,以及如何使用 Git 实现它们。学习完本章,你应该能够在多个远程仓 库 之间游刃有余,通过电子邮件使用 Git,熟练地处理多个远程分支和合作者贡献的补丁。 *第六章*介绍 GitHub ...

    GIT中文资源

    3 Git 分支 43 3.1 何谓分支 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 3.2 基本的分支与合并 . . . . . . . . . . . . . . . . . . . . . . . . . . 47 3.2.1 基本分支 . . . . . . . . . ....

    chef-jenkins:ChefJenkins 工作流集成

    厨师-詹金斯 使用 Jenkins 从 git 存储库驱动您的 Chef 环境的持续部署和同步它是如何工作 # 当您使用 Chef-jenkins 时,您应该始终处于 Chef-repo 中! (毕竟,我们要从詹金斯那里跑出来——但稍后再看) # 将 git...

    cordova-network-status:通知Cordova应用程序中的网络连接状态更改

    cordova-network-status 封装了标准的Cordova网络连接状态...该存储库使用git流分支策略。 如果您想贡献,请从开发分支分支-仅在请求合并到开发分支的情况下才请求拉取请求。 作者 由Brendan Graetz维护 执照 GPLv3

    Workflows-Assignment

    集成/合并拉取请求并在提交和任务(和拉取请求)之间建立可追溯性的工作流策略。第1步-创建新的存储库使用您的个人GitHub帐户名为CS471WorkflowsHomeworkAssignment。以下选项:应该禁用/取消选中Initialize this ...

    CS471工作流程家庭作业分配

    集成/合并拉取请求并在提交和任务(和拉取请求)之间建立可追溯性的工作流策略。第1步-创建新的存储库使用您的个人GitHub帐户名为CS471WorkflowsHomeworkAssignment。 以下选项:应该禁用/取消选中Initialize this ...

    CS471WorkflowsHomeworkAssignment

    集成/合并拉取请求并在提交和任务(和拉取请求)之间建立可追溯性的工作流策略。 第1步-创建新的存储库 使用您的个人GitHub帐户名为CS471WorkflowsHomeworkAssignment。 以下选项:应该禁用/取消选中Initialize ...

    documents:与Kodkollektivet相关的文件

    文件资料该存储库包含与Kodkollektivet相关的任何文档,例如工作流,策略等。Git工作流程不允许您合并自己的拉取请求(PR)。 编写相关的良好git commits。 允许对提交进行重新设置基准,但不要以混淆的方式重新设置...

    handwriting:手写和笔画识别库

    handwriting 手写和笔画识别库 用法 //去做 ...该存储库使用git流分支策略。 如果您想贡献,请从开发分支分支-仅在请求合并到开发分支的情况下才请求拉取请求。 作者 由Brendan Graetz维护 执照 GPLv3

    【白雪红叶】JAVA学习技术栈梳理思维导图.xmind

    git 项目管理 maven Nexus Jenkins 工作软件 反编译软件 office系列 下载器 adobe系列 记录软件 思维导图 office--Note 邮件管理 性能优化 分层优化 系统级别 中间件级别 JVM级别 代码级别 ...

Global site tag (gtag.js) - Google Analytics