文档章节

Git集中式工作流

小致dad
 小致dad
发布于 2017/08/19 15:32
字数 2380
阅读 24
收藏 0
点赞 0
评论 0

转到分布式版本控制系统看起来像个令人生畏的任务,但不改变已用的工作流你也可以用上Git带来的收益。团队可以用和Subversion完全不变的方式来开发项目。

但使用Git加强开发的工作流,GitSVN有几个优势。首先,每个开发可以有属于自己的整个工程的本地拷贝。隔离的环境让各个开发者的工作和项目的其他部分(修改)独立开来 —— 即自由地提交到自己的本地仓库,先完全忽略上游的开发,直到方便的时候再把修改反馈上去。

其次,Git提供了强壮的分支和合并模型。不像SVNGit的分支设计成可以做为一种用来在仓库之间集成代码和分享修改的『失败安全』的机制。

工作方式

Subversion一样,集中式工作流以中央仓库作为项目所有修改的单点实体。相比SVN缺省的开发分支trunkGit叫做master,所有修改提交到这个分支上。该工作流只用到master这一个分支。

开发者开始先克隆中央仓库。在自己的项目拷贝中,像SVN一样的编辑文件和提交修改;但修改是存在本地的,和中央仓库是完全隔离的。开发者可以把和上游的同步延后到一个方便时间点。

要发布修改到正式项目中,开发者要把本地master分支的修改『推(push)』到中央仓库中。这相当于svn commit操作,但push操作会把所有还不在中央仓库的本地提交都推上去。

冲突解决

中央仓库代表了正式项目,所以提交历史应该被尊重且是稳定不变的。如果开发者本地的提交历史和中央仓库有分歧,Git会拒绝push提交否则会覆盖已经在中央库的正式提交。

在开发者提交自己功能修改到中央库前,需要先fetch在中央库的新增提交,rebase自己提交到中央库提交历史之上。这样做的意思是在说,『我要把自己的修改加到别人已经完成的修改上。』最终的结果是一个完美的线性历史,就像以前的SVN的工作流中一样。

如果本地修改和上游提交有冲突,Git会暂停rebase过程,给你手动解决冲突的机会。Git解决合并冲突,用和生成提交一样的git statusgit add命令,很一致方便。还有一点,如果解决冲突时遇到麻烦,Git可以很简单中止整个rebase操作,重来一次(或者让别人来帮助解决)。

示例

让我们一起逐步分解来看看一个常见的小团队如何用这个工作流来协作的。有两个开发者小明和小红,看他们是如何开发自己的功能并提交到中央仓库上的。

有人先初始化好中央仓库

第一步,有人在服务器上创建好中央仓库。如果是新项目,你可以初始化一个空仓库;否则你要导入已有的GitSVN仓库。

中央仓库应该是个裸仓库(bare repository),即没有工作目录(working directory)的仓库。可以用下面的命令创建:

ssh user@host
git init --bare /path/to/repo.git

确保写上有效的userSSH的用户名),host(服务器的域名或IP地址),/path/to/repo.git(你想存放仓库的位置)。注意,为了表示是一个裸仓库,按照约定加上.git扩展名到仓库名上。

所有人克隆中央仓库

下一步,各个开发者创建整个项目的本地拷贝。通过git clone命令完成:

git clone ssh://user@host/path/to/repo.git

基于你后续会持续和克隆的仓库做交互的假设,克隆仓库时Git会自动添加远程别名origin指回『父』仓库。

小明开发功能

在小明的本地仓库中,他使用标准的Git过程开发功能:编辑、暂存(Stage)和提交。如果你不熟悉暂存区(Staging Area),这里说明一下:暂存区的用来准备一个提交,但可以不用把工作目录中所有的修改内容都包含进来。这样你可以创建一个高度聚焦的提交,尽管你本地修改很多内容。

git status # 查看本地仓库的修改状态
git add # 暂存文件
git commit # 提交文件

请记住,因为这些命令生成的是本地提交,小明可以按自己需求反复操作多次,而不用担心中央仓库上有了什么操作。对需要多个更简单更原子分块的大功能,这个做法是很有用的。

小红开发功能

与此同时,小红在自己的本地仓库中用相同的编辑、暂存和提交过程开发功能。和小明一样,她也不关心中央仓库有没有新提交;当然更不关心小明在他的本地仓库中的操作,因为所有本地仓库都是私有的。

小明发布功能

一旦小明完成了他的功能开发,会发布他的本地提交到中央仓库中,这样其它团队成员可以看到他的修改。他可以用下面的git push命令:

git push origin master

