美文网首页
【iOS开发工程化——开发中】:源代码版本控制

【iOS开发工程化——开发中】:源代码版本控制

作者: 意一ineyee | 来源:发表于2022-06-04 18:30 被阅读0次

目录
一、Git简介
二、Git的一些基本操作
 1、安装Git
 2、配置Git全局用户名和全局邮箱
 3、创建本地仓库、创建远程仓库、本地仓库关联远程仓库
 4、代码重置revert
 5、节点阅读、分支和分支小标签阅读、创建分支和合并分支阅读
三、一些规范
 1、gitignore规范
 2、commit规范
 3、分支规范
 4、打tag规范

一、Git简介


Git和SVN的区别

Git是分布式版本控制系统,SVN是集中式版本控制系统。

所谓分布式主要是指本地仓库这个概念,也就是说我们每个人都可以在自己的电脑上通过本地仓库来进行源代码版本控制,它是去中心化的、不需要联网的;所谓集中式主要是指远程仓库这个概念,也就是说我们每个人都必须直接面向同一个远程仓库来进行源代码版本控制,它是中心化的、需要联网的。当然Git也有远程仓库这个概念,但它的远程仓库并非一个必要角色,而只是为了方便不同空间、多人之间的合作而扩展的一个辅助工具。

Git的分区

Git有工作区、暂存区、本地仓库、远程仓库四个分区,工作区--添加add-->暂存区--提交commit-->本地仓库--推送push-->远程仓库--拉取pull-->本地仓库。

工作区:项目目录下.git以外的部分,存储着我们的源代码。

本地仓库:项目目录下.git

  • 暂存区:存储着准备添加到版本控制的源代码;
  • 贮存区:存储着已经添加到版本控制的源代码。

广义的本地仓库由暂存区和贮存区两部分组成,但是为了方便描述,后面我们提到本地仓库时都是指狭义的本地仓库——即贮存区。

远程仓库:GitHub || GitLab || Gitee,本地仓库的一个云端备份。

Sourcetree里能看到工作区和暂存区,看不到本地仓库和远程仓库。

Git的文件状态

  • 紫色的?:只可能出现在工作区,代表我们新增了该文件、还未添加到版本控制 <==> 对应Xcode里的?——untracked
  • 绿色的+:只可能出现在暂存区,代表我们新增了该文件、准备添加到版本控制 <==> 对应Xcode里的A——added
  • 黄色的...:有可能出现在工作区或暂存区,代表我们修改了该文件的内容 <==> 对应Xcode里的M——modified
  • 橙色的!:有可能出现在工作区或暂存区,代表该文件里有冲突需要我们解决 <==> 对应Xcode里的C——conflicted
  • 红色的-:有可能出现在工作区或暂存区,代表我们删除了该文件 <==> 对应Xcode里的D——deleted

二、Git的一些基本操作


1、安装Git

安装SourceTree,Git也会被自动安装。

2、配置Git全局用户名和全局邮箱

配置Git全局用户名和全局邮箱,将来我们每次提交的“作者”就是“全局用户名 <全局邮箱>”了。

3、创建本地仓库、创建远程仓库、本地仓库关联远程仓库

创建本地仓库
  • 先创建一个项目
  • 创建好后,项目目录下就这俩文件
  • 为项目创建本地仓库
  • 目标路径选择刚才的项目
  • 点击创建后,就为项目创建好了本地仓库
  • 我们会发现项目目录下多了一个隐藏文件夹.git,它就是用来做源代码版本控制的本地仓库,如果我们想让项目脱离版本控制,只需要把.git删掉就可以了
  • 添加.gitignore文件,在项目目录下创建一个.gitignore文件,然后去gitignore.io这个网站搜索一个现成的.gitignore文件,把内容复制到我们创建的.gitignore文件里即可
  • 添加README.md文件,在项目目录下创建一个README.md文件,然后写一些关于该项目如何使用的指导即可
  • 此时把所有的文件都提交,做一次init commit
