Git操作指南: 企业级项目分支管理流程 - SourceTree Mac 版

3,786 阅读14分钟

改不完的 Bug,写不完的矫情。公众号 杨正友 现在专注移动基础开发 ,涵盖音视频和 APM,信息安全等各个知识领域;只做全网最 Geek 的公众号,欢迎您的关注!

发现每到一家公司,公司的管理流程都差距甚远,大的互联网公司注重细节和内部实现,代码质量要求简直就是苛刻,新员工<review code + 导师 >是少不了的,每写一行代码,非得说清楚里面原理是什么?为什么要这样写,是不是用啥设计模式会更有拓展性一点,业务文档和技术文档也是强制性的,各种流程像流水线办公类似,一个细节出问题,影响的就是整个发版,复杂的需求可以划分为多个需求id,然后每个人只负责自己的小需求模块即可,小团队的话则更注重整体业务把握,基本上搞透一个点,做着做着就得梳理之前的业务流程,刚好国庆挤了点时间把git总结了一下,然后再逐步分析一下企业真实的git管理是怎么样的,希望对职场的你有所帮助。

Git 和 SourceTree的安装就不用多说了,网上入门教程很多,我们直接从怎样克隆一个新项目到本地开始说

1. git clone project

git init命令创建一个空的Git仓库或重新初始化一个现有仓库。

git init 
git clone

1.1 从远端上clone项目

1.2 clone成功后的界面

1.3 本地文件变化

1.4 打开我的新 project 展示页面

project

1.5 切换到“日志/历史”面板

1.5 切换到本地master分支

2. 修改 / commit 新项目

2.1 在本地仓库目录下,新建一个 workmanager.md 文件

2.2 在sourceTree的"日志/历史"面板中,查看

2.3 提示你有新的未提交的改动。切换到'文件状态'面板

2.4 改动的文件加入暂存stage、不暂存unstage、提交等选项

  • 工作区

  • 版本区
    • 工作区中有一个.Git的目录,通常这是一个隐藏目录。前面已经说过这个文件夹,表示它所在的目录是Git管理的仓库。这个文件夹下,存放就是Git的版本库信息,这就是Git的版本库
  • 暂存区
    • 打开.git目录,Git版本库中有许多文件,其中最重要的就是称为index(或者stage)的暂存区,还有HEAD指针。而其他分支等信息存放在refs文件夹中。
    • 我们存放修改的地方,所有的修改都必须缓存到这里。当我们执行提交命令时,实际上就是把暂存区的内容提交到HEAD对应的分支上。
    • 初始时,暂存区应该是空的,当我们把内容提交到暂存区之后,就像上面这样,暂存区有了内容才能执行commit命令。
    • 提交之后,暂存区会被清空,等待下一次的暂存和提交。
  • HEAD指针
    • Git只是指针的移动,那么Git的指针到底是什么,它到底如果移动的,HEAD指针指向的是我们当前所在的分支
      • git的每一次提交都会把他串成一条线,这条线是一条时间线,一条时间线就是一条分支。
      • 一开始时,我们只有一个master分支,也只有一条时间线,所以,我们的HEAD指向master,然后master又指向我们的提交线。
      • HEAD指向的并不是提交,而是指向分支,master才是指向提交的,所以,HEAD指向的就是当前分支。由此可见,HEAD和master其实都是指针
      • 当有新提交时,时间线节点增加一个,master向前移动一步,然后HEAD也会跟着移动
      • 当创建新分支dev时,实际上是新创建了一个dev指针,但是,dev是从master分出去的,所有,初始时,dev和master在同一个节点
      • 它的指向信息我们是看不到的,但是可以通过sourceTree项目列表中,该项目名称下的分支信息来查看当前HEAD指向的分支,HEAD指向了dev。
      • 创建新分支后,HEAD指向了新分支,这时候的提交操作,就对应dev了
      • 在dev上的提交,仅仅只是dev向前移动了一步,而master还在原来的地方没动
      • 我们的合并操作又是怎么办的呢?
        • 合并操作,其实仅仅只是把master指向了dev当前所在的提交,这还是一个指针移动过程。

          • git的合并同样非常快速,工作区的内容没改变(其实只有很小的改变,因为要切换回master操作,这会使文件发生一些改变),然后就是指针的移动而已

          • 删除分支,也非常简单。仅仅只是指针的移除,没有文件系统的改变。删除分支后,已经合并的master分支并没有任何影响,仅仅只是指针的移除。

2.5 提交成功后,“文件状态”面板又恢复干净了。此时切换到“日志/历史”

  • 只有加入暂存区的修改才会被提交,因为Git管理的是修改。比如,你先做了第一次修改,然后加入暂存区,接着做了第二次修改,但是第二次修改没有加入暂存区,这时候如果提交,那么你提交的只会是第一次修改的内容

    • 因为Git只是把你第一次放入暂存区的内容情况,而你第二次的修改并没有在暂存区内。要把第二次修改也提交,请重新暂存并提交。
  • 我们提交成功,仅仅只是向本地的仓库提交成功了,不信你可以去远程仓库看看有没有最新的提交信息。本地仓库,我们只能在本地玩,虽然也能进行版本管理,但是别人看不到,我们还需要推送到远程仓库,让别人也能看到

