如何在没有 Git 的情况下将 Git SHA1 分配给文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/552659/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to assign a Git SHA1's to a file without Git?
提问by git-noob
As I understand it when Git assigns a SHA1 hash to a file this SHA1 is unique to the file based on its contents.
据我了解,当 Git 将 SHA1 哈希分配给文件时,此 SHA1 根据其内容对文件是唯一的。
As a result if a file moves from one repository to another the SHA1 for the file remains the same as its contents have not changed.
因此,如果文件从一个存储库移动到另一个存储库,则该文件的 SHA1 保持不变,因为其内容没有改变。
How does Git calculate the SHA1 digest? Does it do it on the full uncompressed file contents?
Git 如何计算 SHA1 摘要?它是否对完整的未压缩文件内容执行此操作?
I would like to emulate assigning SHA1's outside of Git.
我想模拟在 Git 之外分配 SHA1。
回答by Ferdinand Beyer
This is how Git calculates the SHA1 for a file (or, in Git terms, a "blob"):
这是 Git 计算文件(或者,用 Git 术语来说,“blob”)的 SHA1 的方式:
sha1("blob " + filesize + "sha1("blob 0sha1("blob 7from hashlib import sha1
def githash(data):
s = sha1()
s.update("blob %uecho -en "blob ${#CONTENTS}git_id () { printf 'blob %s/// Calculates the SHA1 for a given string
let calcSHA1 (text:string) =
text
|> System.Text.Encoding.ASCII.GetBytes
|> (new System.Security.Cryptography.SHA1CryptoServiceProvider()).ComputeHash
|> Array.fold (fun acc e ->
let t = System.Convert.ToString(e, 16)
if t.Length = 1 then acc + "0" + t else acc + t)
""
/// Calculates the SHA1 like git
let calcGitSHA1 (text:string) =
let s = text.Replace("\r\n","\n")
sprintf "blob %d%c%s" (s.Length) (char 0) s
|> calcSHA1
' "$(ls -l "" | awk '{print ;}')" | cat - "" | sha1sum | awk '{print }'; }
$CONTENTS" | sha1sum
" % len(data))
s.update(data)
return s.hexdigest()
foobar\n") = "323fae03f4606ea9991df8befbb2fca795e648fa"
$ echo "foobar" > foo.txt
$ git hash-object foo.txt
323fae03f4606ea9991df8befbb2fca795e648fa
") = "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"
$ touch empty
$ git hash-object empty
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
" + data)
So you can easily compute it yourself without having Git installed. Note that "\0" is the NULL-byte, not a two-character string.
因此,您无需安装 Git 即可轻松地自行计算。请注意,“\0”是 NULL 字节,而不是两个字符的字符串。
For example, the hash of an empty file:
例如,一个空文件的哈希值:
import os
from hashlib import sha1
def hashfile(filepath):
filesize_bytes = os.path.getsize(filepath)
s = sha1()
s.update(b"blob %uuse strict;
use warnings;
use Digest::SHA1;
my @input = <>;
my $content = join("", @input);
my $git_blob = 'blob' . ' ' . length($content) . "#!/usr/bin/env perl
use Digest::SHA1;
my $content = do { local $/ = undef; <> };
print Digest::SHA1->new->add('blob '.length($content)."perl -MDigest::SHA1 -E '$/=undef;$_=<>;say Digest::SHA1->new->add("blob ".length()."require 'digest/sha1'
def git_hash(file)
data = File.read(file)
size = data.bytesize.to_s
Digest::SHA1.hexdigest('blob ' + size + "#!/bin/sh
(
echo -en 'blob '"$(stat -c%s "")"'##代码##';
cat ""
) | sha1sum | cut -d\ -f 1
" + data)
end
".$_)->hexdigest' < file
".$content)->hexdigest(), "\n";
" . $content;
my $sha1 = Digest::SHA1->new();
$sha1->add($git_blob);
print $sha1->hexdigest();
" % filesize_bytes)
with open(filepath, 'rb') as f:
s.update(f.read())
return s.hexdigest()
Another example:
另一个例子:
##代码##Here is a Python implementation:
这是一个 Python 实现:
##代码##回答by knittl
A little goodie: in shell
一个小东西:在壳里
##代码##回答by CB Bailey
You can make a bash shell function to calculate it quite easily if you don't have git installed.
如果你没有安装 git,你可以制作一个 bash shell 函数来很容易地计算它。
##代码##回答by Dale Hagglund
Take a look at the man page for git-hash-object. You can use it to compute the git hash of any particular file. I thinkthat git feeds more than just the contents of the file into the hash algorithm, but I don't know for sure, and if it does feed in extra data, I don't know what it is.
查看git-hash-object的手册页。您可以使用它来计算任何特定文件的 git 哈希。我认为git 不仅仅是将文件的内容提供给哈希算法,但我不确定,如果它确实提供了额外的数据,我不知道它是什么。
回答by forki23
This is a solution in F#.
这是 F# 中的解决方案。
回答by Tomer
Full Python3 implementation:
完整的 Python3 实现:
##代码##回答by Alec the Geek
And in Perl (see also Git::PurePerl at http://search.cpan.org/dist/Git-PurePerl/)
在 Perl 中(另见http://search.cpan.org/dist/Git-PurePerl/ 上的Git::PurePerl )
##代码##回答by dolmen
In Perl:
在 Perl 中:
##代码##As a shell command:
作为 shell 命令:
##代码##回答by Leif
Using Ruby, you could do something like this:
使用 Ruby,您可以执行以下操作:
##代码##回答by Fordi
A little Bash script that should produce identical output to git hash-object
:
一个小 Bash 脚本应该产生与以下相同的输出git hash-object
: