这是我参与「第五届青训营 」伴学笔记创作活动的第 4 天
这里是Git的使用介绍,和最佳实践的内容
方向介绍
Why Git
Git是必须技能昂!!!
- 协同工作
- 开源社区
Git是什么
Git的优缺点
Git是一个版本控制系统
- SVN:
- Git:
Git发展历史
linus做的,开源,可以找到代码康康昂!
- Git发展历史:
Gitlab可定制化很强(字节也是用Gitlab),自己服务器上可以很好搭建Gitlab,保证自己的数据和代码存在自己系统的服务器上,稳健!!!(企业喜欢用昂!!!)
Git的基本使用方式
Git Init
初始化git仓库
- Git仓库
- HEAD就是当前头位置
- Config:git仓库的一些配置
- Hooks: 配置一些hooks
- Objects: 存储的一些文件信息
- Refs: 存一些分支信息
- 工作区&暂存区
Git Config
Config级别
--global, --system, --local
- 每个级别的配置可能重复,但是低级别的配置会覆盖高级别的配置。
常见Git配置
Git Remote
git remote -h -> 可以看到帮助文档昂!有很多命令,其他的git命令也是类似的昂!!!
Remote查看 & 添加:
同一个origin设置不同的 Push 和 Fetch URL:
HTTP Remote
SSH 和 HTTP 都要身份验证昂,
- 免密配置:
一般不用HTTP的,一般都是SSH。HTTP没有那么安全昂!!!
SSH Remote
加密通过公私钥的机制昂!!!
一般SSH的URL都是
git@github.com:git/git.git,这种形式昂!
推荐ed25519 -> 来进行处理昂!!!过程都是一样的昂!!!
Git Add
加入文件到暂存区
git add之后,可以看到.git中,多了一部分的内容昂!!!
git cat-file -p,可以根据加密后的内容,反解出文件的内容昂!
- git cat-file的使用:
1
alex ~ $ git cat-file -h
2
用法:git cat-file <类型> <对象>
3
或:git cat-file (-e | -p) <对象>
4
或:git cat-file (-t | -s) [--allow-unknown-type] <对象>
5
或:git cat-file (--batch | --batch-check | --batch-command) [--batch-all-objects]
6
[--buffer] [--follow-symlinks] [--unordered]
7
[--textconv | --filters]
8
或:git cat-file (--textconv | --filters)
9
[<版本>:<路径|树对象> | --path=<路径|树对象> <版本>]
10
11
检查对象存在或输出对象内容
12
-e 检查 <对象> 是否存在
13
-p 美观地打印 <对象> 的内容
14
15
输出 [坏的] 对象属性
16
-t 显示对象的类型('blob'、'tree'、'commit'、'tag'……其中之一)
17
-s 显示对象大小
18
--allow-unknown-type 允许 -s 和 -t 对损坏的对象生效
19
--use-mailmap 使用邮件映射文件
20
--mailmap --use-mailmap 的别名
21
22
批量处理标准输入中请求的对象(或者 --batch-all-objects)
23
--batch[=<格式>] 显示完整的 <对象> 或 <版本> 内容
24
--batch-check[=<格式>]
25
类似于 --batch,但不输出 <内容>
26
-z 标准输入以 NUL 字符分隔
27
--batch-command[=<格式>]
28
从标准输入读取命令
29
--batch-all-objects 带有 --batch[-check]:忽略标准输入,批量处理所有已知的对象
30
31
更改或优化批处理输出
32
--buffer 缓冲 --batch 的输出
33
--follow-symlinks 跟随树内符号链接
34
--unordered 在输出对象前不要排序
35
36
转换或过滤后输出对象(数据对象或树)(单独或批处理)
37
--textconv 对对象内容做文本转换
38
--filters 对对象内容做过滤
39
--path 数据对象|树 (--textconv | --filters) 使用 <路径>;而不是 'batch'
Git Commit
真正提交到git目录里面昂!!!
这里多了两个文件诶!!!是啥呢?git cat-file -p看一下!!!
- blog的那个东西,表示的是文件的信息,可以看到,readme.md里面,恰好是第二个东西,也就是文件内容!!!
- 3a3axxx,本质上是一个目录信息,这个目录里面存储了一个文件是readme.md,readme.md是blob类型的,内容是557db03xxx
- 下面这个是一个commit,tree是它的目录树,author是作者,committer是提交者,还有一些提交的信息和备注昂!!!
Git Log
可以查看的Log信息,可以看到和上面的内容有重复的昂!!!自己好好对应一下!!!
Objects
- 不同的Objects类型
- 信息的串联:
- Objects关系可视化:
Refs
新切出来的test分支,和之前的master分支的内容是一样的哈!!!
branch & tag:
Git Tag
可以使用git tag命令生成tag。e.g.
git tag v0.0.1
Linux中,一切皆为文件。这里的tag其实也是哈,由于是从test分支创建出来的,而test分支本质是从master最新的commit切出来的,因此,这里的v0.0.1,本质上指向的,就是master中最新的commit!
Annotation Tag
附注标签:特殊的Tag,可以给 Tag 提供一些额外的信息。
- 命令:
git tag -a v0.0.2 -m "add feature 1"
注意哈,这里指向了一个新的Reference,这个34eddxxx是新增的,在objects里面也有对应的昂!!!
git cat-file -p 34eddxxx -> 这个本质上就是我们上面讲的tag object
实际指向的是b4870xxx,但是会有tagger之类的东西,以及一些携带的信息昂!!!
追溯历史版本
如果修改了上面这个文件,再次commit了
objects下面有7个文件了!!!原来只有4个的,对应的更新后的tree,对应的更新后的blob,以及记录了最新的一次提交的object,因此多了三个昂!
- 最新的commit,还有一个parent commit,commit形成了一条链。
- Tree中的内容改变,也生成了一棵全新的Tree。
修改历史版本
第一个commit --amend完了之后,会多一个commit object,而其他的objects不会改变昂,只变了comment嘛,其他关系又没变。
新增的Object和悬空的Object
类似于上面这种,如果改变了comment,那么之前的那个reference就没有引用了,寄!
git fsck --lost-found可以查看所有这种悬空的Object昂!!!
Git GC
一个GC的例子:
1
# 设置操作过期,这样就可以去掉历史操作对于Reference的引用
2
git reflog expire --expire=now --all
3
# 现在之前的全部清理
4
git gc --prune=now
完整Git视图
Git Clone & Pull & Fetch
Git Push
开发常用昂!!!这里的Branch protection rules在开发中还蛮常用的,比如不能直接push到master。
Git研发流程
不同工作流
集中式工作流
分支管理工作流
- Git Flow:
- Gitlab Flow
都只是推荐的工作流而已,不一定要按照推荐的来昂,很多地方和github一样一样的。没有限制的那么死昂!!!
Github Flow:
例子:
clone仓库到本地
- 本地main -> 修改 -> push 到 main
- 本地切一个分支dev -> 改完了push到远端dev -> PR -> MR
- Branch Protection Rules:
这里就可以使用昂!!!
- 比如设置了,不可以直接push,必须提MR的保护:
代码合并
- Fast-Forward
git merge test --ff-only-> 没有merge节点昂!!!
- Three-Way Merge
git merge test --no-ff-> 存在merge节点昂!
git log中可以看到,生成了一个新的Merge Point