前语

咱们好,我是加权,在37手游负责安卓SDK业务。

本文旨在介绍在作业中运用git的一些经历,让初学者能够快速理解和运用git,不会触及深邃的指令和冷门操作。希望对咱们有协助。

运用Git的意图

咱们网上随意一搜就能查到git的各种优势,我就不仿制粘贴了。

实践作业中,对我最有协助的几点是

  1. 答应我犯错,能够吊销操作,康复代码
  2. 完好的代码记载,能够了解项目代码的发展过程
  3. 分支的办理协作,防止代码紊乱

而我运用git的底子意图在于,让我的项目时刻保持在一个明晰,便于保护的状态。所以我每做一个操作,都会考虑下,这样做是否能够合理。

接下来,咱们有必要先介绍下git的几个有必要知道的概念。

基本概念

作业区域概念

  1. 作业区
    1. 工程下git办理的一切文件默许都在作业区
    2. 作业区的文件你能够随意玩,十分安全
    3. 作业区的改动经过add指令增加到暂存区
  2. 暂存区
    1. 暂存区是寄存提交前的内容的当地,需求细心留意进入暂存区的内容是否是你想要的
    2. 暂存区的内容能够提交(commit)到本地库房
  3. 本地库房
    1. 提交到本地库房后,改动就会记载在案,能够针对提交记载做二次操作
    2. 提交后,二次处理提交记载时需求当心,由于操作错误后需求更杂乱的办法才能够康复,乃至不能康复
    3. 本地库房能够推送(push)到长途库房,能够拉取(pul)长途库房的内容
  4. 长途库房:
    1. 公司代码的大本营,除了拉取代码(pull)是绝对安全,其他指令都要三思
    2. 一般状况下都会对长途库房做权限办理,防止错误操作做成无法挽回的问题

Git实践根底共享

操作对象概念

  1. 分支(branch)
    1. 创立分支等同于创立副本,在分支内做任何操作都十分安全,不会影响主版本
    2. 一般,一个需求会对应一个分支
    3. 大部分分支都是“消耗品”,兼并后会删去
  2. 头(HEAD)
    1. 是一个特殊的指针,指向你当时所在的提交上,一般来说都是指向某个分支的最新提交上,可是也能够独自指向某个提交
    2. 一般是不需求特别留意,可是做任何提交前,应该都要留意当时的头在哪里,保证操作正确
  3. 提交(commit)
    1. 当把暂存区的内容提交(动词)到库房时,就会发生一个提交(commit,名词)
    2. 一个commit会有一个仅有的sha值,经过这个sha值就能够找回内容
    3. commit是单个操作的最小单元,大部分的二次操作都是针对commit的
    4. 在主分支上的commit能够说是不朽的
    5. 不在主分支上的commit,大部分时分,只需知道sha值也能够康复
  4. 标签(tags)
    1. 用来标记commit
    2. 常见用来标记发版节点

操作概念

  1. 检出(checkout)
    1. 切换、创立分支
  2. 提交(commit)
    1. 把暂存区的内容提交到库房
  3. 推送(push)
    1. 把本地库房的内容推送到长途库房
    2. 一般都是推送单个分支
  4. 拉取(pul)
    1. 把长途库房的内容拉取到本地库房
    2. 需求留意,一些git东西(如source tree),能够跨分支拉取,有或许发生其他附带操作(如兼并、变基)
  5. 获取(fetch)
    1. 拉取长途库房的信息,不会对分支发生影响
  6. 兼并(merge)
    1. 兼并是针对分支操作的
    2. 兼并有几种形式,需求留意的是快速兼并不会发生commit,类似于直接仿制分支,实践作业中,兼并需求分支时禁用快速兼并,强制发生commit会比较好
    3. 兼并是有方向的,A merge B是把B分之兼并到A分支,发生的commit会在A分支上
  7. 变基(rebase)
    1. 变基是针对分支操作的
    2. 简略地说,变基便是调整分支上的第一个commit的开端方位
    3. 变基的高阶操作,能够调整分支上任意一个commit,这一个功用对收拾代码十分有用
  8. 遴选(cherry pick)
    1. cherry pick是针对commit的
    2. 能够理解为仿制代码,一般是用来仿制其他分支的commit到当时分支
    3. cherry pick对commit的细化程度有要求,假如commit内有剩余的代码,一般就比较难直接cherry pick
  9. 回滚(revert)
    1. 提交一个commit的反操作,来消除commit
    2. 最合适的场景是,经过revert来移除一个现已兼并的功用,抵挡重复修正需求的产品经理的神器
  10. 重置(reset)
    1. 把分支重置到某个commit,相当于吊销操作
    2. 留意,重置后,分支上的记载,乃至暂存区的内容,都会消失,因此需求当心操作

常用的概念基本便是这些,百看不如一练,接下来看看在实践场景中会用到哪些操作吧。

场景0:张三入职第一次拉工程

#0x00:拉工程

git clone xxxxx.git

信任聪明的咱们都会了,不在赘述

#0x01:设置用户

有时分会漏了这一步,这样咱们有或许看不出这代码是张三写的,那么想让他背锅的时分就比较费事~所以得让张三设置下用户特点。