创建远程仓库
  • 远程仓库可以是GitHub || GitLab || Gitee,这里我们选择Gitee做演示。注意创建远程仓库的时候,创建一个完全空的仓库,不要勾选创建.gitignore文件和README.md文件,否则本地仓库关联远程仓库的时候容易出问题
  • 点击创建后,就创建好了远程仓库
本地仓库关联远程仓库

本地仓库关联远程仓库的方式有两种:HTTPS或SSH,它们俩的主要区别就是HTTPS直接用就行,但是后面每次拉取代码或推送代码都得输入GitHub || GitLab || Gitee的用户名和密码(存储到钥匙串好像就不用输入了),而SSH则需要先配置公钥和私钥后才能使用,以后随便拉取代码或推送代码,这里我们采用SSH的方式来演示。

  • 创建和配置SSH公钥和私钥

终端输入ssh-keygen -t ed25519 -C "ineyee@foxmail.com"(后面跟的是你的邮箱),然后连摁三次回车就完事了(期间不用输地址,会有一个默认的存储公钥和私钥的地址;期间不用输密码和确认密码,否则将来在推送代码和拉取代码的时候就得输密码)。

打开.ssh文件夹,就可以看到生成的公钥和私钥。

打开.pub公钥文件,把里面的内容全部复制下来。

打开Gitee,点击你的头像 --> 设置 --> SSH公钥,把复制下来的内容填进去,点击确定即可。

然后在终端输入ssh -T git@gitee.com(如果是GitHub || GitLab,则输入ssh -T git@github.com || ssh -T git@gitlab.com),因为首次使用需要确认并添加主机到本机SSH可信任列表,这就配置成功了。

  • 把远程仓库的SSH地址复制下来
  • 关联本地仓库

4、代码重置revert

工作区重置

工作区的内容,如果我们不想要了,可以采用工作区重置。

暂存区重置

暂存区的内容,如果我们不想要了,可以采用暂存区重置。

本地仓库重置

选中要重置到的某次提交,右键选择“将XXX重置到这次提交”。

  • 软合并(麻烦、一般使用混合合并代替;最终效果其实和混合合并一样,但是比混合合并少做了一步“暂存区 --> 工作区”的操作)

软合并是指我们重置到这次提交后,这次提交后面的提交记录还会给我们保存在暂存区,以备我们可能还会用到这些代码,如果用不到直接重置掉即可。

  • 混合合并(靠谱、常用;相当于软合并后,我们手动把暂存区的代码移动到工作区)

混合合并是指我们重置到这次提交后,这次提交后面的提交记录还会给我们保存在工作区,以备我们可能还会用到这些代码,如果用不到直接重置掉即可。

  • 强行合并(危险、慎用;相当于混合合并后,我们手动把工作区的代码重置掉)

混合合并是指我们重置到这次提交后,这次提交后面的提交记录全部抹掉、不会给我们保存在暂存区或工作区,我们就丢失掉这些可能还会有用的代码了,如果你非常确定这些代码你就是用不到了,再选择强行合并。

远程仓库重置

方式一、不推荐:完成了上面的本地仓库重置,我们可以通过本地仓库重置 + 强制推送的方式达到远程仓库重置的效果,但是这种方式会抹掉提交记录,在团队开发中是不推荐的。

方式二、推荐:推荐的方式是本地仓库重置两次(强行合并一次 + 软合并一次) + 提交、推送的方式,这种方式可以保留提交记录。

先把本地仓库重置到3,注意选择强行合并,以便本地仓库丢掉4、5、6这三次提交的代码,当然你也可以选择软合并或混合合并、然后再自己重置掉保存下来的代码,这样本地仓库就可以比远程仓库少掉不想要的代码了。

然后再把本地仓库重置到远程仓库当前所在的节点6,注意需要选择软合并,这样我们刚才删除4、5、6三次提交代码的操作就会被扔到暂存区了(如果想不通,可以这样想,代码多的那个节点往代码少的那个节点重置时,选择软合并是把多出来的代码——即增加代码操作扔到暂存区了;那代码少的那个节点往代码多的那个节点重置时,选择软合并是把少出来的代码扔到暂存区了——即删除代码操作)

此时我们做一次提交、推送操作,就完成远程仓库重置了。

