为什么按名称删除远程分支会产生错误,而按 ref 删除不会?
Why does deleting a remote branch by name produce an error while deleting by ref does not?
当我尝试按名称 删除不存在的远程 Git 分支 时,我预计会收到错误消息:
$ git push origin --delete non/existent
error: unable to delete 'non/existent': remote ref does not exist
error: failed to push some refs to 'git@github.com:<_replaced_>.git'
$ echo $?
1
但是,通过 ref 删除相同的分支 (例如取自 .git/config
)不被视为错误:
$ git push origin --delete refs/heads/non/existent
remote: warning: Deleting a non-existent ref.
To github.com:<_replaced_>.git
- [deleted] non/existent
$ echo $?
0
为什么会这样?这些命令是否等效?
它们不等价。
一个 ref 要么 完全限定 ,即以 refs/
开头,因此是明确的,要么不是完全限定的,即以除此之外的其他内容开头refs/
.
必须将不完全限定的 ref 转换为完全限定的 ref。排位赛取决于您 git push
的目标。如果它没有找到完全合格的 ref,它会向 git push
的来源报告它无法限定 ref.
完全合格的 ref 当然已经完全合格,所以接收 Git 只是说 "ok, that doesn't exist" 因此要求删除的 Git 很高兴地报告裁判不存在。所以 Git 运行 git push --delete
很高兴,认为一切都很好。
有人可以争辩说 Git 执行 git push
以意识到 "I can't qualify that ref for you" 可能 意味着 [=40] 是合理的=] 这又意味着 "whatever ref you meant, it doesn't exist",这可以使 Git 运行 git push --delete
快乐。但事实并非如此。
请注意,对于匹配两种或多种可能性的模糊引用,我观察到以下内容:
server-repo$ git for-each-ref
11ae6ca18f6325c858f1e3ea2b7e6a045666336d commit refs/heads/ambig
222c4dd303570d096f0346c3cd1dff6ea2c84f83 commit refs/heads/branch
e068bdfce2fd992dc396cb4969327ef5c4d39a43 commit refs/heads/fix-signal
d41117433d7b4431a188c0eddec878646bf399c3 commit refs/heads/foobranch
11ae6ca18f6325c858f1e3ea2b7e6a045666336d commit refs/heads/master
11ae6ca18f6325c858f1e3ea2b7e6a045666336d commit refs/tags/ambig
d41117433d7b4431a188c0eddec878646bf399c3 commit refs/tags/tag-foo
和:
client-repo$ git push --delete origin ambig
error: dst refspec ambig matches more than one
error: failed to push some refs to [server URL]
当我尝试按名称 删除不存在的远程 Git 分支 时,我预计会收到错误消息:
$ git push origin --delete non/existent
error: unable to delete 'non/existent': remote ref does not exist
error: failed to push some refs to 'git@github.com:<_replaced_>.git'
$ echo $?
1
但是,通过 ref 删除相同的分支 (例如取自 .git/config
)不被视为错误:
$ git push origin --delete refs/heads/non/existent
remote: warning: Deleting a non-existent ref.
To github.com:<_replaced_>.git
- [deleted] non/existent
$ echo $?
0
为什么会这样?这些命令是否等效?
它们不等价。
一个 ref 要么 完全限定 ,即以 refs/
开头,因此是明确的,要么不是完全限定的,即以除此之外的其他内容开头refs/
.
必须将不完全限定的 ref 转换为完全限定的 ref。排位赛取决于您 git push
的目标。如果它没有找到完全合格的 ref,它会向 git push
的来源报告它无法限定 ref.
完全合格的 ref 当然已经完全合格,所以接收 Git 只是说 "ok, that doesn't exist" 因此要求删除的 Git 很高兴地报告裁判不存在。所以 Git 运行 git push --delete
很高兴,认为一切都很好。
有人可以争辩说 Git 执行 git push
以意识到 "I can't qualify that ref for you" 可能 意味着 [=40] 是合理的=] 这又意味着 "whatever ref you meant, it doesn't exist",这可以使 Git 运行 git push --delete
快乐。但事实并非如此。
请注意,对于匹配两种或多种可能性的模糊引用,我观察到以下内容:
server-repo$ git for-each-ref
11ae6ca18f6325c858f1e3ea2b7e6a045666336d commit refs/heads/ambig
222c4dd303570d096f0346c3cd1dff6ea2c84f83 commit refs/heads/branch
e068bdfce2fd992dc396cb4969327ef5c4d39a43 commit refs/heads/fix-signal
d41117433d7b4431a188c0eddec878646bf399c3 commit refs/heads/foobranch
11ae6ca18f6325c858f1e3ea2b7e6a045666336d commit refs/heads/master
11ae6ca18f6325c858f1e3ea2b7e6a045666336d commit refs/tags/ambig
d41117433d7b4431a188c0eddec878646bf399c3 commit refs/tags/tag-foo
和:
client-repo$ git push --delete origin ambig
error: dst refspec ambig matches more than one
error: failed to push some refs to [server URL]