git 笔记
我们的项目使用 git 来进行版本管理,这里记录一些使用心得。
-
Git 是一个 Key/Value 数据库。(这是 git 官方的说法,我并没有看到 git 作为一个数据库的特殊优势,如果不涉及版本管理,大部分情况下其他的 kv 数据库似乎是一个更好的选择)
-
Git 内部包含 blob对象(存储文件),tree 对象 , commit 对象和 tag 对象(标签,见 引用部分)
对象在.git/objects
目录下。
可以通过git cat-file -t sha1
确定对象的类型
通过git cat-file -p sha1
查看对象的内容
对象使用zlib
压缩,亦可以使用pigz
解压查看内容pigz -d sha1
或pigz -d < sha1
-
Git 引用
保存在.git/refs
目录下。所谓引用就是一个包含 sha1 值的文本文件。使用可读的名字,如 master。HEAD 引用
是一个特殊的引用,内容不是 sha1 值,而是其他的引用的名称。- 标签引用分为轻量标签和附注标签,两种标签都是指向一个 sha1 的文本文件,不同的是轻量标签直接指向一个
commit 对象
,而附注标签指向一个标签对象
(标签对象里包含了tag -a xxx
备注的内容。标签亦可指向任意对象,不过不是常规用法。 远程引用
是只读的,Git 将这些远程引用作为记录远程服务器上各分支最后已知位置状态的书签来管理。远程引用的文本内容是远程分支的 sha1 值。
-
为节约存储空间,Git 使用打包对象来压缩文件。使用命令
git gc
可以手动开启打包,在你向远程服务器推送或本地有太多松散(loose)对象时,Git 也会自动启动打包。打包后的对象保存在.git/objects/pack
目录下。可以通过git verify-pack pack-xxxx.idx
命令查看已打包的内容。最新版的文件是保存全部,而旧的版本是保存差异内容(这基于大部分情况下需要快速访问文件的最新版本的假设)。 -
git
rebase
和cherry-pick
的实现是相同的,都是把当前 commit 与 base 进行比较后,重放一遍变动。 gitmerge
的实现同理。 -
git merge
是三方合并,其他的版本管理系统同理。三方合并的具体做法是:- 找出要合并分支 A 和 B 的最大公共 base,commit C
- 分别比较 commit C 与 A B,做 diff
- 合并两个 diff
- 生成一个新的 commit D,commit D 的 parent 有两个,分别是分支 A 和 B 的最后一个 commit
-
关于
git cherry-pick
-
由于是使用 diff 重放实现的,故会导致内容相同的两个提交。在使用
git log A..B
时无法比较 commit。有文章不提倡使用cherry-pick
,此文章并给出了使用 patch 分支分别合并到 A 和 B 分支的方式来避免使用cherry-pick
Stop cherry-picking, start merging, Part 1: The merge conflict
-
按照
cherry-pick
的使用场景,应该仅在少数场景下使用。但是按照我们目前的开发流程。
master 作为开发分支
针对不同的地区使用不同的 release 分支(如 release/tw release/sea),都是 long live branch。
且不通分支之间的版本并不一致,有时候相差很长时间。
release 分支不会合并回 master。
为避免cherry-pick
遗漏,我任务从master
切出新的feature
分支,feature
分支仅合并回主干,通过git cherry-pick commits
将整个feature
分支在各个release
分支重放即可。
-
Reference:
今天听 梁文道的《八分》,里面提到了过年回家,各地规章的混乱,并且还提到至少应该提供一个统一的地方,方便我们查询各地的规则,还应该输入一个起始地和一个目的地,就告诉我应该怎么做。这个当然是不难,只是没有人愿意这么做。很久以来,我们就是这样,都进入了移动互联网时代,但是有价值的信息极为稀少,甚至是没有,每个地方都有一个看起来很相像的政府网站,一堆公众号,但是你在里面基本上很难查到一些有价值的信息,反而小小的香港政府,web 1.0 时代的网站,我记得去年疫情初期的时候就通过一个表格详细列出了你需要的各种信息。
如果一个有价值的信息加 10分,一个错误的信息或者谣言 -1分,那在我们现在这个信息爆炸的时代,总评分估计是负的。