学习Git的使用。

项目

项目开发流程

产生:
  1.明确需求和业务场景(用例图和如何使用)
  2.设计代码框架(代码结构和数据流向)
  3.分析设计细节业务的实现
  4.设计类,设计流程图,序列图,状态图
  5.评估设计和后续设计修改
维护:
  1.建立开发分支,开发完成
  2.提交测试
  3.生成changelog
  4.测试通过,release提交changelog,打tag,合并到dev或者master上,删除临时分支

项目开发结构工程

tree
1
2
3
4
5
6
7
8
9
10
11
12
13
.vscode 
|--- settings.json // vscode 配置
|--- templates
|--- cpp.lict // license文件
|--- h.lict // license文件
.gitignore // git push 忽略push时的文件和目录
README.md // 工程的描述
include // 工程头文件
src // 工程的源文件
docs // 工程的文档文件
CHANGELOG.md // 工程的的变化日志
node_modules // nodejs生成变化日志的插件

Git教程

熟悉Git的基本的使用可通过Git的教程游戏学习。

Git原理

了解Git的原理和不同的模式

git模型
git模型

git状态
git状态

git工作原理
git原理

Git基础

Git配置用户

安装Git之后,要做的第一件事就是设置自己的用户名和邮件地址。通过Git对项目进行版本管理的时候,Git需要使用这些基本信息,来记录是谁对项目进行了操作。

1
2
3
4
5
# 如果使用了 --global 选项,那么该命令只需要运行一次,即可永久生效
git config --global user.name "your_name"
git config --global user.email "your_email"
# 写入到C:/Users/用户名文件夹/.gitconfig文件中。这个文件是Git的全局配置文件,配置一次即可永久生效。
# 可以使用记事本打开此文件,从而查看自己曾经对Git做了哪些全局性的配置。

检查配置信息

1
2
3
4
5
# 查看所有的全局配置项
git config --list --global
# 查看指定的全局配置项
git config user.name
git config user.email

获取帮助信息

1
2
3
4
# 打开git config命令的帮助手册
git help config
# 获取git config命令的快速参考
git config -h

Git操作

操作之前要知道, git中文件的状态未跟踪? 未修改U 已修改M 已暂存A
Git文件状态

创建仓库

有一个尚未进行版本控制的项目目录,想要用Git来控制它

1
2
3
# 在项目目录, 开 Git Bash
git init
# 创建.gitignore配置文件

.gitignore配置文件书写方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 以 # 开头的是注释
# 以 / 结尾的是目录
# 以 / 开头防止递归
# 以 ! 开头表示取反
# 可以使用glob模式进行文件和文件夹的匹配(glob指简化了的正则表达式)
# -星号 *匹配零个或多个任意字符
# -[abc] 匹配任何一个列在方括号中的字符(此案例匹配一个a或匹配一个b或匹配一个c)
# -问号 ?只匹配一个任意字符
# -在方括号中使用短划线分隔两个字符, 表示所有在这两个字符范围内的都可以匹配(比如 [0-9] 表示匹配
# -所有 0到9的数字)
# -两个星号 ** 表示匹配任意中间目录(比如 a/**/z 可以匹配 a/z 、 a/b/z 或 a/b/c/z 等)

# 忽略所有.a文件
*.a
# 跟踪除了lib.a的文件
!lib.a
# 忽略当前目录下的file文件
/file
# 忽略任何目录下的doc文件夹
doc/
# 忽略所有doc/文件名.txt
doc/*.txt
# 忽略doc/目录及其所有子目录下的.pdf文件
doc/**/*.pdf

操作命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# 查询文件状态
git status -s

# 跟踪一个文件
git add file

# 跟踪添加多个文件
git add .

# 提交更新
git commit -m "更新信息"

# 撤销对所有已修改但未提交的文件的修改,但不包括新增的文件
git checkout .
# 撤销对指定文件的修改filename为文件名
git checkout --filename

# git reset回退项目版本
# CommitId是某个commit的哈希值,可以用git log查看
git reset --hard CommitId

# 撤销从上次提交之后
git reset HEAD
# 撤销从上次提交之后文件
git reset HEAD --filename

# 从git仓库和工作区中同时移除filename
git rm -f filename
# 从git仓库中移除filename,工作区中保留filename
git rm --cached filename

