为什么git update-ref接受非/ refs引用?

Hen*_*ing 9 git reference

虽然像"git log"这样的命令会很乐意接受同一参考的不同表达式,例如

refs/heads/master
heads/master
master
Run Code Online (Sandbox Code Playgroud)

对于"git update-ref",情况并非如此.例如

git update-ref master HEAD^
Run Code Online (Sandbox Code Playgroud)

是不一样的

git update-ref refs/heads/master HEAD^
Run Code Online (Sandbox Code Playgroud)

第一个命令创建一个新的ref .git/master(反过来引入了关于refs/heads/master的歧义).只有第二个命令真正更新了主人的脑袋.(git的/参/头/主)

为什么git update-ref接受没有"refs /"前缀的引用?是否应该至少有警告或命令行选项来强制创建此类引用?

我花了很长时间才弄明白为什么

git update-ref master HEAD^
Run Code Online (Sandbox Code Playgroud)

没有按预期工作.

Enr*_*lio 7

TL;博士

主要原因git loggit update-ref行为方式不同的原因是因为它git-log是一个高级命令 - 因此设计为用户友好的 - 而且git-update-ref是一个用于脚本的低级命令.

瓷器与管道

在Git的说法中,高级命令被称为瓷器,而低级命令被统称为管道.

瓷器命令旨在由人类交互使用,因此暴露了熟悉的高级概念,例如符号引用.另一方面,管道命令旨在以编程方式使用- 通常在脚本中 - 并允许直接操作Git的内部文件系统结构.

git的更新-REF

虽然git-log是能够解决的引用,git-update-ref-它是一个管道命令-解释的第一个参数无论是作为符号连接或一个普通的文件名取决于如何自行指定它.

文档:

它只跟着真正的符号链接,如果它们以"refs /"开头:否则它只会尝试读取它们并将它们更新为常规文件.

这就是为什么如果你说git update-ref master <value>它将master视为文件名并在.git目录中创建它.同样的道理,当你说git update-ref HEAD <value>它将写入<value>.git/HEAD文件中.

  • 好吧,`update-ref`没有关于你应该和不应该做什么的意见.作为一个低级命令,它只是允许你操纵Git的内部文件系统.通常,您不会在_.git_目录中创建分支引用,而是在[`HEAD`]等其他类型或引用中创建分支引用(https://git-scm.com/book/en/v2/Git-Internals-Git-参考#The-HEAD)确实存在,你也应该能够更新它们. (2认同)