当使用树的哈希时,为什么`git checkout`会产生错误`Invalid argument`

时间:2017-08-18 18:08:52

标签: git

我正在尝试创建一个git树并在不使用任何高级命令和提交对象的情况下检查它。所以我初始化了git并创建了两个blob:

$ git init

$ echo ‘f1’ | git hash-object -w --stdin
8e1e71d5ce34c01b6fe83bc5051545f2918c8c2b

$ echo ‘f2’ | git hash-object -w --stdin
9de77c18733ab8009a956c25e28c85fe203a17d7

现在我正在使用mktree

创建一棵树
$ echo -e 
    "100644 blob 8e1e71d5ce34c01b6fe83bc5051545f2918c8c2b\tf1.txt" 
    "100644 blob 9de77c18733ab8009a956c25e28c85fe203a17d7\tf2.txt" 
    | git mktree
bf9571850c4570cd36ffa426343b81364a855911

哪个正确地返回了我的git树哈希。现在我想看看。根据{{​​3}},我可以这样做:

$ git checkout bf9571850c4570cd36ffa426343b81364a855911 .

但它会产生错误:

error: unable to create file f1.txt 100644 blob 9de77c18733ab8009a956c25e28c85fe203a17d7        f2.txt (Invalid argument)

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

您的说明中有些不太明显,因为如果我重新输入

$ echo 'f1' | git hash-object -w --stdin

我得到相同的哈希:

8e1e71d5ce34c01b6fe83bc5051545f2918c8c2b

但如果我尝试剪切和粘贴它们,我会得到一些非常不同的东西。这是因为某些东西(我不确定是什么)损坏了单引号:你的实际上是Unicode U + 2018字符,或LEFT SINGLE QUOTATION MARK

无论如何,因此我不太确定如何使用第三个​​ echo命令,但如果我认为它没有损坏,它实际上是在发送:

100644 blob 8e1e71d5ce34c01b6fe83bc5051545f2918c8c2b\tf1.txt 100644 blob 9de77c18733ab8009a956c25e28c85fe203a17d7\tf2.txt

(其中每个\t代表一个文字制表符)到git mktree,这将使一个条目成为一棵树。试着这个让我:

$ printf "100644 blob 8e1e71d5ce34c01b6fe83bc5051545f2918c8c2b\tf1.txt 100644 blob 9de77c18733ab8009a956c25e28c85fe203a17d7\tf2.txt\n" | git mktree
bf9571850c4570cd36ffa426343b81364a855911

具有相同的树形哈希,并且:

$ git cat-file -p bf9571850
100644 blob 8e1e71d5ce34c01b6fe83bc5051545f2918c8c2b    "f1.txt 100644 blob 9de77c18733ab8009a956c25e28c85fe203a17d7\tf2.txt"

(我在这个stackoverflow输入中留下了一个原始标签,这有点棘手,但在Mac上使用剪切和粘贴)。

将树记录到当前目录中将尝试创建一个名为f1.txt 100644 blob 9de77c18733ab8009a956c25e28c85fe203a17d7\tf2.txt的文件(名称中包含嵌入式选项卡)。大概你的主机操作系统(Windows?)拒绝这样的文件名。

据推测,您想要的是将两条行打印到git mktree中,f1f2文件各一行。 printf命令可能是更好的方法:

$ printf '%s %s %s\t%s\n' \
> 100644 blob 8e1e71d5ce34c01b6fe83bc5051545f2918c8c2b f1.txt \
> 100644 blob 9de77c18733ab8009a956c25e28c85fe203a17d7 f2.txt |
> git mktree
97da1d249d1b56762add1fb35096a46544416c7f
$ git checkout 97da1 -- .
$ ls
f1.txt  f2.txt