git-push结合镜像库refspec删除其他分支?

git-push combined with refspec from mirror repositories deletes other branches?

有两个远程仓库如下。

使用 git push --mirror 从镜像推送 refs 到原始远程按预期工作。但是,当 refspec(例如分支名称)与 git-push 组合时,Git 会尝试从原始存储库和镜像存储库中删除除指定分支之外的所有其他分支。

  1. 为什么 Git 尝试删除其他分支?
  2. 在远程仓库中没有设置 receive.denyDeletes 的情况下,如何防止删除远程分支? (刚才误删了远程分支。)

注意:我现在使用的是git v2.18.0,据我所知,git push --mirror <repo> <refsepc>在旧版本中是不允许的,例如git v1.7.1

bash-4.1$ cd mirror.git/
bash-4.1$ git branch
* master
  new_branch

bash-4.1$ git config --list | grep remote
remote.origin.url=/user/han/git/original.git/
remote.origin.fetch=+refs/*:refs/*
remote.origin.mirror=true

bash-4.1$ git push --mirror
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 16 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 280 bytes | 280.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To /user/han/git/original.git/
 * [new branch]      new_branch -> new_branch

bash-4.1$ git push origin master
To /user/han/git/original.git/
 - [deleted]         new_branch

specification for the --mirror option in git push是:

Instead of naming each ref to push, specifies that all refs under refs/ (which includes but is not limited to refs/heads/, refs/remotes/, and refs/tags/) be mirrored to the remote repository. Newly created local refs will be pushed to the remote end, locally updated refs will be force updated on the remote end, and deleted refs will be removed from the remote end. This is the default if the configuration option remote.<remote>.mirror is set.

(我的粗体字)。将 --mirror 与 command-line refspec 结合使用会导致您的 Git 认为命令行中提到的所有 而不是 的引用都已删除,这会导致您的 Git 发送 "delete this ref" 请求1 给另一个 Git.

有人可能会争辩说这是一个错误——你自己的 Git 应该简单地拒绝将 --mirror 与 command-line 参数 refspecs 结合的尝试——这肯定有点不友好.另请参阅 --prune,它具有类似的行为,,旨在与 command-line refspecs 结合使用。


1像往常一样,它们采用礼貌的形式 "please, if you're willing, do <thing>",除非您在命令行中添加 --force 标志,或者在命令行中添加加号生成请求的 refspec。不幸的是,默认情况下会遵守 删除 分支的礼貌请求,这与以非 fast-forward.

方式移动分支的礼貌请求不同。