如果给hash-object的filename参数与原始文件名不同,则无法创建commit

时间:2018-05-22 15:10:59

标签: git git-plumbing

我正在使用git管道命令来更好地理解其内部机制。我试图在不使用git commit命令的情况下重现提交。让我们创建一个blob

$ git init
$ echo "I'm an apple" > apple.txt
$ git hash-object -w apple.txt
2d1b0d728be34bfd5e0df0c11b01d61c77ccdc14

现在让我们将其添加到索引中,但使用不同的文件名

$ git update-index --add --cacheinfo 100644 2d1b0d728be34bfd5e0df0c11b01d61c77ccdc14 orange.txt

这是git status的输出:

$ git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

    new file:   orange.txt

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    deleted:    orange.txt

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    apple.txt

这里发生了什么?

apple.txt 仍然存在但未跟踪,这对我来说似乎很正常,因为我将SHA-1提供给blob对象,该对象仅包含内容的文件。

让我们继续写下树:

$ git write-tree
abbb70126eb9e77aaa65efbe0af0330bda48adf7
$ git cat-file -p abbb70126eb9e77aaa65efbe0af0330bda48adf7
100644 blob 2d1b0d728be34bfd5e0df0c11b01d61c77ccdc14    orange.txt
$ git cat-file -p 2d1b0d728be34bfd5e0df0c11b01d61c77ccdc14
I'm an apple

让我们通过创建指向此树的提交来完成此操作:

$ echo "Add fruit" | git commit-tree abbb70126eb9e77aaa65efbe0af0330bda48adf7
57234c35c0d58713d2b4f57b695043e5331afe58
$ git cat-file -p a4386cb82e1f6d1755e47ace1f378df35df31967
tree abbb70126eb9e77aaa65efbe0af0330bda48adf7
author Gregoire Borel <gregoire.borel@nxxx.xx> 1527001408 +0200
committer Gregoire Borel <gregoire.borel@xxx.xx> 1527001408 +0200

Add fruit

现在,如果我运行git status,输出与上面给出的相同。为什么?此外,提交似乎没有创建:

$ git log
fatal: your current branch 'master' does not have any commits yet

我错过了什么吗?

2 个答案:

答案 0 :(得分:3)

您创建了提交,但您没有更新任何指向它的引用。您仍然要检查未出生的master分支机构。 (默认情况下,请记住git log显示已检出的内容的历史记录;即使您告诉它显示&#34;所有&#34;它往往只能通过引用可以访问的内容。 )

您没有在上面显示它,但是当您发布commit-tree时,它应该在标准输出上打印一个哈希值(在我的测试中,按照您的步骤进行操作)。所以,然后将其称为<commit-hash>,您可以说

git merge <commit-hash>

更改文件名主要是红鲱鱼。在这种情况下,索引和数据库都不包含知道apple.txt的对象,因此apple.txt只是工作树中未跟踪的文件。

更新 - 作为补充说明,您创建新的提交时没有父级,这是有道理的,因为您的回购中没有任何提交(如果我正在阅读你的场景正确)。通常,如果向现有(和签出)分支添加新提交,则需要提供类似-p HEAD的参数 - 即使这样,commit-tree命令也只会赢得更新分支。

如果您想避免合并(支持较低级命令),则替代方案为git update-ref,如

git update-ref refs/heads/master 50b7

(这有点危险,因为假设你知道自己在做什么,即使你犯了错误,也更容易做错事......但是那&# 39;管道命令的性质。)

答案 1 :(得分:1)

你仍然需要运行

let firstResponder = UIResponder.first

这会将您的新提交注册为当前HEAD