如何在不使用 git 的情况下查看 git 对象和索引
Posted
技术标签:
【中文标题】如何在不使用 git 的情况下查看 git 对象和索引【英文标题】:How to view git objects and index without using git 【发布时间】:2010-12-04 16:21:13 【问题描述】:使用 OS X 终端,
您如何以纯文本形式查看这些文件的内容?
【问题讨论】:
这些文件本质上不是纯文本的,要这样查看它们,您需要一个将它们从格式转换为文本的程序。 Git 是一个程序,其组件旨在做到这一点。如果有人写了另一个,我会感到非常惊讶。 所以对象(特别是提交对象)不会转换为纯文本? 它们至少使用 zlib(deflate)压缩进行压缩。 @CoreyFloyd 当然它们会转换为纯文本!这就是git
的用途!
这可以分为三个问题:1) 计算哈希:***.com/questions/7225313/… 2) 如果在松散的对象上,DEFLATE:***.com/questions/3178566/deflate-command-line-tool 3) 如果在一个包文件中...学习如何打包文件工作并重新实现它们:) ***.com/questions/9478023/… , ***.com/questions/76002/git-pack-file-entry-format
【参考方案1】:
alias deflate="perl -MCompress::Zlib -e 'undef $/; print uncompress(<>)'"
deflate .git/objects/4b/3083256dedabd68e839d7717aa785424119990 | sha1sum
4b3083256dedabd68e839d7717aa785424119990 -
【讨论】:
此答案适用于任何使用 perl 的机器,而接受的答案是指特定工具zpipe
,例如,它在 macOS 上无法立即使用。不过,如果它描述了perl
调用正在做什么,那就太好了:从 perl 标准库加载zlib
模块,然后解压缩标准输入。我喜欢 perl!
我投了赞成票,但它应该被命名为“inflate”? compress=deflate, uncompress=inflate【参考方案2】:
看“Object storage format” in Git User Manual。
它是使用zlib 的原始压缩数据。可以使用“zlib1g-dev”包中的zpipe
。用gcc -o zpipe zpipe.c -lz
编译the example。这不是标准的.gz
什么的。
./zpipe -d < .git/objects/02/43019ddb4d94114e5a8580eec01baeea195133
打印 blob 的内容(标题+数据)
如果要检查 SHA-1,必须将未压缩的 blob 放入文件 (myblob
) 并执行
sha1sum myblob
【讨论】:
不幸的是,这不适用于打包的对象(那些已经在存储库中一段时间的对象)。 您的意思是目标文件仅包含 DEFLATE 有效负载,而不包含在 ietf.org/rfc/rfc1952.txt 中指定的其他元数据字段,所以这就是gunzip
不起作用的原因?【参考方案3】:
我将以不同的方式解释您的问题。如果您想了解对象文件是什么,可以使用 git 直接查看它们,而无需浏览历史日志或使用 git checkout、diff 等。例如:
对于文件.git/objects/04/a42e9a7282340ef0256eaa6d59254227b8b141
运行命令
git show 04a42e
它结合了/04/
中的04
和剩余数字a42e
的前四个字符。
> git show 04a42e
commit 04f7db976fa54c72fcc6350dd7d0aa06cb249df6
Author: Alex Brown <alex@XXXX.XXX>
Date: Fri Jan 8 11:02:21 2010 +0000
a text file
diff --git a/1.txt b/1.txt
new file mode 100644
index 0000000..04a42e9
--- /dev/null
+++ b/1.txt
@@ -0,0 +1,3 @@
+Woo
+# boo
+# choo
这是一个提交,其他对象可能是文件 blob、树等。
【讨论】:
【参考方案4】:如果您想查看纯文本形式的 git 对象(提交和/或 blob,即文件内容) 不使用 git,这并不容易,尤其是在存储库被打包的情况下。你不能在本地安装 git,在你的主目录(或 MacOS X 上的等效目录)吗?
loose 对象的格式,以文件形式存储在.git/objects/
扇出目录中,例如.git/objects/02/43019ddb4d94114e5a8580eec01baeea195133
(扇出目录和文件名形成对象的 SHA-1 标识符),例如描述为在“Pro Git”一书的Chapter 9.2 "Git Objects"(可免费在线获得)和“Git Community Book”的Chapter 7.1 "How Git Stores Objects"。
pack 格式,其中一组对象存储在.git/objects/pack/
的单个文件中,例如.git/objects/pack/pack-1db7aa96d95149a4dd341490a3594181a24415ee.pack
,在“Git Community Book”的Documentation/technical/pack-format.txt 和Chapter 7.5 "The Packfile" 中有描述(在“Pro Git”的Chapter 9.4 "Packfiles" 中有提及)
如果要查找最新提交,请先查看.git/HEAD
文件以查找当前分支。它将包含以下内容:
ref: refs/heads/master
(如果它包含 SHA-1,你可以将它作为最后一次提交的 id,并跳过一个步骤)。然后检查例如.git/refs/heads/master
查找分支指向的位置。它将包含提交的 SHA-1,例如:
dbc1b1f71052c084a84b5c395e1cb4b5ae526fcb
最后(最近的)提交可能是松散的格式;在此示例中,它将位于 .git/objects/db/c1b1f71052c084a84b5c395e1cb4b5ae526fcb
文件中。
【讨论】:
【参考方案5】:索引存储在.git/index
下。
它是在https://github.com/git/git/blob/master/Documentation/technical/index-format.txt 指定的二进制未压缩格式,因此读取它的唯一方法是使用hd
之类的工具。
index
文件包含文件列表及其元数据,包括索引节点、权限和修改时间。它还包含内容的 SHA-1,它作为对象存储,这意味着当您执行git add
时,它可能会创建新对象。
我鼓励您创建一个简单的测试存储库,如git init init && cd init && echo a > a && git add a
,然后hd .git/index
逐字段验证格式。
以下问题更关注索引:What does the git index contain EXACTLY?
【讨论】:
以上是关于如何在不使用 git 的情况下查看 git 对象和索引的主要内容,如果未能解决你的问题,请参考以下文章
如何在不修改 .git/index 的情况下运行 git status - 例如在 PROMPT_COMMAND 中
如何使用 git reset 在不丢失本地更改的情况下重置未推送的提交