Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Git对象SHA-1是文件内容还是文件名?_Git_Git Hash - Fatal编程技术网

Git对象SHA-1是文件内容还是文件名?

Git对象SHA-1是文件内容还是文件名?,git,git-hash,Git,Git Hash,我对文件的实际内容如何存储在.git中感到困惑 例如,Version 1是test.txt中的实际文本内容。当我将其提交(首次提交)到repo时,git返回该文件的SHA-1,该文件位于.git\objects\0c\15af113a95643d7c24432b0e0b287184cd049中 当我在文本编辑器中打开文件15af113a95643d7c244332b0e0b287184cd049时,它都是垃圾,类似这样 x+)JMU074f040031QÐKÏ,ÏLÏ/JeÎw[œRÎyÎyG*

我对文件的实际内容如何存储在.git中感到困惑

例如,
Version 1
test.txt
中的实际文本内容。当我将其提交(首次提交)到repo时,git返回该文件的SHA-1,该文件位于
.git\objects\0c\15af113a95643d7c24432b0e0b287184cd049

当我在文本编辑器中打开文件
15af113a95643d7c244332b0e0b287184cd049
时,它都是垃圾,类似这样

x+)JMU074f040031QÐKÏ,ÏLÏ/JeÎw[œRÎyÎyG*,8Š³,1%>9Ï5ÏDÏ3%

但是我不确定这个垃圾是否代表文本的加密形式
Version 1
,或者它是由SHA-1
15af113a95643d7c244332b0e0b287184cd049
表示的

顺便说一下,.git/objects中的文件是用zlib压缩的,因此您不应该直接盯着它们看。通过
zpipe-d
过滤它们,或者键入(使用):

使用
zpipe

$ ./zpipe -d < .git/objects/0c/15af113a95643d7c244332b0e0b287184cd049
然后:

$/usr/share/doc/zlib1g dev/examples/zpipe-d
您将得到如下结果:

vonc@VONCAVN7:/mnt/d/git/seec$ /usr/share/doc/zlib1g-dev/examples/zpipe -d < .git/objects/0d/b6225927ef60e21138a9762c41ea0db714ca0d
blob 2142 <full content there...>
vonc@VONCAVN7:/mnt/d/git/seec$/usr/share/doc/zlib1g dev/examples/zpipe-d<.git/objects/0d/b6225927ef60e21138a9762c41ea0db714ca0d
水滴2142
您将看到一个由类型和内容大小组成的标题,后跟实际内容

有关blob实际内容的说明,请参见Jeff Kunkle的“”幻灯片8:


主题行中问题的正确答案:

Git对象SHA-1是文件内容还是文件名

可能是“两者都不是”,因为您指的是松散对象文件的内容,而不是原始文件,即使您指的是原始文件,也不完全正确

Git中的松散对象是一个普通文件。文件名由对象的散列ID构成。反过来,对象的散列ID是通过计算附加前缀头的对象内容的散列来构造的

前缀头取决于对象类型。有四种类型:
blob
commit
tag
tree
。头由以ASCII(或等效的UTF-8)形式的类型名组成的以零结尾的字节字符串组成字节字符串,后跟空格,后跟以字节为单位的对象大小的十进制表示,后跟ASCII NUL(
b'\x00'
在Python中,如果您喜欢现代Python表示法,或者
'\0'
如果您喜欢C)

头之后是实际的对象内容。因此,对于包含字节字符串
b'hello\n'
的文件,要散列的数据包括
b'blob 6\0hello\n

$ echo 'hello' | git hash-object -t blob --stdin
ce013625030ba8dba906f756967f9e9ca394464a
$ python3
[...]
>>> import hashlib
>>> s = b'blob 6\0hello\n'
>>> hashlib.sha1(s).hexdigest()
'ce013625030ba8dba906f756967f9e9ca394464a'
因此,将用于存储此文件的文件名是(源自)
ce0136503ba8dba906f756967f9e9ca394464a
。作为松散对象,它将变成
.git/objects/ce/013625030ba8dba906f756967f9e9ca394464a

但是,该文件的内容是zlib压缩形式的
b'blob6\0hello\n'
(显然,
level=1
——默认值当前为6,结果在该级别上不匹配;不清楚Git的zlib deflate是否与Python的完全匹配,但在这里使用level 1确实有效):

(请注意,最后的
$
再次是shell提示符;现在回到Python3)

其中
vis.py
为:

def vischr(byte):
    "encode characters the way vis(1) does by default"
    if byte in b' \t\n':
        return chr(byte)
    # control chars: \^X; del: \^?
    if byte < 32 or byte == 127:
        return r'\^' + chr(byte ^ 64)
    # printable characters, 32..126
    if byte < 128:
        return chr(byte)
    # meta characters: prefix with \M^ or \M-
    byte -= 128
    if byte < 32 or byte == 127:
        return r'\M^' + chr(byte ^ 64)
    return r'\M-' + chr(byte)

def vis(bytestr):
    "same as vis(1)"
    return ''.join(vischr(c) for c in bytestr)
def vischr(字节):
“按vis(1)默认方式对字符进行编码”
如果字节在b'\t\n'中:
返回chr(字节)
#控制字符:^X;删除:\^?
如果字节<32或字节==127:
返回r'\^'+chr(字节^64)
#可打印字符,32..126
如果字节<128:
返回chr(字节)
#元字符:前缀为\M^或\M-
字节-=128
如果字节<32或字节==127:
返回r'\M^'+chr(字节^64)
返回r'\M-'+chr(字节)
def vis(bytestr):
“与第(1)款相同”
返回“”。加入(bytestr中c的vischr(c)
vis
生成二进制文件的可逆但可打印的编码;这是我对
cat-v
问题的答案)


请注意,存储在Git存储库中的文件名(在提交下)仅显示为存储在单个
对象中的路径名组件。计算树对象的散列ID是不重要的;我的公共“脚本”中有Python代码可以做到这一点存储库下。

这就是我现在要讲的内容,但我仍然不清楚文件内容部分,因此我不得不在这里提问。您能否将您的问题编辑为关于“对象存储”下描述的某些特定方面这个链接的标题很难理解?使用命令
git cat file-p[sha1]
探索您的存储库对象,您会更好地理解…至少这次,它更“简洁”切中要害+1@torek,根据您的回答,我尝试了这个。
$git cat file-p 16ed
输出:
100644 blob a7036e7253f5e7099e8b68c2fe99ecf5f8b013d3 pom.xml
。然后,
cat pom.xml | git hash object-t blob
输出:
af86ccbdb1f4f1685ffe85cf6837210949a
pom.xml只有一个版本(不确定如何用git术语表示)因此,在使用
git哈希对象时,我不可能引用不同版本的pom.xml。为什么SHA-1不匹配。@samshers:有过滤器(清除和涂抹过滤器)吗和/或crlf hacking已打开?如果是,请使用
pom.xlm | git hash object-t blob
,因为树和索引哈希来自已过滤的内容,而不是工作树内容。(插入适当的命令,不管是什么,作为过滤器-例如,如果工作树副本有CRLF结尾,您可以使用
tr-d'\015'
vonc@VONCAVN7:/mnt/d/git/seec$ /usr/share/doc/zlib1g-dev/examples/zpipe -d < .git/objects/0d/b6225927ef60e21138a9762c41ea0db714ca0d
blob 2142 <full content there...>
$ echo 'hello' | git hash-object -t blob --stdin
ce013625030ba8dba906f756967f9e9ca394464a
$ python3
[...]
>>> import hashlib
>>> s = b'blob 6\0hello\n'
>>> hashlib.sha1(s).hexdigest()
'ce013625030ba8dba906f756967f9e9ca394464a'
$ echo 'hello' | git hash-object -w -t blob --stdin
ce013625030ba8dba906f756967f9e9ca394464a
$ vis .git/objects/ce/013625030ba8dba906f756967f9e9ca394464a
x\^AK\M-J\M-IOR0c\M-HH\M-M\M-I\M-I\M-g\^B\000\^]\M-E\^D\^T$
>>> import zlib
>>> zlib.compress(s, 1)
b'x\x01K\xca\xc9OR0c\xc8H\xcd\xc9\xc9\xe7\x02\x00\x1d\xc5\x04\x14'
>>> import vis
>>> print(vis.vis(zlib.compress(s, 1)))
x\^AK\M-J\M-IOR0c\M-HH\M-M\M-I\M-I\M-g\^B\^@\^]\M-E\^D\^T
def vischr(byte):
    "encode characters the way vis(1) does by default"
    if byte in b' \t\n':
        return chr(byte)
    # control chars: \^X; del: \^?
    if byte < 32 or byte == 127:
        return r'\^' + chr(byte ^ 64)
    # printable characters, 32..126
    if byte < 128:
        return chr(byte)
    # meta characters: prefix with \M^ or \M-
    byte -= 128
    if byte < 32 or byte == 127:
        return r'\M^' + chr(byte ^ 64)
    return r'\M-' + chr(byte)

def vis(bytestr):
    "same as vis(1)"
    return ''.join(vischr(c) for c in bytestr)