Git 教程

 

前言

工作区(Working Directory)

暂存区(Stage)

版本库(Repository)

远程仓库(Remote)

1. Git 分支规范

1.1 分支类型

分支类型基于Git Flow规范,并做了简化。

功能分支(feature) 紫色

发布分支(release) 黑色和红色

修复分支(hotfix) 灰色

主分支(master) 绿色

 

1.2 分支命名

类型 规则 备注
功能分支 feature-* 以功能或上线日期为准
发布分支 develop dev环境发布分支
发布分支 test/sit 测试环境发布分支
发布分支 release* 预发布和生产发布分支, 默认release,多版本并行可release1, release2
修复分支 hotfix-* 已修复问题命名
主分支 master 保护分支,一般发布完生产需要合并到master

 

1.3 分支合并

该图的原型为git flow, 原作者为Vincent Driessen

  1. 公共发版分支,是供给多版本有交叉提测时段时,针对某一环境发版专用的环境发版分支。
  2. 公共发版分支,必须是单向合并,严禁反向污染。 (gitlab线上合并,有冲突时禁用)
  3. release生产/预发布发版分支open in new window,由业务线组长或该版本负责人,统一集中合并。
  4. 公共发版分支维护统筹,由各业务线组长负责;
  5. 跨业务线开发,需要发布环境时,需主动联系该业务线负责人,说明版本计划、时间、公共包版本等,沟通清楚无异议后方可使用
  6. 严控版本Tagopen in new window,每次发版后,需业务新建tag入口组长或功能主开发进行操作,格式如下: 生产版本: Tag-YYYYMMDD版 (日期为发版日期) 修复版本: Fix-YYYYMMDD版 (日期为修复日期)

 

2. Git 提交规范

本节由alan提供。

commit message format(信息域) commit message 一般分为三个部分 Header,Body 和 Footer

<type>(<scope>): <subject>
// 空一行
<body>
// 空一行
<footer>

2.1 HEAD

type 用于说明 commit的类型,允许以下标识:

类型 描述
feat 新增功能
fix 修复 bug
docs 文档变更
style 不影响代码运行的变动如:样式调整
refactor 重构(既不是新增加的 feature,也不是修复 bug)
pref 性能优化
test 增加测试如:测试代码
chore 构建过程或者辅助功能的变动
revert 版本回退
build 打包

2.2 BODY

本次commit的内容描述

本次commit存在不兼容变动或者关闭的 issue

2.4 注意事项

1:每个提交都必须使用类型字段前缀,它由一个名词构成,诸如 feat 或 fix , 其后接可选的范围字段,可选的 !,以及必要的冒号(英文半角)和空格。
2:当一个提交为应用或类库实现了新功能时,必须使用 feat 类型。
3:当一个提交为应用修复了 bug 时,必须使用 fix 类型。
4:范围字段可以跟随在类型字段后面。范围必须是一个描述某部分代码的名词,并用圆括号包围, 例如: fix(parser): 描述字段必须直接跟在 <类型>(范围) 前缀的冒号和空格之后。 描述指的是对代码变更的简短总结,例如: fix(doc): update ref doc
5:在简短描述之后,可以编写较长的提交正文,为代码变更提供额外的上下文信息。正文必须起始于描述字段结束的一个空行后。
6:提交的正文内容自由编写,并可以使用空行分隔不同段落。
7:在正文结束的一个空行之后,可以编写一行或多行脚注。每行脚注都必须包含 一个令牌(token),后面紧跟 : 或 # 作为分隔符。
8:脚注的令牌必须使用 - 作为连字符,比如 Acked-by (这样有助于 区分脚注和多行正文)。有一种例外情况就是 BREAKING CHANGE,它可以被认为是一个令牌。
9:脚注的值可以包含空格和换行,值的解析过程必须直到下一个脚注的令牌/分隔符出现为止。
10:破坏性变更必须在提交信息中标记出来,要么在 <类型>(范围) 前缀中标记,要么作为脚注的一项。
11:包含在脚注中时,破坏性变更必须包含大写的文本 BREAKING CHANGE,后面紧跟着冒号、空格,然后是描述,例如: BREAKING CHANGE: environment variables now take precedence over > config files 。
12:包含在 <类型>(范围) 前缀时,破坏性变更必须通过把 ! 直接放在 : 前面标记出来。 如果使用了 !,那么脚注中可以不写 BREAKING CHANGE:, 同时提交信息的描述中应该用来描述破坏性变更。
13:在提交说明中,可以使用 feat 和 fix 之外的类型,比如:docs: updated ref docs 。
14:工具的实现必须不区分大小写地解析构成约定式提交的信息单元,只有 BREAKING CHANGE 必须是大写的。 BREAKING-CHANGE 作为脚注的令牌时必须是 BREAKING CHANGE 的同义词。 :::

2.5 具体使用

站点已集成commitizen遵循谷歌 conventionalcommits约定式提交规范,进行了汉化方便辨识同时集成了commitlint和 lintstaged规则格式校验; 提交类型以及内容体参照 👆 具体操作: fileChange后执行命令git add .(全量存入暂存区或者单文件存入)再执行 script 命令:

npm run commit

例:

PS F:\qzd-patents-pc\qzd-patents-pc> npm run commit

> wz-website@1.0.0 commit
> git cz

cz-cli@4.2.4, cz-customizable@6.3.0

All lines except first will be wrapped after 100 characters.
? 请选择提交的类型; (Use arrow keys)
> feat:      新功能
  fix:       修复
  docs:      文档变更
  style:     代码格式(不影响代码运行的变动)
  refactor:  重构(既不是增加feature),也不是修复bug
  pref:      性能优化
  test:      增加测试
(Move up and down to reveal more choices)

通过方向键选择提交类型,再进行本次提交的内容描述:

例:

All lines except first will be wrapped after 100 characters.
? 请选择提交的类型; fix:       修复
? 请输入修改的范围(可选) commitlint.md
? 请简要描述提交(必填) content change
? 请输入详细描述(可选) commitlint.md content edit
? 请选择要关闭的issue(可选)

###--------------------------------------------------------###
fix(commitlint.md): content change

commitlint.md content edit
###--------------------------------------------------------###



? 确认要使用以上信息提交?(y/n) (Yneh) y

编辑完内容后确认提交本次commit

确认提交后会进行prettiereslint格式校验,校验通过继续向下执行。

 

pre-commit 已集成规则校验,务必按照此规范commit

 

3. Git 常见问题

3.1 git merge 或 git pull时出现冲突要怎么解决。

首先我们简述一下git merge 的机制 Tree-Way Merge(三向合并), A(当前分支),B(待合并分支), C(两者共同历史),

  1. 首先用A,B 和 C对比,发现第30行,如果只有一个分支A对比C有变更,那就采用A分支自动merge。
  2. 如果只有B对比C有变更,那么采用B分支自动合并,
  3. 如果两个分支都有变更,此时三个分支都不一致,那么就需要手动合并。

1,2 两种场景属于自动merge 我们一般是不需要处理的。

第三种就是我们日常遇到的冲突场景,也是比较容易丢失代码的场景。

以vscode为例

首先遇到冲突第一件事情是看跟谁冲突了,然后联系对方确定以谁的为准,严禁直接采用自己的代码放弃别人的代码, 经过对方确认后,再决定使用那一方的代码。

第二步是解决冲突。

左键点击文件可以很清晰的看到Tree-Way Merge(三向合并)的三个文件,我用字母做了标识,可以参考关于三向合并的说明(Visual Studio Code 1.69, 设置中搜索   git.mergeEditor控制使用新界面还是老界面)。

右键点击文件弹出菜单,根据你跟对方协商的结果,决定采用谁的代码,Accpet All Current 是指全部以当前分支(A)的代码为准,Accpet All Incomming 是指全部以被合并分支(B) 为准。⚠️这个操作合并的是整个文件而不是单行冲突。单行合并请勾选对应的行数进行操作。

新版界面

老版界面

有些函数比较复杂,同一个作用域内出现了多个冲突, 解决冲突后,可能存在括号丢失之类的,要查看是否有语法错误。

如果是文件行数较多的文件,请务必保证解决了所有的冲突而不是所有的冲突,可以通过git hooks或者自己全局来搜索<<< 来确认。

提交代码

git add filename
git commit -m "fix: fix conflict for filename"
git push

至此,一个冲突解决完成。

 

3.2 如何进行代码回滚?

代码回滚一定要慎重!如果修改到的文件比较少,我们可以不通过命令回滚的方式,手动删除之前的修改,再进行提交。

  1. 获取到想要回滚到commit Id
git log

  1. 回滚到指定提交
# 适用场景: 如果想恢复到之前某个提交的版本,且那个版本之后提交的版本我们都不要了,就可以用这种方法。
$ git reset --hard < commit ID >
$ git push -f

# 适用场景:如果我们想撤销之前的某一版本,但是又想保留该目标版本后面的版本,记录下这整个版本变动流程,就可以用这种方法。
$ git revert -n < commit ID >
$ git commit -m "fix: revert some commit"
$ git push

两种方法对比在于要不要撤回某个commit 之后的所有提交。 git reset 会放弃所有,并且如果之前提交已经同步到了remote, 那么需要使用git push -f 进行强制提交,因为本地分支对于远程分支落后了n个版本。

git revert 只会放弃某次commit的代码,并且是生成一次新的commit, 需要再commit一次。 所以比远程多了一次提交,所以不需要强制提交。

 

3.3 不小心把代码push到远程仓库后怎么撤销?

参考上一个问题代码回滚

 

3.4 错误的merge要怎么撤销?

尚未merge成功的状态下,想要撤回合并请使用

$git merge --abort

如果已经merge 成功了,想要撤销合并

找到merge 之前的commit id,参考3.2问题代码回滚

 