# 查看提交历史
git log --pretty=oneline
# 查看最新的n条历史
git -log -n --pretty=oneline
# 自定义输出格式
# %h哈希值 %an作者名字 %ar修改日期 %s提交说明
git -log -n --pretty=format:"%h | %an | %ar | %s"

Git的HEAD

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 分离HEAD到提交记录CommitId
# CommitId是某个commit的哈希值,可以用git log查看
git checkout CommitId
# 向上移动当前提交的前1个提交记录
git checkout HEAD^
# 向上移动HEAD的前3个提交记录
git checkout HEAD~3
# 向上移动分支的前1个记录
git checkout 分支^
# 向上移动分支的前3个记录
git checkout 分支~3
# 让分支指向某个提交记录
git branch -f 分支 HEAD
# 撤销远程分享分支
git checkout 撤销分支
git revert HEAD

Git提交树

1
2
3
4
5
6
# 复制提交记录到某个分支
git checkout 某个分支
git cherry-pick CommitId CommitID ...
# 重新排列HEAD3个提交顺序成新分支
git checkout 某个分支
git rebase -i HEAD~3

Github操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# 将远程仓库克隆到本地
git clone 远程仓库地址

# 查看分支列表
# *当前所处的分支
git branch

# 新分支
git brach 分支名称
# 切换分支
git checkout login
# 创建分支并切换到分支上
git checkout -b 分支名称

# merge合并分支
# 切换到需要合并的主分支上
git checkout 主分支
# 将目标分支合并到主分支
git merge 目标分支

# rebase合并分支记录
# 把目标分支的记录移动到主分支上
# 切换目标支上
git checkout 目标支上
# 将目标分支记录合并到主分支后面
git rebase 主分支
git rebase 目标分支 主分支

# 删除分支
git branch -d 分支

# 分支合并冲突
# 在不同的分支中对同一个文件进行不同的修改
# 只能手动解决冲突文件

# 将本地分支推送到远程仓库
# -u把本地分支和远程分支进行关联,在第一次推送时需要带-u参数
git push -u 远程仓库名字 本地分支名称:远程分支名称
git push -u origin main:main
git push -u origin main
# 把当前的仓库推送变成远程仓库
git push origin 远程仓库名字

# 查看远程分支名称
git remote show 远程仓库名称

# 把远程仓库下载到本地仓库
git checkout 远程分支名称
git checkout dev

# 把对应远程分支下载到本地仓库,并把下载的本地分支重命名
git checkout -b 本地分支名字 远程仓库名字/远程分支名
git checkout -b ldev origin/dev

# 远程跟踪仓库
git branch -u 远程仓库名字/远程仓库名 本地仓库名字

# 拉取远程分支当前的最新代码
# git pull是git fetch和git push的缩写
git pull 远程仓库名字 远程分支名称:本地分支名称
# git pully远程分支到到本地为本地分支名字,合并远程分支到当前分支
# git fetch origin dev; git merge o/dev
# git fetch origin 远程分支,合并远程分支都当前分支
git pull origin dev
git pull

# 删除远程分支
git push 远程分支 --delete 远程分支
git push origin --delete dev

# 从远程仓库下载本地仓库中缺失的提交记录
git fetch
git fetch 远程仓库名字 远程分支名称:本地分支名称

第一次Push Master分支

cmd
1
2
3
4
5
6
7
8
9
10
# 设置git
git config --global user.name "your_name"
git config --global user.email "your_email"
# 推送仓库
git init # 本地初始化Git
git add -A # 提交改动
git commit -m "init blog" # 提交信息
# git remote rm origin https:// #username 你的gitlab库名字
git remote add origin https:// # 链接远程的gitlab的master
git push -u origin main # 以master的角色推送到远程仓库

Git常用的命令

教程参考,多上Google查阅。

