Git push: refs/head/my/subBranch 存在,无法创建

在服务器上的回购中创建一些子文件夹是不可能的吗?

如果我这样做:

git push origin dev/master

一切工作找到

但如果我这么做了

git push origin dev/sub/master

我知道了:

error: 'refs/heads/dev/sub' exists; cannot create 'refs/heads/dev/sub/master'

我用 git branch -r检查过,直接用 ssh 检查过,没有已经创建的 dev/sub 文件夹。

怎么了?

129189 次浏览

这不是一个 文件夹的存在,它是一个 树枝。(嗯,可能有一个文件夹/目录涉及到某个地方ーー也可能没有,因为引用被“打包”,不再作为目录中的文件存在。)

  • 如果存在分支 b,则不能创建名为 b/anything的分支
  • 同样,如果存在分支 dev/b,则无法创建 dev/b/c

这是 git 的内部限制。在这种特殊情况下,远程 origin有一个名为 dev/sub的分支(不管您是否拥有它,重要的是远程是否拥有它)。为了在 origin上创建一个名为 dev/sub/master的分支,必须首先删除 origin上名为 dev/sub的分支:

git push origin :dev/sub

(当然,删除这个分支可能会删除那里的一些重要内容,所以要确保您知道自己在做什么。一般来说,您可能希望首先使用 git fetch origin,捕获它们的 dev/sub作为您的 origin/dev/sub。然后可以创建一个名为 dev/renamed-sub的本地分支,指向相同的提交,在远程上创建 dev/renamed-sub,删除远程 dev/sub,然后在远程上创建 dev/sub/master。)


如果您可以登录到远程(承载 origin的系统) ,那么您可以进入那里的存储库,并简单地重命名本地 dev/sub分支。(根据下面的评论,我怀疑那里也有一个坏掉的自动部署脚本,它可能应该被修复为只部署“可部署”分支,而不是被推送的所有东西。但我只是在猜测。)

我处于一种甚至无法获取的状态,因为我的回购商有关于不存在的远程分支的信息,而我甚至还没有检查过。 我通过以下组合解决了这个问题:

  • 列出远程分支的本地副本
  • 列出远程分支
  • git fetch --prune origin更新远程分支的本地副本(这对我没什么帮助)
  • 删除关于已删除的远程分支的信息(是这个)

试试这个命令来修复它:

git gc

在当前存储库中运行许多内部管理任务并删除不可访问的对象(通过调用 git prunegit fsck --unreachable)。

阅读更多: git help gc(医生)和 git help prune(医生)。

Git-gc-清理不必要的文件并优化本地存储库

Git-Prune-从对象数据库中删除所有不可到达的对象

#!/usr/bin/env bash
echo "update-ref delete refs/tags"
log="git-update-ref-errors.log"
script="./git-update-ref-exist-tags-delete.sh"
git_command="git update-ref -d refs/tags"


echo "log errors from ${git_command} to ${log}"
${git_command} 2>&1 | > ${log}
echo "show errors to ${log}"
cat ${log}
echo create ${script}
touch ${script}
echo "add execute (+x) permissions to ${script}"
chmod +x ${script}
echo "generate ${script} from errors log ${log}"
${git_command} 2>&1 | grep 'exists' | sed -n "s:.*\: 'refs/tags/\(.*\)' exists;.*:git tag -d '\1':p" >> ${script}
echo "execute ${script}"
${script}


echo fetch
log="git-fetch-errors.log"
script="./git-fetch-exist-tags-delete.sh"
git_command="git fetch"
echo "log errors from ${git_command} to ${log}"
${git_command} 2>&1 | > ${log}
echo "show errors from ${log}"
cat ${log}
echo create ${script}
touch ${script}
echo "add execute (+x) permissions to ${script}"
chmod +x ${script}
echo "generate ${script} from errors log ${log}"
${git_command} 2>&1 | grep 'exists' | sed -n "s:.*\: 'refs/tags/\(.*\)' exists;.*:git tag -d '\1':p" >> ${script}
echo "execute ${script}"
${script}
git fetch


echo pull
log="git-pull-errors.log"
script="./git-pull-exist-tags-delete.sh"
git_command="git pull"
echo "log errors from ${git_command} to ${log}"
${git_command} 2>&1 | > ${log}
echo "show errors from ${log}"
cat ${log}
echo create ${script}
touch ${script}
echo "add execute (+x) permissions to ${script}"
chmod +x ${script}
echo "generate ${script} from errors log ${log}"
${git_command} 2>&1 | grep 'exists' | sed -n "s:.*\: 'refs/tags/\(.*\)' exists;.*:git tag -d '\1':p" >> ${script}
echo "execute ${script}"
${script}
git pull


