【问题标题】:git push failing for certain branch names某些分支名称的 git push 失败
【发布时间】:2016-04-26 08:46:26
【问题描述】:

在我们公司,使用我们的名字来扩展功能的情况并不少见。因此,如果我们在master 上并想要分支一个新功能,我们将创建john/feature-testbob/feature-test2。这一直很有效,直到最近我们的一名队友失去了将任何东西推到我们原点的能力。

她可以创建其他分支就好了,但是如果分支以mira/... 开头,那么它会像这样失败:

$ git push -f
Counting objects: 2, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 243 bytes | 0 bytes/s, done.
Total 2 (delta 1), reused 0 (delta 0)
remote: error: Cannot update the ref 'refs/heads/mira/testing': unable to create directory for logs/refs/heads/mira/testing: No such file or directory
To git@bitbucket.org:<team>/<repo>.git
 ! [remote rejected] mira/testing -> mira/testing (failed to update ref)
error: failed to push some refs to 'git@bitbucket.org:<team>/<repo>.git'

当我在我的机器上尝试这个时,我得到了同样的结果。所以问题似乎出在 Bitbucket 上的远程 git 服务器上。我们尝试删除所有以mira/... 开头的分支,但没有帮助。我已经修剪了远程和本地,运行了git gc,等等。似乎没有任何效果。

有趣的是我们可以进入 Bitbucket,创建一个名为 mira/testbranch 的分支,运行 git fetch,运行 git checkout mira/testbranch,进行更改,提交,然后推送……但推送仍然会失败问题。

有谁知道这是怎么发生的以及我们可以做些什么来解决它?

【问题讨论】:

  • 如果我猜的话,那是因为您的分支的名称中有一个斜线,并且不知何故,您启用的某些接收后日志钩子无法处理它。它尝试为分支创建一个目录,但不是运行mkdir -p $branchname,而是运行mkdir $branchname,但是当分支名称中有斜杠时,它会失败。这只是基于 git 知识的疯狂猜测,以及错误消息,但根本不了解 bitbucket。
  • 尝试这里描述的解决方案:stackoverflow.com/a/42846055/2786215

标签: git bitbucket


【解决方案1】:

问题在服务器上,必须在那里解决(可能通过客户端上的操作;见下文)。

服务器向客户端提供尽可能多的信息(但见下文):

remote: error: Cannot update the ref 'refs/heads/mira/testing': unable to create directory for logs/refs/heads/mira/testing: No such file or directory

从中我们可以得出结论:

  • 服务器配置设置了core.logAllRefUpdates(见下文)
  • 文件logs/refs/heads/mira/testing当前不存在(见下文)
  • logs/refs/heads/mira 中的某些目录/目录也存在/不存在
  • 执行推送的过程也未能创建该目录,因为某些前驱目录不存在(这是神秘的部分,因为 git 会根据需要创建路径中的每个目录)。

可能应该在服务器上进行进一步调查,但最可能的问题是logs/refs/heads/mira 已经作为普通文件而不是目录存在,并且 git 正在使用@987654328 破坏文件路径的EEXIST 错误@ 生成目录序列期间的错误。 (这将是 git 中的一个小错误:无论哪种方式它都必须失败,但它可能会说“无法创建日志/参考/头/米拉/测试,因为日志/参考/头/米拉是一个常规文件”,例如。此外,如果途中有一个未删除的分支(见下文),它应该会给出更清晰的错误消息;这将是 git 中的一个更大的错误。)

假设我的猜测(存在这样的文件)首先是正确的,那么该文件是如何被遗忘的仍然是个谜。可能有一个名为mira 的分支,它需要创建一个名为logs/refs/heads/mira 的引用日志文件,但是当它被删除时——它一定是在某个时候为了创建一个名为mira/testing 的分支;如果已经有一个分支X,你就不能有一个分支X/Y——这也应该删除了reflog。但是如果这的问题,解决方法是在你想要它的内容的时候把文件移开,或者如果不想要它就完全删除它。如果途中有未删除的分支(在分支问题之前出现了 reflog 问题),您可以简单地删除该分支,这也会删除 reflog 文件。

您也可以禁用core.logAllRefUpdates。通常它会被禁用,因为这应该是一个--bare 存储库。

关于core.logAllRefUpdates

the git config documentation 对此进行了很好的描述:

core.logAllRefUpdates

启用引用日志。通过附加新旧 SHA-1、日期/时间和更新原因,将对 ref 的更新记录到文件“$GIT_DIR/logs/”中,但仅在文件存在时.如果此配置变量设置为 true,则会自动为分支头(即 refs/heads/ 下)、远程 refs(即 refs/remotes/ 下)创建缺少的“$GIT_DIR/logs/”文件,注意 refs (即在 refs/notes/) 下,以及符号 ref HEAD。

此信息可用于确定“2 天前”分支的提示是什么提交。

默认情况下,该值在具有关联工作目录的存储库中为 true,在裸存储库中默认为 false。

【讨论】:

    猜你喜欢
    • 2015-07-31
    • 2021-09-01
    • 2016-05-20
    • 2016-12-07
    • 2014-07-20
    • 2012-07-08
    • 2013-08-25
    • 2012-02-17
    • 1970-01-01
    相关资源
    最近更新 更多