git add命令将文件内容添加到索引(将修改添加到暂存区)。也就是将要提交的文件的信息添加到索引库中。
git clone命令将存储库克隆到新目录中。
git status命令用于显示工作目录和暂存区的状态。
git diff命令用于显示提交和工作树等之间的更改。
git commit命令用于将更改记录(提交)到存储库。
git reset命令用于将当前HEAD复位到指定状态。
git rm命令用于从工作区和索引中删除文件。
git mv命令用于移动或重命名文件,目录或符号链接。
git branch命令用于列出,创建或删除分支。
git checkout命令用于切换分支或恢复工作树文件。
git merge命令用于将两个或两个以上的开发历史加入(合并)一起。
git log命令用于显示提交日志信息。
git stash命令用于将更改储藏在脏工作目录中。
git fetch命令用于从另一个存储库下载对象和引用。
git pull命令用于从另一个存储库或本地分支获取并集成(整合)。
git push命令用于将本地分支的更新,推送到远程主机。
git remote命令管理一组跟踪的存储库。
git show命令用于显示各种类型的对象。
git rebase命令在另一个分支基础之上重新应用,用于把一个分支的修改合并到当前分支。

Git合并分支请求

cmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1.创建新分支编辑代码
git checkout -b your_branch_name
2.在自己分支下git status
获取本次修改文件列表
3.添加Commit
git add -A
git commit -m "
xxxxx
"
4.切换到合并的主分支上pull最新代码(dev是主合并分支)
git branch显示所有分支(当前在本地新创建your_branch_name分支)

git checkout dev 切换到dev分支上
git pull 拉取服务器上dev的最新代码
git checkout your_branch_name 切换到自己修改的分支上
git merge dev 合并分支到dev上

5.推送本地分支到服务器
git push origin your_branch_name:your_branch_name

Gitlab上Merage请求

1.选择merge请求
创建Merge请求
创建Merge请求
创建Merge请求
创建Merge请求

Git仓库的分支和Commit开发规范

Git仓库分支管理

分支命名

固定 分支

master 分支

  • master 为主分支,也是用于部署生产环境的分支,确保master分支稳定性
  • master 分支一般由develop以及hotfix或fixbug分支合并,任何时间都不能直接修改代码

develop 分支

  • develop 为开发分支,始终保持最新完成以及bug修复后的代码
  • 一般开发的新功能时,feature分支都是基于develop分支下创建的

临时 分支

feature 分支

  • 开发新功能时,以develop为基础创建feature分支
  • 分支命名: feature/ 开头的为特性分支, 命名规则: feature/user_module、 feature/cart_module

release分支

  • release 为预上线分支,发布提测阶段,会release分支代码为基准提测

当有一组feature开发完成,首先会合并到develop分支,进入提测时,会创建release分支。
如果测试过程中若存在bug需要修复,则直接由开发者在release分支修复并提交。
当测试完成之后,合并release分支到master和develop分支,此时master为最新代码,用作上线。

fixbug 分支
分支命名: fixbug/ 开头的为修复分支,它的命名规则与 feature 分支类似
非紧急的bug时,计划性修复,以master或develop分支为基线,创建fixbug分支,修复完成后,需要合并到master分支和develop分支
修补bug

hotfix 分支

分支命名: hotfix/ 开头的为修复分支,它的命名规则与 feature 分支类似
线上出现紧急问题时,需要及时修复,以master或develop发布的分支为基线,创建hotfix分支,修复完成后,需要合并到master分支和develop分支

分支任务

feature 分支

cmd
1
2
3
4
git checkout -b feature/xxx            # 从dev建立特性分支
git add -A
git commit -m 'commit comment'
git merge feature/xxx --no-ff # 把特性分支合并到dev (--no-ff保留合并信息)

hotfix 分支

cmd
1
2
3
4
5
git checkout -b hotfix/xxx         # 从master建立hotfix分支
git add -A
git commit -m 'commit comment'
git merge hotfix/xxx --no-ff # 把hotfix分支合并到master,并上线到生产环境 (--no-ff保留合并信息)
git merge hotfix/xxx --no-ff # 把hotfix分支合并到dev,同步代码 (--no-ff保留合并信息)

release 分支

cmd
1
git merge dev --no-ff             # 把dev分支合并到release,然后在测试环境拉取并测试 (--no-ff保留合并信息)

master 分支

cmd
1
2
git merge release --no-ff          # 把release测试好的代码合并到master (--no-ff保留合并信息)
git tag -a v0.1 -m '部署包版本名' #给版本命名,打Tag

Git Commit规范

Commit messages的基本语法,参考比较广泛的格式Angular Git Commit Guidelines参考文档1参考文档2