注意,origin是在小明克隆仓库时Git创建的远程中央仓库别名。master参数告诉Git推送的分支。由于中央仓库自从小明克隆以来还没有被更新过,所以push操作不会有冲突,成功完成。

小红试着发布功能

一起来看看在小明发布修改后,小红push修改会怎么样?她使用完全一样的push命令:

git push origin master

但她的本地历史已经和中央仓库有分岐了,Git拒绝操作并给出下面很长的出错消息:

error: failed to push some refs to '/path/to/repo.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

这避免了小红覆写正式的提交。她要先pull小明的更新到她的本地仓库合并上她的本地修改后,再重试。

小红在小明的提交之上rebase

小红用git pull合并上游的修改到自己的仓库中。这条命令类似svn update——拉取所有上游提交命令到小红的本地仓库,并尝试和她的本地修改合并:

git pull --rebase origin master

--rebase选项告诉Git把小红的提交移到同步了中央仓库修改后的master分支的顶部,如下图所示:

如果你忘加了这个选项,pull操作仍然可以完成,但每次pull操作要同步中央仓库中别人修改时,提交历史会以一个多余的『合并提交』结尾。对于集中式工作流,最好是使用rebase而不是生成一个合并提交。

小红解决合并冲突

rebase操作过程是把本地提交一次一个地迁移到更新了的中央仓库master分支之上。这意味着可能要解决在迁移某个提交时出现的合并冲突,而不是解决包含了所有提交的大型合并时所出现的冲突。这样的方式让你尽可能保持每个提交的聚焦和项目历史的整洁。反过来,简化了哪里引入Bug的分析,如果有必要,回滚修改也可以做到对项目影响最小。

如果小红和小明的功能是相关的,不大可能在rebase过程中有冲突。如果有,Git在合并有冲突的提交处暂停rebase过程,输出下面的信息并带上相关的指令:

CONFLICT (content): Merge conflict in

Git很赞的一点是,任何人可以解决他自己的冲突。在这个例子中,小红可以简单的运行git status命令来查看哪里有问题。冲突文件列在Unmerged paths(未合并路径)一节中:

# Unmerged paths:
# (use "git reset HEAD <some-file>..." to unstage)
# (use "git add/rm <some-file>..." as appropriate to mark resolution)
#
# both modified: <some-file>

接着小红编辑这些文件。修改完成后,用老套路暂存这些文件,并让git rebase完成剩下的事:

git add
git rebase --continue

要做的就这些了。Git会继续一个一个地合并后面的提交,如其它的提交有冲突就重复这个过程。

如果你碰到了冲突,但发现搞不定,不要惊慌。只要执行下面这条命令,就可以回到你执行git pull --rebase命令前的样子:

git rebase --abort

小红成功发布功能

小红完成和中央仓库的同步后,就能成功发布她的修改了:

git push origin master

本文转载自:https://my.oschina.net/liuyuantao/blog/1516693

共有 人打赏支持
小致dad
粉丝 116
博文 510
码字总数 556749
作品 0
济南
技术主管
好代码是管出来的——Git的分支工作流与Pull Request

  上一篇文章好代码是管出来的——使用Git来管理源代码 介绍了常用的版本控制工具以及git的基本用法,从基本用法来看git与其它的版本控制工具好像区别不大,都是对代码新增、提交进行管理,...

dotNET跨平台
06/25
0
0
分布式版本控制系统入门

在过去几年,对于分布式版本控制可以给开发过程提供的益处有许多争论。最近,分布式工具已经很成熟了。尽管分布式工具的一些优点最初可能不明显,但是从长 期来看,它们提供的灵活性是非常有...

红薯
2009/05/26
2.4K
2
代码管理工具--git-repo

Android使用Git作为代码管理工具,开发了Gerrit进行代码审核以便更好的对代码进行集中式管理,还开发了Repo命令行工具,对Git部分命令封装,将百多个Git库有效的进行组织。要想克隆和管理这百...

tadcat
2013/12/06
2.2K
0
Git算不算程序员的必备技能?

点击关注 异步图书,置顶公众号 每天与你分享 IT好书 技术干货 职场知识 参与文末话题讨论,每日赠送异步图书。 ——异步小编 Git的背后有着一个非常精彩的成功故事。2005年4月,Linus Torva...

异步社区
04/26
0
0
深入理解学习Git工作流(git-workflow-tutorial)

一、译序 二、Git工作流指南 2.5.1 解析Pull Request 2.5.2 工作方式 2.5.3 在功能分支工作流中使用Pull Request 2.5.4 在Gitflow工作流中使用Pull Request 2.5.5 在Forking工作流中使用Pul...

北方人在上海
2016/02/27
144
0
前端版本管理