echo push
log="git-push-errors.log"
script="./git-push-exist-tags-delete.sh"
git_command="git push"
echo "log errors from ${git_command} to ${log}"
${git_command} 2>&1 | > ${log}
echo "show errors from ${log}"
cat ${log}
echo create ${script}
touch ${script}
echo "add execute (+x) permissions to ${script}"
chmod +x ${script}
echo "generate ${script} from errors log ${log}"
${git_command} 2>&1 | grep 'exists' | sed -n "s:.*\: 'refs/tags/\(.*\)' exists;.*:git tag -d '\1':p" >> ${script}
echo "execute ${script}"
${script}
git push

上面的脚本将错误记录为 XXX 错误。记录并通过生成和运行 XXX- 存在-标签-删除来修复它们。Sh 自动从 XXX-错误。使用以下命令记录:

  1. Git update-ref-d refs/tag
  2. 去捡回来
  3. 饭桶拉
  4. 推车

目前接受的答案没有帮助我,因为我没有一个远程回购裁判删除-它纯粹是在我的本地!因此,如果你处于这种情况,以下是你应该做的:

这就是我所面临的问题:

$ git fetch origin
error: cannot lock ref 'refs/remotes/origin/fix/sub-branch':
'refs/remotes/origin/fix' exists; cannot create
'refs/remotes/origin/fix/sub-branch'
From <repo URL>
! [new branch]      fix/sub-branch          -> origin/fix/sub-branch
(unable to update local ref)

我尝试了接受的答案的建议,但得到了这个:

$ git push origin :fix
error: unable to delete 'fix': remote ref does not exist
error: failed to push some refs to <repo URL>

因此,裁判甚至不存在于 origin-它显然只是徘徊在我当地的回购的地方。所以我运行 $ git remote show me,它产生了:

Remote branches:
...
refs/remotes/origin/fix             stale (use 'git remote prune' to remove)
...

这就清楚地说明了问题的解决方案:

$ git remote prune origin
Pruning origin
URL: <redacted>
* [pruned] origin/fix

这样一来,问题就消失了:

$ git fetch origin
remote: Counting objects: 5, done.
remote: Total 5 (delta 2), reused 2 (delta 2), pack-reused 3
Unpacking objects: 100% (5/5), done.
From <repo URL>
* [new branch]      fix/sub-branch          -> origin/fix/sub-branch

git remote prune origin帮我解决了这个问题

对我来说—— >

错误 =

fatal: cannot lock ref 'refs/heads/release/wl/2.3': 'refs/heads/release/wl'
exists; cannot create 'refs/heads/release/wl/2.3'

解决方案 =

$~ git update-ref -d refs/heads/release/wl
$~ git checkout release/wl/2.3

作为一个 windows 用户,到目前为止没有一个解决方案能够解决我的问题。我看到这个错误的原因是(使用 OP 的分支名称)我试图创建一个分支 dev/sub,但是有人创建了一个名为 Dev的分支,正如我们所知道的,windows 有一个不区分大小写的文件系统。

所以当 windows 尝试下拉 dev/sub时,它首先尝试创建文件夹 dev,但是它不能,因为 Dev已经存在了。

解决方案是使用 git branch -d Dev && git push origin :Dev在本地和远程删除 Dev分支。

接下来的另一个教训是,分支名称应该始终使用小写字母,以避免出现这种问题。

如果所有其他方法都失败,请检查您的回购系统对分支名称没有限制。在我的例子中,您只能创建以 SD-<number>开头的分支。任何其他的命名都只能给你一个通用的名字:

remote: error: cannot lock ref 'refs/heads/mybranch': 'refs/heads/mybranch/environment-variables' exists; cannot create 'refs/heads/mybranch'
To git.example.com:project/repository.git
! [remote rejected] mybranch -> mybranch (failed to update ref)
error: failed to push some refs to 'git@git.example.com:project/repository.git'

我知道这个问题已经有答案了,但是对我来说没有用。我不关心本地的变化,因为它已经被推高,但有问题拉回来。在我的例子中,我们在将“修复程序”作为分支改为将父文件夹作为“修复程序”的文件夹系统之间做了一半的改变。

修复 —— hotfix/1234 _ bug —— hotfix/3456 _ bug

所以我得到了下面的错误:

Fetching from origin Error: cannot lock ref 'refs/remotes/origin/hotfix/1234_bug': 'refs/remotes/origin/hotfix' exists; cannot create 'refs/remotes/origin/hotfix'

在寻找类似的错误之后,我终于在一个讨论线程 给你上找到了解决方案。

git remote prune origin
git checkout -b hotfix/my-new-branch


ga
gm "my commit"


gp --set-upstream origin hotfix/subscribers-function

dev/sub重命名为 dev/sub/something,然后可以创建分支 dev/sub/master