《Pro Git》读书笔记

当时在公交车上阅读没有留下笔记,事后补充一些我关注的章节笔记。

 

第9章 git内部原理

底层命令(plumbing commands)和相关高级命令:

git hash-object # 计算hash。可以改从stdin读取(--stdin),可以写入object文件(-w)
git cat-file # 读取object的内容。打印(-p),查大小(-s),查类型(-t)
git update-index # 更新暂存区(index)或目录缓存。同时添加未被跟踪的文件(--add) ,对于已经保存的object可以直接插入到暂存区(--cacheinfo mode,object,path)
git write-tree # 将暂存区内容写入tree对象
git read-tree # 读取tree文件。并作为子目录(--prefix=<dirName>)
git commit-tree # 提交(-p指定父提交)
git log --stat <commitId> # 查看提交日志
git update-ref <refPath> <commitId> # 创建将commitId写入ref文件中
git symbolic-ref HEAD # 对HEAD进行读写,如果后面加一个refPath的话就做写入,否则做读取
git gc # 触发gc,打包、删除久远的无引用的对象(--auto判断是否需要gc)
git verify-pack -v <packfileIdxPath> # 校验并打印(-v)packfile的信息
git fetch/push <remoteName> <src>:<dest> # 远程分支同步
git reset --hard <commitId> # 修改当前分支的HEAD
git log -g # 按照时间顺序浏览提交(不限制特定分支),该功能基于reflog(.git/logs/**日志文件)
git branch <newBranchName> <commitId> # 基于commit新建分支
git fsck --full # 查找未被引用的对象(新版本中--full是默认行为,相对的为--no-full,用于控制是否在备选对象池中查找)
git rev-list # 逆序显示提交对象,打印被提交引用的对象(--objects), 将refs目录下的所有引用都视为commitId参数(--all)
git filter-branch # 重写分支的版本历史,重写暂存区而不检出tree(--index-filter),重写书及内容(--tree-filter)
git prune --expire # 删除未被引用的对象
git count-objects -v # 查看存储情况

 

基本存储类型(具有HASH标识):

blob: 文件内容
tree: 目录结构,包括目录下的文件名、类型、hash索引、访问权限标识
commit: 提交

 

其他相关文件:

ref: 保存对提交的引用。
HEAD: 其中的ref属性指向一个ref。

 

ref分类:

head
tag
remote

 

远程仓库与.git/config中的存储demo:

[remote "origin"]
url = git@github.com:schacon/simplegit-progit.git
fetch = +refs/heads/*:refs/remotes/origin/*
push = refs/heads/master:refs/heads/qa/master

而关联的本地分支则存储为:

[branch "master"]
remote = origin
merge = refs/heads/master

 

补充说明:
- 在.git/HEAD文件指向的ref文件中写入对应的commitId,commit-tree的提交就相当于一次普通提交了。(HEAD指向ref,ref指向提交,提交指向父提交和tree。但是注意,git gc或者其他命令触发打包之后目录结构又复杂化了)
- git使用zlib作为压缩方式。


移除一个无用大文件的示例:
1. 找到文件:

$ git verify-pack -v .git/objects/pack/pack-3f8c0...bb.idx | sort -k 3 -n | tail -3
e3f094f522629ae358806b17daf78246c27c007b blob 05408d195263d853f09dca71d55116663690c27c blob 7a9eb2fba2b1811321254ac360970fc169ba2330 blob
1486 734 4667
12908 3478 1189 2056716 2056872 5401

 

2. 找到文件名:

$ git rev-list --objects --all | grep 7a9eb2fb
7a9eb2fba2b1811321254ac360970fc169ba2330 git.tbz2

 

3. 找到相关的commit:

$ git log --pretty=oneline -- git.tbz2
da3f30d019005479c99eb4c3406225613985a1db oops - removed large tarball
6df764092f3e7c8f5f94cbe08ee5cf42e92a0289 added git tarball

 

4. 指定起始版本重写提交:

$ git filter-branch --index-filter 'git rm --cached --ignore-unmatch git.tbz2' -- 6df7640^..
Rewrite 6df764092f3e7c8f5f94cbe08ee5cf42e92a0289 (1/2)rm 'git.tbz2'
Rewrite da3f30d019005479c99eb4c3406225613985a1db (2/2)
Ref 'refs/heads/master' was rewritten

 

5. (可选)清理引用,gc,删除文件

$ rm -Rf .git/refs/original
$ rm -Rf .git/logs/
$ git gc 
$ git prune --expire

 

posted @ 2019-03-30 12:11  rainforwind  阅读(46)  评论(0)    收藏  举报