3. create 我的 Dev 分支

3.0 创建分支的本质

  • 创建一个新分支是多么的简单,仅仅只是创建一个新指针,HEAD改变下指向,没有文件的拷贝,所以,它在1s内就能完成新分支的创建

  • master分支有BUG时,从master新建一个临时temp分支,在temp修复BUG,然后合并到Master分支,master继续发布

  • 修复的BUG再合并到Dev分支,这样也保证Dev分支上的代码是稳定的。最后再删除temp分支

3.1 如何创建分支?

  • 新分支与被分支的那个分支(这里的master)所处的状态是一样的
  • 创建新分支后,SourceTree(Git)会默认把HEAD指向新创建的分支,并且新分支与原来的分支所处的状态一样
    • 如果要切换分支,只需要在需要切换的分支上双击即可。这比使用Git命令切换分支要快很多。然后把Dev分支推送到服务端。
    • 推送成功后,在sourceTree远程选项的origin中,就会多了一个Dev分支,表明服务端也已经有了Dev分支

3.2 如何切换分支?

  • 如果我们还未提交就切换到其他分支,这种修改也会带到其他分支的。直接双击master分支
  • 我在Dev分支的修改还没提交。就是不管有没有加入暂存区,只要还没commit,那么这种修改在切换分支时,就会带到其他分支
  • 我们在切换分支前,要确保修改已经提交或者栈存

4. 合并分支

4.1 如何合并分支?

合并分支要到目标分支上去操作,比如我们要把Dev分支上的修改合并到master分支,那么我们就要到master分支上去操作

合并完成后,我们可以检查master分支下的文件,它已经与Dev分支下的修改一样了。然后将master分支推送到服务端 这里我的Dev分支我始终没推送到服务端。这只是为了说明,我们在本地的修改是可以不提交到服务端的,这就是我们通常利用分支来修复Bug和开发新功能的方式 实际情况中,我们的Dev分支还是应该要提交服务端的,因为大家都在Dev分支中工作,而你从Dev分支出去的其他本地分支,是不应该提交到服务器的

4.2 分支管理规范要求

4.2.1 master /develop

  • 不要删除,覆盖,不要重命名常驻分支(分支*master,分支*develop)

4.2.2 master

  • 不允许分支#master上直接提交,允许其他分支#合并到分支#master
  • 合并到分支#master的是已发布的代码(提示:发布前需要进行测试)
  • 不允许分支#master上直接合并到其他分支。
  • 允许分支#master创建新分支

4.2.3 release

  • 发布版本时,从分支#master创建新分支#release/x.x.x(新分支#release/[版本号],例如 release/1.0.0)
  • 允许已完成的待发布功能(已通过测试的),合并到分支#release
  • 发布版本完了,合并到分支#master, 分支#develop

4.2.4 新增

  • release打包之前,询问本组所有开发,确认需要发布的代码是不是准备好了(合并,删减,修改等)
  • release打包之后,通知相关人员进行测试,并描述本次发布的内容(新增功能,删减,修复BUG,优化性等)

5. 发布新版本

  • 5.1 master合并完之后,就可以发布新版本了,我们使用tag标签来表示版本。

  • 5.2 Tag其实跟分支类似,只不过它是从某一个提交处建立的一个指针副本,因此它不能进行移动,但是可以添加多个tag,也可以删除

  • 5.3 标签也可以推送到远程端

  • 5.4 点击确定之后,在服务端查看版本信息

  • 5.5 分支*master标签使用

    • 执行relase发布成功合并合后,在当前发布版本打入TAG(TAG命名规范:[版本号])
  • 5.6 Git上开发一个功能A,B并发布版本的流程:

      1. master分别拉一个功能分支A和分支B
      1. 分别在分支A、B开发功能,开发完毕后分别在分支A、B进行单元测试
      1. 功能分支A、B分别做完单元测试后分别将其合入到develop里做集成测试
      1. 有新版本要发布,从master稳定分支中抽出一个release分支作为打包发布分支
      1. 此时可能有四种需求:

      2. 此版本中只需包含一个功能A或者B,这种情况将功能分支A或者B合到Release中做最后的打包发布测试,测试完成后发布。

      3. 此版本既要包含功能A和功能B,将分支A和分支B都merge到release分支里做最后的打包发布测试,测试完成后发布。

      4. 版本发布完成后将release分支分别合并到master和develop

      5. 删掉此时的release分支和已发布的功能A分支或B分支或者AB两分支

  • 5.7
    两段式版本号规范 版本号(Version Name)由3段数字构成,用2个点隔开,分别代表 主版本号,次版本号,编译版本号,例如1.1.0,如下图所示:

  • 主版本号:App相对有比较大的功能更新时+1,比如添加了一些重大的新功能。

  • 次版本号:App日常版本更新时+1,注意BugFix不用更新小版本号。

  • 编译版本号:打包机每次构建打包+1,保证每个构建包的唯一性,方便定位和排查问题。