5、节点阅读、分支和分支小标签阅读、创建分支和合并分支阅读

节点阅读

我们每一次提交都会形成一个节点,当前所在的节点用一个空心圆圈表示,以前的节点用一个实心圆点表示。

分支和分支小标签阅读
创建分支和合并分支阅读

master分支小标签是蓝色的,它对应的节点树就是蓝色的那条;dev分支小标签是粉色的,它对应的节点树就是粉色的那条。dev分支是从master分支的“重置:到3”节点处创建出来的,提交了三次,然后就合并到了master分支(注意:Git会自动帮我们把dev分支的多次提交合并成一次“Merge brach ‘xxx’”的提交合并到master分支),合并分支完成后master分支就会落到“Merge brach ‘xxx’”的这一次提交节点上。

三、一些规范


1、gitignore规范

忽略精确的文件:Extra.txt;忽略所有后缀为此的:*.dll;忽略某个文件夹下所有的文件:abc/

我们项目里的.gitignore文件通常都是去gitignore.io这个网站搜索一个现成的.gitignore文件,把内容复制到我们创建的.gitignore文件里,不过复制完后还有几点需要注意:

  • .gitignore文件本身不能忽略,要加入版本控制,保证每个开发者忽略的东西都一样。不过这个我们不用动,.gitignore文件模板本来就没忽略.gitignore文件;
  • README.md文件不能忽略,要加入版本控制,保证每个开发者读到的东西都一样。不过这个我们不用动,.gitignore文件模板本来就没忽略README.md文件;
  • xcuserdata文件夹得忽略,不要加入版本控制,它里面存储的是每个开发者Xcode的一些情况,如Xcode的目录展开情况、Xcode里面打的断点等,这些东西大家没必要共享。不过这个我们不用动,.gitignore文件模板本来就忽略了xcuserdata文件夹;
  • project.pbxproj文件不能忽略,要加入版本控制,它里面存储的是项目里源文件的描述信息,如我们新增了一个文件、移动了一个文件的目录、重命名了一个文件等,这些东西大家需要共享。不过这个我们不用动,.gitignore文件模板本来就没忽略project.pbxproj文件;
  • project.xcworkspce文件不能忽略,要加入版本控制,它对应于project.pbxproj文件、存储的是工作区源文件的描述信息;
  • Pods文件夹得忽略,不要加入版本控制,它里面存放的是所有三方库的源码文件,我们一般不把它放到版本控制里,是为了避免不同分支依赖了不同版本的三方库、进而导致在分支合并时的冲突,而是把Podfile和Podfile.lock文件加入版本管理,团队其他人员拉取代码后得执行一下pod install项目才能跑起来。这个需要我们去.gitignore文件里打开/Pods的注释,.gitignore文件模板默认是没忽略Pods文件夹的。

2、commit规范

格式:type: content
例如:feature: 新增JS弹窗功能bugfix: 修复JS弹窗bug

1️⃣类型type

  • feature:新增xxx功能(常用)
  • bugfix:修复xxxbug(常用)
  • test:测试xxx功能(常用)
  • build:依赖项的修改,例如Podfile文件的修改等(常用)
  • chore:不修改源代码的其余修改,例如调整文件目录顺序等(常用)
  • docs:变更xxx文档
  • style:变更xxx代码格式或注释
  • refactor:重构xxx功能或方法
  • revert:重置到xxx(常用)

2️⃣内容content

末尾不要加.标点

3、分支规范

创建分支规范

1️⃣release分支

  • 发布分支或者叫线上分支
  • 作用:它是一个专门用来做发布的分支,其它任何操作都不要在该分支上进行,以保证线上包的稳定,该分支上的每一个tag都对应一个线上版本
  • 对于该分支的唯二操作:准备发布App时,把master分支合并到该分支,在该分支上打包发布App打tag

2️⃣master分支

  • 主分支或者叫预上线分支
  • 作用:它像是一个feature分支/bugfix分支和release分支的中转分支,前两者把代码合并到它身上,它又把代码合并到后者身上,从而起到了保护线上分支的作用,避免了直接往release分支上合并代码可能导致的错误
  • 对于该分支的唯四操作:从它身上拉feature分支/bugfix分支feature分支/bugfix分支把代码合并到它身上它把代码合并到release分支身上在该分支上跑debug包调试、打release包供测试做回归