git config user.name zhangsan
git config user.email zhangsan@gmail.com

假如是张三自己的电脑,他也能够是设置大局特点,那么就不必每次都设置了。

#0x02:拉取最新分支

一般clone库房后,默许拉取的是master分支,张三需求承认下工程的分支标准,然后拉取最新的分支

git checkout dev
git pull

至此,张三就在本地有了最新的代码了他能够开端搬砖了

场景1:新使命

现在需求来了,咱们给张三分配个需求,验下货,就给他做个登录界面吧。

那么张三就要先拉取最新的dev分支,如上一步,那么此刻张三是在dev分支上了。

#0x00:创立分支

要新开使命,所以张三需求新建分支,分支称号假如能表现需求的话,在后续的处理上会有协助,所以咱们以fea前缀表明功用,login表明登录需求,创立一个fea-login分支。

git checkout -b fea-login

关于分支的标准各个团队或许不同,可是应该至少能够经过分支名区别出一般需求(feature)、更新功用(update)、移除功用(remove)、bug修复(bugfix)等类型,以便在分支兼并或许回忆时快速知道分支的内容。

#0x01:提交代码

张三一顿操作之后,创立了几个新文件,此刻他想先提交一次。

那么首先经过add指令,增加想提交的内容到暂存区

git add --all

这一步经过GUI东西会更加简单,比方sourceTree

Git实践根底共享
经过GUI能够明晰看到暂存区的状况,能够按行或许按区块增加改动到暂存区,比敲指令更不简单犯错。

增加代码到暂存区后,张三能够提交代码了。

为了提交记载的可读性,咱们要求张三每次提交时需求写上能表现提交内容的信息

git commit -m 'a-增加登录文件'

关于提交信息,信任各个团队有自己的标准和要求。我自己习气在提交信息前增加前缀来表明这个提交的首要作用,是新增代码(a),修正代码(m),修复问题(f),移除代码(rm),测试代码(ta/tm),还是无关重要的文本优化(o)。这个习气对我回忆提交记载时有很大协助,咱们能够参考下。

又经过一顿操作,张三总算搞定了,他预备推送分支到长途库房,好让咱们兼并分支了。

// 首次提交
git push --set-upstream origin fea-login
// 一般提交
git push

到目前为止张三表现不错,看看接下来怎样~

场景2:李四更新了远端分支

就在张三预备承认推送之前,李四告知张三,由于他开发的功用有部分也触及登录模块,现已提交兼并到dev了,有或许会影响张三的功用,所以让张三留意下,防止发生抵触。

其实这里不一定要张三处理,不过张三第一天来,还是多干一点好好表现吧。

所以张三切换回dev分支,重新拉取了dev的代码

git checkout dev
git pull

由于改动的内容比较多,张三也不承认自己改动的代码会不会和现在的dev抵触,这时张三能够挑选经过变基来承认是否有抵触

// 先切换回作业分支
git checkout fea-login
// rebase到最新的dev上
git rebase dev

运气不错,顺利完成了变基,张三承认自己的代码不会和dev发生抵触,能够推送到长途库房了。这样在兼并分支时,必定不会有抵触发生。

经过变基操作,咱们的分支能够好像在最新的代码的根底上开发相同,假如代码有抵触,也能够得到明晰提示,在这个场景下相当有用。

可是需求留意,rebase实践会发生新的commit,和原本的分支的提交记载会有较大差异,所以假如现已推送过到远端,则需求当心操作!

场景3:兼并功用提测

张三和李四都开发结束,现在能够兼并提测了,首先介绍下兼并的fast-forward概念

当时分支兼并到另一分支时,假如没有分歧解决,会直接移动文件指针,这个过程便是fast-forward

这样兼并后的作用相当于一直在主分支上开发,被兼并分支不存在。

这样虽然看起来整个分支树会很简洁,可是在多人合作的场景下并不好,由于今后回忆的时分就好像张三直接在主分支开发了登录功用,假如都运用这种形式兼并的话,很简单就无法区别功用分支了。

所以,在兼并分支时,我更加倾向经过no-ff参数禁用fast-forward,强制发生一个新的merge commit,这样分支兼并就很明晰了。

所以张三需求做的是

// 先切换回dev上
git checkout dev
// 保证代码最新
git pull
// 兼并作业分支
git merge --no-ff fea-login
// 推送到远端
git push

这样就完成了能够提测了

一般提测或许还需求新增版本号,这时张三也能够直接在dev分支上新增版本号后再提交构建。

总结

至此,张三现已能够正常处理日常的开发需求了,回忆下几个重要点

  1. 一个功用应该一个分支,而且分支称号应该契合标准
  2. 提交代码应该把控好“颗粒度”,而且应该填写契合标准的提交信息,方便review
  3. 推送分支代码前,应该先查看是否和远端有抵触,可经过rebase来处理,假如现已推送过远端需求当心操作
  4. 兼并分支应该运用no-ff禁用fast-forward,发生兼并commit

以上便是本文共享的全部内容了,下一篇文章咱们再来共享下更多git操作。

欢迎咱们在评论区说出git操作的一些问题,一同讨论~