背景

最近我们组几个同事都投入到了一个新项目,互相之间的功能耦合比较紧密,因此,是打算从master上新拉一个分支,可以理解为我们几个人的开发分支,以develop代替。

一开始,我们是打算像svn那样用的,几个人就把这个新分支develop当做唯一的主干分支,几个人互相快速提交/拉取,回到了用svn的快乐日子。

不过,大家用svn也知道,经常呢,我们为了保证代码不丢,会经常性地往分支提交,即使某个功能写了一半,一个功能,n次commit记录,且和同事的commit交错在一起;另外,我们提交的代码,有时候会导致同事那里跑不起来。

简而言之,就是commit有点碎;另外,可能阻塞其他同事。

我们组长提了另外一种思路,就是,每个人基于这个开发分支develop,再自己单独拉取一个分支出来,如develop-zhangsan,develop-lisi。每个人在自己的单独的分支上开发,开发了一个较为完整的功能后,再提一个pull request给develop,此时,可以对这个较完整的功能做代码review,review通过后,即合并到develop分支。但此时,怎么才是最佳实践呢,且能保证开发分支develop的提交历史成为优雅的一条线呢?

这里假设有张三、李四两个人,基于gitlab、github、gitee等进行开发,最终,主要有以下几个分支:

远程 本地
origin/master master
origin/develop develop
origin/develop-zhangsan develop-zhangsan
origin/develop-lisi develop-lisi

实战环境准备

我这边已经准备好了实战案例,已经把上面的几个分支都拉好了。

https://gitee.com/ckl111/git-rebase-test

假设我先在远程,把这几个分支先建好,我是在gitee操作的。

目前,zhangsan、lisi分支,是基于develop拉出来的,所以最新提交都是一样的。

模拟张三开发

大家看上图,张三来了一顿操作,切到了自己的分支,改了点东西,做了一次提交,不过提交还没推送到远端自己的分支。

模拟李四开发

修改、推送

李四也是个猛人啊,上来一顿cv,commit、push一气呵成。

远端状态

此时,可以看到,远端分支里,只有lisi这娃儿的分支状态有变化。此时,按照标准流程,李四需要在远程发起一个到develop的pull request。

发起pr

此时,是可以查看这次pr的内容,包括提交内容,文件修改差异。具体每个平台不一样,但是功能应该类似。

此时,假设经过代码review,认为没有问题,那么可以合并到develop去了。

合并后,develop的情况

可以看到,除了把lisi分支的commit拿过来了,还加了个表示本次合并的commit。

ok,李四的工作,第一阶段就算结束了。

模拟张三拉取李四代码

张三一看,李四这小伙子太快了,cv666。假设张三就依赖李四代码,此时,应该要把李四代码拉下来。

其实,这里有个操作上的问题,当前张三在自己的分支上,他现在需要做的是:拉取develop代码最新代码,然后将develop的代码合到自己这里来。

这个步骤的话,其实有些工具做得比较好,我用的intelj idea就有相关功能。这一步如果工具不趁手的话,非常要命。因为我们可能开发到一半,要去切换到其他分支,结果本分支有代码没提交,还得先提交或者stash,切过去到develop,pull最新代码。然后再切回来自己分支。

很累人。

这块回头我讲讲idea里面的实战操作,其他ide工具大家可以自行探索。

这次先只介绍命令行版本,我先用笨办法,切过去,pull,再切回来的方式吧。

模拟张三合并/rebase李四代码

要保证develop的commit保持线性,这里有个重点,我们要以rebase的方式去合并develop的代码,而不是merge的方式。

rebase呢,这里简单说下,

这里就是rebase的大体流程图,其实,我刚有个想法,最近拿起了以前的电视剧,新三国。里面吕布不就换了几位义父吗,这里的rebase,换的也是parent啊,感觉rebase也是相当神似。

当然了,忘了一点,进行rebase那些的commit,hashcode会发生变化,和以前不一样了。

我们这边实际操作,看看效果:

这里主要几个操作,

1 git rebase develop -------因为和lisi改了同一行,需要解决冲突
2 我这边习惯用小乌龟git,解决冲突
3 git add .
4 git rebase --continue

形象一点,也就是前面那个图,不过新的rebase后的commit的hash变了

模拟张三push代码到远端,远端发起pull request

push

pull req

远端develop log查看

可以看看,远程的develop分支,log是非常好看的。

第二轮开始

可以看到,第一轮已经差不多结束了,张三李四各提交了一次。假设现在轮到李四了,李四发现张三有push代码,就准备拉下来,就像之前的张三一样。

李四切换到develop,拉取最新develop代码,并rebase

然后,我们基于develop,进行rebase(也就是,以develop为base)。本来为了模拟效果,是应该先本地搞点提交,再rebase的,我搞忘了。不过不重要,过程和前面张三差不多。

李四修改代码、commit、push

李四远端发起pull request

检查远程develop分支的commit 记录

依然是漂亮的commit记录。

张三在此期间,已经做了修改、commit、push

张三这期间,暂时不依赖李四代码,就自己commit、push了(为啥push,怕代码丢嘛,多个备份)

张三切换到develop、拉取最新develop、rebase

张三此时终于准备合并李四的代码。

省略了张三这次解决了冲突的过程,我依然用了小乌龟。

张三此时的log情况

张三,由于rebase,导致自己本地之前的那次commit,被rebase了。rebase后,hashcode也变了。

此时,张三的本地分支,和张三远程分支之间,出现了分叉。

张三rebase后,面临分叉,强行push,覆盖远程分支

强制push后,张三远程分支的log

张三远程发起pull request

远程develop分支log,线性日志

总结

两轮实战结束。大家学会了没?

2点要点:

1、总是rebase的方式去合并develop分支

2、rebase的时候,就是会面临分叉的情况,此时强制push远程分支,让远程分支的log和本地一致。

git 多人在同一分支上迭代开发时,如何保证分支提交历史保持线性的更多相关文章

  1. 【IntelliJ IDEA】在idea上操作 git分支合并【如何将远程swagger分支 合并到 远程 master分支上】【如何切换 本地分支】

    ============================================ 明确一点: 如果项目交给git管理了[如何将项目交给git管理:https://www.cnblogs.com ...

  2. 解决mac上Android开发时出现的ADB server didn't ACK

    mac 上adb连接不到android手机可以参考:这里 xxxdeMacPro:~ xxx$ adb start-server * daemon not running. starting it n ...

  3. 解决Mac上Android开发时adb连接不到手机问题

    今天在Mac OS上进行Android开发的时候,打开eclipse连接不到手机MX4问题 1. 插入手机打开 Terminal,输入 system_profiler  SPUSBDataType 2 ...

  4. 上传文件时用form.submit提交的时候在低版本的IE中报拒绝访问的错误

    上传文件的时候,在IE7下总是传不了,但FireFox,IE11和Chrome下则可以上传.发现是form.submit();时出错了(“拒绝访问”). html代码为: <label oncl ...

  5. JavaScript中,返回上一个页面时,如何保证上一个页面的不刷新?

    history.back()和history.go(-1)都可以实现返回上一页并不刷新.History 对象包含用户(在浏览器窗口中)访问过的 URL. history.back() 等同于在浏览器点 ...

  6. git合并分支上的commit为一条commit到master

    标签: git 缘由? 有一次被人问到怎么把一个分支的所有commit按一个commit合并到主分支上,当时一脸蒙B,平时开发都是直接merge,很少考虑到这种问题,于是特意搜索了相关资料. 场景 其 ...

  7. git 将主分支的提交合并到分支上(主分支同步到分支)

    通常都会遇到将分支修改的内容合并到主分支中,但是在主分支中修改了内容怎么同步到分支上呢,这个时候需要将主分支上的提交操作在分支上再做一次: 1.首先在主分支上执行: git log 2.找到你想要同步 ...

  8. git多人协作--分支

    分支: 创建分支: git checkout -b 新分支 切换分支: git checkout 目标分支 删除分支: git branch -d 待删除分支 推送到远程分支: git checkou ...

  9. git将当前分支上修改的东西转移到新建分支

    比如我在A分支做了一些修改,现在由于某种原因(如A分支已经合并到master)不能把A分支上修改的东西保留下来但是需要把A分支上修改的东西继续在新分支继续修改.那么现在我们可以有两种简单的做法完成这一 ...

随机推荐

  1. java集合专题 (ArrayList、HashSet等集合底层结构及扩容机制、HashMap源码)

    一.数组与集合比较 数组: 1)长度开始时必须指定,而且一旦指定,不能更改 2)保存的必须为同一类型的元素 3)使用数组进行增加/删除元素-比较麻烦 集合: 1)可以动态保存任意多个对象,使用比较方便 ...

  2. PostgreSQL VACUUM 之深入浅出 (二)

    AUTOVACUUM AUTOVACUUM 简介 PostgreSQL 提供了 AUTOVACUUM 的机制. autovacuum 不仅会自动进行 VACUUM,也会自动进行 ANALYZE,以分析 ...

  3. CobaltStrike逆向学习系列(4):Beacon 上线协议分析

    这是[信安成长计划]的第 4 篇文章 关注微信公众号[信安成长计划] 0x00 目录 0x01 Beacon 发送 0x02 TeamServer 处理 0x03 流程图 0x04 参考文章 在上一篇 ...

  4. 金融行业BI可视化报表,直观体验数据的价值

    现在,数据已成为非常重要的资产.之前,人们只是把它当作一种附属品,由客户来办理业务,在系统中产生了这样的附属品.但如今,发现在客户办理业务这一信息中,蕴藏着一些客户的需求,积聚成千条这种信息,可以洞察 ...

  5. 都在用神器,只有你还在死磕excel做分析

    一.excel数据分析工具_EXCE弱点 EXCEL一直是非常流行的个人计算机数据处理工具,它可以处理多种多样的数据,操作非常简单,支持丰富的函数.统计图表,在工作中更是非常得力的生产力工具.然而随着 ...

  6. 【C# IO 操作 】Big-endian 和 Little-endian 详解

    首先,认识字节(Byte),计算机中Byte意思为"字节",8个二进制位构成1个"字节(Byte)",即1Byte=8bit,字节是计算机处理数据的基本单位.所 ...

  7. Qt:QWidget

    0.说明 QWidget类是所有用户界面对象的基类. QWidget是用户界面的原子类.它接收鼠标.键盘和来自系统的其他事件,并在屏幕上将它们绘制出来.每个Widget都是矩形的,并按照Z-order ...

  8. Qt:QDateTime

    0.说明 提供时间日期的表达和相关函数. QDateTime通过日期+时间来构造一个日期时间.它综合了QDate和QTime的所有特性. 它可以通过系统时钟来获取当前DateTime.它还提供了比较时 ...

  9. MATLAB神经网络应用设计【1】

    基于看到一个博客的大佬说自己学的东西太多了,很容易遗忘.我觉得我目前也出现这样的问题了,所以在这里开了博客,开始记录整理自己的学习之旅.   今天看了这本书的前几章,看这个书的目的是为了1个多月后的数 ...

  10. php简易表单及下拉框动态渲染

    <?php//1.连接数据库$link = mysqli_connect('127.0.0.1','root','root','1906');//2.设置字符集mysqli_set_charse ...