3️⃣feature分支

  • 功能分支
  • 开始:当开发一个新功能时,从master分支最新的节点处(为了减少将来合并分支时的冲突)拉一个feature分支出来,分支名为feature/功能描述,例如我们要开发一个点赞功能,分支名可以命名为feature/add_like_button
  • 过程:新功能都在该分支上开发,开发完成后,测试需要先在该分支回归
  • 结束:该分支回归完成后,合并到master分支,master分支再次回归完成后,合并到release分支,release分支上线后,即可删除该功能分支

4️⃣bugfix分支

  • 修复 bug 分支
  • 开始:当修复一个bug时,从master分支最新的节点处(为了减少将来合并分支时的冲突)拉一个bugfix分支出来,分支名为bugfix/修复bug描述,例如我们要修复一个用户头像的UI bug,分支名可以命名为bugfix/fix_avatar_ui_bug
  • 过程:bug都在该分支上修复,修复完成后,测试需要先在该分支回归
  • 结束:该分支回归完成后,合并到master分支,master分支再次回归完成后,合并到release分支,release分支上线后,即可删除该修复bug分支
合并分支规范

1️⃣master分支保护和合并请求(PR/MR,Pull Request/Merge Request)

为了减少事故的发生,我们一般会做master分支保护,不允许开发者直接往master分支上推送代码。

而是让开发者在需要合并其它分支到master分支时提交一个合并请求,项目管理者收到合并请求后把经过code review的代码合并到master分支上。

建议开发者在提交合并请求之前,先把master分支的代码合并到feature分支/bugfix分支,看看代码是否有冲突,有冲突的话优先在feature分支/bugfix分支上解决掉,这样可以保证开发者的分支在合并到master分支时没有冲突。

2️⃣普通合并和变基合并

想保留提交记录就用普通合并,不想保留提交记录就用变基合并rebase。

普通合并:Git会自动帮我们把dev分支的多次提交合并成一次“Merge brach ‘xxx’”的提交合并到master分支,dev分支的提交记录会被记录在提交历史上。

reabase:Git不会帮我们把dev分支的多次提交合并成一次统一的提交,而是直接把dev的几次提交平移合并到master分支,dev分支的提交记录不会被记录在提交历史上,就像我们是直接在master分支上修改的一样。

4、打tag规范

每当release分支上线后,我们都会给release分支打一个和线上版本号一致的tag并推送到远程仓库,这样方便我们查看版本、追踪问题。

版本号一般由四个部分组成:MAJOR、MINOR、PATCH、BUILD。

  • MAJOR是指主版本号,通常在重大更新的时候才会需要更新主版本号。例如iOS每年都会更新一个主版本号;而对于第三方库来说,主版本号的更新,表示该库的API新增了重大功能,或者引入了不可兼容的更新。

  • MINOR是指副版本号,用于小功能的改善。例如iOS14在发布主版本后,在一年内可能发布多个副版本如14.1、14.2来完善其系统功能;而对于第三方库来说,副版本号的更新就是新增一些API,但不包含不可兼容的更新。

  • PATCH是指补丁版本号,一般用于bugfix以及修复安全性问题等。对于第三方库来说,补丁版本号的更新也不应该有不可兼容的更新。虽然实际操作中这会有些困难,但我们可以通过把原有 API 标记为 deprecated,或者为新API参数提供默认值等办法来解决。

  • BUILD是指构建版本号,通常在内部测试时使用。一般当我们使用CI服务器进行自动构建时,构建版本号会自动更新。

第一次打tag 重大更新或者引入了不可兼容的更新,修改MAJOR 小功能的改善,修改MINOR 修复bug或安全问题,修改PATCH 远程仓库查看tag

相关文章

网友评论

      本文标题:【iOS开发工程化——开发中】:源代码版本控制

      本文链接:https://www.haomeiwen.com/subject/xeqlmrtx.html