具体格式为:

<type>(scope): <subject>
<BLANK LINE>
body
<BLANK LINE>
footer

参数说明

type: commit的类型
scope: commit修改的文件范围
subject: 简明commit的内容,留空首字母不要大写,动词开头,结尾不需要.,不超过50个字符
body: commit详细描述,需换行,则使用 |,每一行不超过72个字符
footer: 其他与代码无关描述

Type的类别说明:

描述
feat(feature) 新增一个功能
fix 修复一个Bug
docs 文档变更
style 代码格式(不影响功能,例如空格、分号等格式修正)
refactor 代码重构
perf(perfect) 改善性能
test 测试
build 变更项目构建或外部依赖
ci 更改持续集成软件的配置文件和package中的scripts命令
chore 变更构建流程或辅助工具
revert 代码回退

Git commit 提交例子

git
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
git add -A    # 添加修改文件

# git commit 例子

git commit -m "
feat(client/*): add the unblock client connect server mode

Add the unblock client to connect server
- The block client will time out
- Use the select listen the client successful status

BREAKING CHANGE: not need wait to socket connect
- unblock connect
- timeout retry connect

fix #123
"

git push

Nodejs的Changelog

  • nodejs安装

官方网站下载,选择对应的版本,解压

cmd
1
2
3
4
5
6
7
8
9
10
11
vim ~/.bashrc

在# Alias definitions下添加
export NODE_HOME=/opt/nodejs/node-v11.1.0-linux-x64/bin
export PATH=$NODE_HOME:$PATH

source ~/.bashrc

node -v
npm -v

  • Commitizen安装

更换淘宝镜像

1
npm install -g cnpm --registry=https://registry.npm.taobao.org
1
2
npm install -g commitizen
# cnpm install -g commitizen
  • 安装changelog
1
2
3
4
npm install -g conventional-changelog
npm install -g conventional-changelog-cli
# cnpm install -g conventional-changelog
# cnpm install -g conventional-changelog-cli

检查

1
2
npm ls -g -depth=0
# cnpm ls -g -depth=0

成功安装

1
2
3
4
5
/home/dev/workspace/nodejs/node-v12.18.2-linux-x64/lib
├── commitizen@4.1.2
├── conventional-changelog@3.1.21
├── conventional-changelog-cli@2.0.34
└── npm@6.14.5
  • 到工程目录

nodejs初始化

1
2
npm init --yes
# cnpm init --yes

支持Angular的Commit message格式

1
commitizen init cz-conventional-changelog --force --save --save-exact

生成Changelog
生成Changelog记得打开package.json修改version

1
2
3
4
5
6
7
8
9
# 基于上次 tag 版本(本地的tag版本)之后的变更
conventional-changelog -p angular -i CHANGELOG.md -s
# 生成之前所有 commit 信息产生的 changelog
conventional-changelog -p angular -i CHANGELOG.md -w -r 0
# 添加到package的script脚本中
"scripts": {
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s"
}
执行npm run changelog

定制commit message格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 安装cz-customizable
npm install cz-customizable --save-dev

cp node_modules/cz-customizable/cz-config-EXAMPLE.js .cz-config.js

# 注释.cz-config.js中以下代码
// scopes: [{ name: 'accounts' }, { name: 'admin' }, { name: 'exampleScope' }, { name: 'changeMe' }],

// allowTicketNumber: false,
// isTicketNumberRequired: false,
// ticketNumberPrefix: 'TICKET-',
// ticketNumberRegExp: '\\d{1,5}',

// skipQuestions: ['body'],

# 将之前符合Angular规范的cz-conventional-changelog适配器路径改成cz-customizable适配器路径:
# 更改当前项目下的package.json中cz-conventional-changelog为cz-customizable
"config": {
"commitizen": {
"path": "node_modules/cz-customizable"
}
}

Note:
  提交git commit 时使用git cz
添加步骤:
  1.git add -A // 将改变添加入缓存
  2.git cz // 添加文件修改commit
  3.conventional-changelog -p angular -i CHANGELOG.md -s -p // 生成本次的Changelog
  4.git add -A // 添加Changelog的改变
  5.git cz // 添加Changelog的改变
  6.git push // 进行push