前面的话   版本管理在产品级开发中是非常重要的一个部分,它涉及到团队协作,且影响到产品最终的发布、上线以及测试环节。本文将详细介绍版本管理 概述   版本控制系统(Version Contro...

sshpp
2017/07/24
0
0
git工作流介绍--结合sourcetree

git工作流介绍--结合sourcetree git分布式版本控制系统 分布式是如何实现的: 服务器上有一个git仓库。完整地克隆服务器上的git仓库生成本地仓库。进行本地开发,开发完成后,提交到本地仓库...

sekaiga
2017/10/22
0
1
初创公司应该如何做好持续集成和部署?

持续集成和部署是每一个互联网开发团队都必须要面对的问题,特别是在初创公司,由于业务和技术团队快速增长,技术积累较弱的,所以一个高效的,可持续的运维规范尤为重要。 最近一段时间一直...

90xa
2016/03/19
87
0
在 RHEL、CentOS 和 Fedora 上安装 Git 及设置 Git 账号的技巧

Git 是一个可以让你追踪软件改动、版本回滚以及创建另外一个版本的目录和文件的软件仓库。 Git 主要是用 C 语言来写的,混杂了少量的 Perl 脚本和各种 shell 脚本。它主要在 Linux 内核上运行...

linux小陶
2016/11/09
9
0
在 RHEL、CentOS 和 Fedora 上安装 Git 及设置 Git 账号的技巧

Git 是一个可以让你追踪软件改动、版本回滚以及创建另外一个版本的目录和文件的软件仓库。 Git 主要是用 C 语言来写的,混杂了少量的 Perl 脚本和各种 shell 脚本。它主要在 Linux 内核上运行...

linuxCool
2016/11/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

about git flow

  昨天元芳做了git分支管理规范的分享,为了拓展大家关于git分支的认知,这里我特意再分享这两个关于git flow的链接,大家可以看一下。 Git 工作流程 Git分支管理策略   git flow本质上是...

qwfys
今天
2
0
Linux系统日志文件

/var/log/messages linux系统总日志 /etc/logrotate.conf 日志切割配置文件 参考https://my.oschina.net/u/2000675/blog/908189 dmesg命令 dmesg’命令显示linux内核的环形缓冲区信息,我们可...

chencheng-linux
今天
1
0
MacOS下给树莓派安装Raspbian系统

下载镜像 前往 树莓派官网 下载镜像。 点击 最新版Raspbian 下载最新版镜像。 下载后请,通过 访达 双击解压,或通过 unzip 命令解压。 检查下载的文件 ls -lh -rw-r--r-- 1 dingdayu s...

dingdayu
今天
1
0
spring boot使用通用mapper(tk.mapper) ,id自增和回显等问题

最近项目使用到tk.mapper设置id自增,数据库是mysql。在使用通用mapper主键生成过程中有一些问题,在总结一下。 1、UUID生成方式-字符串主键 在主键上增加注解 @Id @GeneratedValue...

北岩
今天
2
0
告警系统邮件引擎、运行告警系统

告警系统邮件引擎 cd mail vim mail.py #!/usr/bin/env python#-*- coding: UTF-8 -*-import os,sysreload(sys)sys.setdefaultencoding('utf8')import getoptimport smtplibfr......

Zhouliang6
今天
1
0
Java工具类—随机数

Java中常用的生成随机数有Math.random()方法及java.util.Random类.但他们生成的随机数都是伪随机的. Math.radom()方法 在jdk1.8的Math类中可以看到,Math.random()方法实际上就是调用Random类...

PrivateO2
今天
3
0
关于java内存模型、并发编程的好文

Java并发编程:volatile关键字解析    volatile这个关键字可能很多朋友都听说过,或许也都用过。在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果。在...

DannyCoder
昨天
1
0
dubbo @Reference retries 重试次数 一个坑

在代码一中设置 成retries=0,也就是调用超时不用重试,结果DEBUG的时候总是重试,不是0吗,0就不用重试啊。为什么还是调用了多次呢? 结果在网上看到 这篇文章才明白 https://www.cnblogs....

奋斗的小牛
昨天
2
0
数据结构与算法3

要抓紧喽~~~~~~~放羊的孩纸回来喽 LowArray类和LowArrayApp类 程序将一个普通的Java数组封装在LowArray类中。类中的数组隐藏了起来,它是私有的,所以只有类自己的方法才能访问他。 LowArray...

沉迷于编程的小菜菜
昨天
1
0
spring boot应用测试框架介绍

一、spring boot应用测试存在的问题 官方提供的测试框架spring-boot-test-starter,虽然提供了很多功能(junit、spring test、assertj、hamcrest、mockito、jsonassert、jsonpath),但是在数...

yangjianzhou
昨天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部