《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

浙公网安备 33010602011771号