3.5 windows系统文件名大小写不敏感问题?

# 此操作设置git大小写敏感
git config --global core.ignorecase false
# 此操作设置window10 以上系统大小写敏感
fsutil file setCaseSensitiveInfo <dir path> enable

 

3.6 已经提交过的文件怎么忽略?

1.从本地Git缓存中删除文件

# 忽略文件
$ git rm --cached <filename>
# 忽略文件夹
$ git rm -r --cached <Dirname>

2.提交到仓库里面

$ git commit -m "chore: remove somefile version tacking changes"
$ git push

3.将文件path添加到.gitignore 文件

 

3.7 换行符不统一导致eslint校验不通过的问题?

git 配置

# 提交时转换为 LF,检出时不转换
$ git config --global core.autocrlf input
# 不允许有混用换行符提交
$ git config --global core.safecrlf true

编辑器配置

在编辑器插件设置中设置 end_of_line 值为 lf

尚未安装插件的话建议设置编辑器配置files.eol 值为 '\n'

 

4. 附录 Git 常用命令

git 命令分为重要常用不推荐熟悉四种。

重要一般为前置全局配置的命令,一定在初始化之项目之前配置。

常用一般的开发中使用频率较高的命令

不推荐是指常用,但是不推荐使用的命令

熟悉是指可能会用到的命令

还有一些较冷门的命令将不会在以下说明中列出。

4.1 创建版本库

#  初始化git仓库
git init
#  在目录内新建一个仓库
git init <dirname>
#  克隆一个git仓库, 此处的url一般推荐ssh,不推荐https(常用)
git  clone <url>

4.2 配置

# 设置提交代码时候的用户信息(重要)
$ git config <--global> user.name "<name>"
$ git config <--global> user.email "<email address>"
# 提交时转换为LF,检出时不转换, 解决win mac 系统换行符问题,
# 一般规范内使用LF换行,不同的换行符会被识别为代码变更。(重要)
$ git config --global core.autocrlf input
# 拒绝提交包含混合换行符的文件(重要)
$ git config --global core.safecrlf true

# 查看config配置
$ git config --list
# 编辑Git配置文件
$ git config -e <--global>

 

4.3 修改和提交

# 将某个文件添加到暂存区(常用)
git add <filename1> <filename2> ...
# 将某个目录添加到暂存区(常用)
git add <dirname>
# 将所有变更文件添加到暂存区(不推荐)
git add .
# 提交(常用)
$ git commit -m "<message>"
# add 和 commit 合为一步(常用)
$ git commit -am "<message>"
# 删除工作区文件,并将这次删除放入暂存区
git rm <filename>

 

4.4 更新和发布

# 获取远程分支,并更新到本地分支(常用)
$ git pull <remote> <branch>
# 推送本地更新到远程分支(常用)
$ git push <remote> <branch>
# 获取远程分支,但是不更细本地分支(常用)
$ git fetch <remote> 
# 获取远程分支详细信息
$ git remote  -v 
# 添加一个新的远程仓库
$ git remote add <shortname> <url>
# 删除远程仓库
$ git remote rm <name>

 

4.5 合并和变基

# 合并分支到当前分支, 存在两条记录
$ git merge <branch>
# 合并分支到当前分支, 存在一条记录
$ git rebase <branch>
# 取消当前的rebase, 用于rebase冲突后放弃rebase
$ git rebase --abort
# 继续rebase, 用于解决冲突后继续执行rebase
$ git rebase --continue

 

4.6 分支和标签

# 显示本地分支, -a 显示全部,包含remote(常用)
$ git branch <-a>
# 切换分支(常用)
$ git checkout <branch>
# 丢弃工作区修改, . 丢弃所有
$ git checkout -- <filename>
# 从当前分支新建一个本地分支并切换(常用)
$ git checkout -b <branchname>
# 删除本地分支(常用)
$ git branch -d <branch>
# 给当前分支打标签
$ git tag <tagname>

 

4.7 撤销和回滚

将当前版本重置至HEAD, 用于merge失败
$ git reset --hard HEAD
# 将当前版本重置至某一个提交状态(不推荐)
$ git reset --hard <commit>
# 将当前版本重置至某一个提交状态,代码不变
$ git reset <commit>
# 重置至某一状态,保留版本库中的不同文件
$ git reset --merge <commit>
# 重置至某一状态,重置变化的文件,代码改变
$ git rest --keep <commit>
# 丢弃本地更改信息并将其存入指定文件
$ git checkout HEAD <file>
# 撤销提交
$ git revert <commit> 

 

4.8 其他

# 查看当前版本状态(常用)
$ git status 
# 查看日志,可选用查看几条(常用)
$ git log -<number>
# 显示某个提交的详细内容
$ git show <commit>
# 显示文件每一行的cimmit号,提交者,最早提交日期
$ git blame <file>

 

posted @ 2023-08-10 19:59  泠风lj  阅读(27)  评论(0编辑  收藏  举报