游客发表
以这个博客为例,被存边其文献存储在一个 Git 货仓中,仓中储那此中有一个文献名为 content/post/2019-06-28-brag-doc.markdown
。这个文献在我的终归 .git
文献夹中险些的职位在那边?过去的文献版本又被存储在那边?那么,就让我们通过编纂极少简短的被存边 Python 代码来穷究谜底吧。
你的仓中储那货仓中,每一个文献的文献汗青版本都被蓄积在 .git/objects
中。譬喻,终归马虎这个博客,.git/objects
贮蓄了 2700 多个文献。
$ find .git/objects/ -type f | wc -l2761
瞩目:
.git/objects
贮蓄的音问,不只是是 “货仓中每一个文献的集体先前版本”,但我们暂节减细辩说这一本色。
这里是一个简短的 Python 顺次(find-git-object.py),它能够附和我们定位在 .git/objects
华厦特定文献的险些职位。
import hashlibimport sysdef object_path(content): header = f"blob { len(content)}\0" data = header.encode() + content sha1 = hashlib.sha1() sha1.update(data) digest = sha1.hexdigest() return f".git/objects/{ digest[:2]}/{ digest[2:]}"with open(sys.argv[1], "rb") as f: print(object_path(f.read()))
此顺次的症结独霸如下:
blob 16673\0
),并将其与文献本色连续e33121a9af82dd99d6d706d037204251d41d54
).git/objects/e3/3121a9af82dd99d6d706d037204251d41d54
)运转的设施如下:
$ python3 find-git-object.py content/post/2019-06-28-brag-doc.markdown.git/objects/8a/e33121a9af82dd99d6d706d037204251d41d54
这种存储计谋的术语为“本色寻址存储content addressed storage”,它指的是目的在数据库华厦文献名与文献本色的哈希值雷同。
本色寻址存储的风趣之处就是,要是我有两份能够多份本色无缺雷同的文献,在 Git 的数据库中,并不会所以占用额外空间。要是本色的哈希值是 aabbbbbbbbbbbbbbbbbbbbbbbbb
,它们都邑被存储在 .git/objects/aa/bbbbbbbbbbbbbbbbbbbbb
中。
要是我试验在 .git/objects
目次下稽查这个文献,露出的本色顺应有极少额外:
$ cat .git/objects/8a/e33121a9af82dd99d6d706d037204251d41d54x^A<8D><9B>}sƑo|<8A>^Q<9D>ju<92><9C><9C>*<89>j^...
这是怎样回事呢?让我们来运转 file
夂箢检讨一下:
$ file .git/objects/8a/e33121a9af82dd99d6d706d037204251d41d54.git/objects/8a/e33121a9af82dd99d6d706d037204251d41d54: zlib compressed data
素来,它是缩短的!我们能够编纂一个茂密的 Python 顺次—— decompress.py
,而后用 zlib
模块去解压这些数据:
import zlibimport syswith open(sys.argv[1], "rb") as f: content = f.read() print(zlib.decompress(content).decode())
让我们来解压一下顾念记挂顾念记挂结果:
$ python3 decompress.py .git/objects/8a/e33121a9af82dd99d6d706d037204251d41d54blob 16673---title: "Get your work recognized: write a brag document"date: 2019-06-28T18:46:02Zurl: /blog/brag-documents/categories: []---... the entire blog post ...
结果露出,这些数据的编码花式额外轻省:首先有 blob 16673\0
记号,后来就是文献的险些本色。
这里有一件我第一次露出时让我认为骇怪的事:这里并莫得任何迥异性数据!阿谁文献是该篇博客著述的第 9 个版本,但 Git 在 .git/objects
目次中存储的版本是齐备文献本色,而并非与前一版本的迥异。
纵然 Git 本质上有韶华会以迥异性数据存储文献(譬喻,当你运转 git gc
时,为了擢升结果,它能够会将多个迥异的文献封装成 “打包文献”),但在我片面阅历中,我从未须要眷注这个细节,是以我们不在此长远辩说。然而,看待这种花色若何职业,Aditya Mukerjee 有篇显赫的著述 《拆解 Git 的打包文献》。
你能够会郁闷:要是在我设立了极少错别字曾经,这篇博文曾经糊口了 8 个版本,那它们在 .git/objects
目次华厦职位是那边?我们若何找到它们呢?
首先,我们来骗捏 git log
夂箢来查找订正过这个文献的每一个提交:
$ git log --oneline content/post/2019-06-28-brag-doc.markdownc6d4db2d423cd76a7e91d7d0f105905ab6d23643998a46dd67a26b04d9999f17026c0f5272442b67
而后,我们采纳一个曾经的提交,譬喻 026c0f52
。提交也被存储在 .git/objects
中,我们能够试验在那里找到它。然而阻难了!鉴于 ls .git/objects/02/6c*
莫得露出任何本色!要是有人通知你,“我们露出有时 Git 会打包目的来节约空间,我们并不需过多珍重它”,但而今,我们须要去面对这个题目了。
那就让我们去解阁阁它吧。
而今我们须要从打包文献中解包出极少目的。我在 Stack Overflow 上查找了一下,顾念记挂起来我们能够这样进行独霸:
$ mv .git/objects/pack/pack-adeb3c14576443e593a3161e7e1b202faba73f54.pack .$ git unpack-objects < pack-adeb3c14576443e593a3161e7e1b202faba73f54.pack
这种直接对库进行手术式的做法让人有些紧绷,但要是我误独霸了,我还能够从 Github 上重新克隆这个库,是以我并不太顾虑。
解包集体的目的文献后,我们赢得了更多的目的:约莫有 20000 个,而不是素来的约莫 2700 个。顾念记挂起来很酷。
find .git/objects/ -type f | wc -l20138
而今我们能够连缀顾念记挂顾念记挂我们的提交 026c0f52
。我们曾经说过 .git/objects
中并不都是文献,此中一部门是提交!为了弄领路我们的旧著述 content/post/2019-06-28-brag-doc.markdown
是在那边被覆灭的,我们须要长远稽查这个提交。
首先,我们须要在 .git/objects
中稽查这个提交。
颠末解包后,我们而今能够在 .git/objects/02/6c0f5208c5ea10608afc9252c4a56c1ac1d7e4
中找到提交 026c0f52
,我们能够用底下的设施去稽查它:
$ python3 decompress.py .git/objects/02/6c0f5208c5ea10608afc9252c4a56c1ac1d7e4commit 211tree 01832a9109ab738dac78ee4e95024c74b9b71c27parent 72442b67590ae1fcbfe05883a351d822454e3826author Julia Evans 1561998673 -0400committer Julia Evans 1561998673 -0400brag doc
我们也能够用 git cat-file -p 026c0f52
夂箢来赢得捏雷同的音问,这个夂箢能起到雷同的浸染,然而它在花色化数据时做得更好极少。(-p
选项意味着它能够以更有爱的花式进行花色化)
这个提交贮蓄一个树。树是什么呢?让我们顾念记挂一下。树的 ID 是 01832a9109ab738dac78ee4e95024c74b9b71c27
,我们能够骗捏先前的 decompress.py
脚本稽查这个 Git 目的,纵然我不得不移除 .decode()
能力预防脚本溃逃。
$ python3 decompress.py .git/objects/01/832a9109ab738dac78ee4e95024c74b9b71c27
这个输出的花色有些难以阅读。症结的题目在于,该提交的哈希(\xc3\xf7$8\x9b\x8dO\x19/\x18\xb7}|\xc7\xce\x8e…
)是原始字节,而莫得进行十六进制的编码,所以我们顾念记挂到 \xc3\xf7$8\x9b\x8d
而非 c3f76024389b8d
。我预备切换至 git cat-file -p
夂箢,它能以更有爱的花式露出数据,我不想自身编纂一个领路器。
$ git cat-file -p 01832a9109ab738dac78ee4e95024c74b9b71c27100644 blob c3f76024389b8d4f192f18b77d7cc7ce8e3a68ad .gitignore100644 blob 7ebaecb311a05e1ca9a43f1eb90f1c6647960bc1 README.md100644 blob 0f21dc9bf1a73afc89634bac586271384e24b2c9 Rakefile100644 blob 00b9d54abd71119737d33ee5d29d81ebdcea5a37 config.yaml040000 tree 61ad34108a327a163cdd66fa1a86342dcef4518e content <-- 这是我们接下来的目的040000 tree 6d8543e9eeba67748ded7b5f88b781016200db6f layouts100644 blob 22a321a88157293c81e4ddcfef4844c6c698c26f mystery.rb040000 tree 8157dc84a37fca4cb13e1257f37a7dd35cfe391e scripts040000 tree 84fe9c4cb9cef83e78e90a7fbf33a9a799d7be60 static040000 tree 34fd3aa2625ba784bced4a95db6154806ae1d9ee themes
这是我在这次提交时库的根目次中集体的文献。顾念记挂起来我曾经不谨慎提交了一个名为 mystery.rb
的文献,自后我苟简了它。
我们的文献在 content
目次中,接下来让我们顾念记挂顾念记挂阿谁树:61ad34108a327a163cdd66fa1a86342dcef4518e
$ git cat-file -p 61ad34108a327a163cdd66fa1a86342dcef4518e040000 tree 1168078878f9d500ea4e7462a9cd29cbdf4f9a56 about100644 blob e06d03f28d58982a5b8282a61c4d3cd5ca793005 newsletter.markdown040000 tree 1f94b8103ca9b6714614614ed79254feb1d9676c post <-- 我们接下来的目的!100644 blob 2d7d22581e64ef9077455d834d18c209a8f05302 profiler-project.markdown040000 tree 06bd3cee1ed46cf403d9d5a201232af5697527bb projects040000 tree 65e9357973f0cc60bedaa511489a9c2eeab73c29 talks040000 tree 8a9d561d536b955209def58f5255fc7fe9523efd zines
还未遣散……
我们要追求的文献位于 post/
目次,所以我们须要进一步穷究:
$ git cat-file -p 1f94b8103ca9b6714614614ed79254feb1d9676c.... 节减了豪爽行 ...100644 blob 170da7b0e607c4fd6fb4e921d76307397ab89c1e 2019-02-17-organizing-this-blog-into-categories.markdown100644 blob 7d4f27e9804e3dc80ab3a3912b4f1c890c4d2432 2019-03-15-new-zine--bite-size-networking-.markdown100644 blob 0d1b9fbc7896e47da6166e9386347f9ff58856aa 2019-03-26-what-are-monoidal-categories.markdown100644 blob d6949755c3dadbc6fcbdd20cc0d919809d754e56 2019-06-23-a-few-debugging-resources.markdown100644 blob 3105bdd067f7db16436d2ea85463755c8a772046 2019-06-28-brag-doc.markdown <-- 我们找到了!!!
在此,2019-06-28-brag-doc.markdown
之是以位于列表终末,是鉴于在揭橥时它是最新的博文。
颠末致力,我们找到了博文汗青版本方位的目的文献!太棒了!它的哈希值是 3105bdd067f7db16436d2ea85463755c8a772046
,所以它位于 git/objects/31/05bdd067f7db16436d2ea85463755c8a772046
。
我们能够骗捏 decompress.py
来稽查它:
$ python3 decompress.py .git/objects/31/05bdd067f7db16436d2ea85463755c8a772046 | headblob 15924---title: "Get your work recognized: write a brag document"date: 2019-06-28T18:46:02Zurl: /blog/brag-documents/categories: []---... 文献的糟粕部门在此 ...
这就是博文的旧版本!要是我践诺夂箢 git checkout 026c0f52 content/post/2019-06-28-brag-doc.markdown
能够 git restore --source 026c0f52 content/post/2019-06-28-brag-doc.markdown
,我就会赢得捏到这个版本。
我们适才通过的通盘进程(找到提交、逐层遍历目次树、采集所需文献名)顾念记挂似繁琐,但本质被骗我们践诺 git log content/post/2019-06-28-brag-doc.markdown
时,背地就是这样在运转。它须要逐个检讨你汗青记载华厦每一个提交,在每个提交中核查 content/post/2019-06-28-brag-doc.markdown
的版本(譬喻在这个案例中为 3105bdd067f7db16436d2ea85463755c8a772046
),并稽查它是否自上一提交倚赖有所迁移。
这就是为什么有时 git log FILENAME
会践诺的有些迂缓 —— 我的这个货仓中有 3000 个提交,它须要对每个提交做豪爽的职业,来肯定该文献是否在该提交中爆发过迁移。
而今,我在我的博旅店房中追踪了 1530 个文献:
$ git ls-files | wc -l1530
但汗青文献有多少呢?我们能够列出 .git/objects
中集体的本色,顾念记挂顾念记挂有多少目的文献:
$ find .git/objects/ -type f | grep -v pack | awk -F/ '{ print $3 $4}' | wc -l20135
但并不是集体这些都代表过去版本的文献 —— 正如我们曾经所见,许多都是提交和目次树。然而,我们能够编纂一个小小的 Python 脚本 find-blobs.py
,遍历集体目的并检讨是否以 blob
首先:
import zlibimport sysfor line in sys.stdin: line = line.strip() filename = f".git/objects/{ line[0:2]}/{ line[2:]}" with open(filename, "rb") as f: contents = zlib.decompress(f.read()) if contents.startswith(b"blob"): print(line)
$ find .git/objects/ -type f | grep -v pack | awk -F/ '{ print $3 $4}' | python3 find-blobs.py | wc -l6713
因而,顾念记挂起来在我的 Git 货仓中寄阁阁的旧文献版本有 6713 - 1530 = 5183
个,Git 会为我覆灭这些文献,以备我想着要规复它们时骗捏。太好了!
在 这个 gist 中附上了险些的此篇著述所用代码,素来没多少。
我算计我曾经对 Git 的职业花式老友知彼,但我过去从未真确触及过打包文献,是以这次穷究很风趣。我也很少陈想念当我让 git log
追踪一个文献的汗青时,它本质上有多大的职业量,所以也很高兴能长远钻探这个。
行径一个风趣的后续:我提交这篇博文后,Git 就鉴戒我货仓华厦目的太多(我猜 20,000 太多了!),并运转 git gc
将它们险些缩短成打包文献。是以而今我的 .git/objects
目次曾经被缩短得相等小了:
$ find .git/objects/ -type f | wc -l14
(题图:MJ/319a396c-6f3f-4891-b051-261312c8ea9a)
责任编辑:庞桂玉 源泉: Linux诸华 Git文献随机阅读
热门排行
友情链接