6. 贮藏和修复Bug

  • 6.1 修复Bug的情况,一般出现在对已发布的版本进行Bug修复。也就是对master分支进行Bug修复。

  • 6.2 一般的情况是我们工作在Dev分支,然后要切换到master分支进行Bug修复。

  • 6.3 前面提到过,在切换分支时,要确保该分支已经提交。如果当前Dev分支可以提交,无疑是最好的选择,但是,如果当前不能提交,就需要用到贮藏功能了

    • 那么问题来了?怎么贮藏呢?
  • 6.4 贮藏后该工作取件就变得很干净了,可以放心切到其他分支呢

  • 6.5 现场贮藏之后,如何恢复

  • 6.6 贮藏功能分类

    • 6.6.1 文件未暂存
      • 此时 text.txt 还没有被 Git 跟踪管理,所以它默认不会被贮藏
      • 从而一直留在文件系统中。如果我们切换到 maste r分支
      • 这个更改(添加新文件也是更改)会被带到 master 中
    • 6.6.2 文件已暂存
      • 作用
        • 为了避免这个文件在master中会被误提交,从而使该文件出现在不应该出现的版本中
      • 删除文件操作也需要加入暂存区才能贮藏现场
    • 6.6.3 保留暂存区
      • 贮藏现场时,如果勾选了 保留暂存的更改 选项,那么已经加入暂存区的内容都会被保留

    • 并且在切换分支时,暂存区的内容也会被带到其他分支去。从而其他分支也能看到所做的更改

  • 6.7 master分支进行Bug的修复

  • 6.8 分支hotfix原则

    • 修复BUG时,从分支#master创建新分支#hotfix/x.x.x(新分支#base/[版本号.BUG号],例如 base/1.0.2)
    • 修复BUG完了,合并到分支#master, 分支#develop

7. 多人协作

7.1 Git代码提交规范

  • 提交代码需仔细review编写的所有代码
  • 提交测试前需按照测试用例充分自测
  • 多线程数据读写必须注意线程安全,该加锁的加锁,尽量使用线程安全的容器
  • 同分支代码更新强制要求使用,Rebase,,以保持分支整洁。推荐用,AndroidStudio,自带版本控制工具避免出错。
  • 分支之间的合并应该使用,Merge,,以保持有完整的合并记录。
  • 避免低级空指针错误
    • java代码对象使用需判空
    • java调用kotlin定义的函数,传参需注意是否可为空
  • 遵循,Alibaba Code Guide, 代码中尽不要出现拼写错误,IDE遇到错误单词会警告,如出现警告要及时纠正,避免代码阅读困难
  • Bugfix版本原则只能修改bug相关的内容,不允许随意增加需求或者修改内容,修bug要找出bug的真正原因,避免为了修bug而引入新的问题

8 解决冲突

解决冲突不建议使用自带的diff工具,我们可以使用AndroidStudio自带的工具或者使用ByondCompare来处理

9 版本回退

10. 换行符兼容

11 撤销修改

  • 什么时候会用到sourceTree(Git)的撤销修改

12 其他操作

13 Git企业分支清理基本原则

  1. 定期做删除无用分支操作.
  2. release分支一律保留,但是前提是需要统一命名规范.
  3. 已经merge过的分支过一个月后可以删除.
  4. merge的分支过三个月征求分支创建者同意后可以删除.
  • 对分支创建者的补充:
    • A、如果是release/bugfix这样的公用分支,可以不带有个人属性名称.
    • B、如果是个人功能这样的分支的创建,统一带需求ID名称,例如: 031004
    • C、如果无法确认分支创建者,须在群里沟通以确认是否可以删除再做定夺(如无人认领分支,则由清理人员自行定夺是否删除).

14 从SVN迁移到Git

  • SVN迁移到Git,不仅需要源代码迁移,同时我们还希望SVN上commit信息也能迁移。这里我们使用Subgit工具。
    • 自上次提交后,你对源文件做了很多修改,你想一步就退回到初始状态,就是上次提交之后的状态

15 Git 管理历史

15.1 本地版本控制系统

15.2 集中管理控制系统

15.3 分布式控制系统

16 Git 和其他SVN的区别

  • 16.1 一个集中控制,一个分布式;近乎所有操作都是本地执行;
  • 16.2 直接记录快照,而非差异比较;
  • 16.3 Git分支使用非常方便;
  • 16.4 Git 一般只添加数据;一旦你提交快照到 Git 中,就难以再丢失数据,特别是如果你定期的推送数据库到其它仓库的话;

17 Git 常用命令流程图

18 Git 文件状态

你的 点赞、评论、收藏、转发,是对我的巨大鼓励!