可以获取但找不到分支
Can fetch but then can not find branch
这种偶尔出现的 Git 细微差别让我感到困惑。有人可以解释这里发生了什么吗?我正在从一个存储库中获取(忽略来自配置的重定向规则)并推入另一个存储库(应用来自配置的重定向规则):
$ HOME=/dev/null git fetch origin refs/heads/8.9.170
* branch 8.9.170 -> FETCH_HEAD
$ git push origin refs/heads/8.9.170
error: src refspec refs/heads/8.9.170 does not match any
$ git rev-parse refs/heads/8.9.170
refs/heads/8.9.170
fatal: ambiguous argument 'refs/heads/8.9.170': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
url = https://chromium.googlesource.com/v8/v8.git
fetch = +refs/heads/*:refs/remotes/origin/*
fetch = +refs/branch-heads/*:refs/branch-heads/*
[branch "master"]
remote = origin
merge = refs/heads/master
与此同时,获取不存在的 branch/ref 会引发明显的错误:
$ HOME=/dev/null git fetch origin refs/heads/obviously/invalid
fatal: couldn't find remote ref refs/heads/obviously/invalid
TL;DR
考虑使用:
git push origin FETCH_HEAD:refs/heads/8.9.170
查看原因的详细答案。
长(大概)
你的 .git/config
的这一部分看起来有点奇怪,但并非完全奇怪:
[remote "origin"]
url = https://chromium.googlesource.com/v8/v8.git
fetch = +refs/heads/*:refs/remotes/origin/*
fetch = +refs/branch-heads/*:refs/branch-heads/*
第二行 fetch =
乍一看似乎不太可能匹配任何内容:Git 本身不使用名称空间 refs/branch-heads/
做任何事情。如果它根本不匹配,那很好;这是无害的。如果它确实匹配某些内容,它将强制更新您获取的任何 refs/branch-heads/
个名称。你明确地没有获取任何东西,但起初,这似乎是一件奇怪的事情。
但事实证明 https://chromium.googlesource.com/v8/v8.git
里面有一大堆 refs/branch-heads/
个名字(我检查了 git ls-remote
并看到他们)。他们的目的是什么,我不知道。他们也有标准的 refs/heads/
分支名称。因为他们确实有这些 refs/branch-heads/
名称,所以您应该格外小心,我注意到您可以在下面做一个完整的 fetch
。
同时,这里输出:
$ HOME=/dev/null git fetch origin refs/heads/8.9.170
* branch 8.9.170 -> FETCH_HEAD
表明您拥有一个真正古老的 Git 二进制文件。这加上其他一些项目可能是您随后所有麻烦的根源。 Git 从 1.8.4 开始的版本将打印:
$ HOME=/dev/null git fetch origin refs/heads/8.9.170
* branch 8.9.170 -> FETCH_HEAD
<hash>..<hash> 8.9.170 -> origin/8.9.170
因为现代 Git 将根据 fetch =
设置“机会性地更新”任何获取的分支,并且当您有一个非标准设置时,它之前是标准设置。所以你一定有一个严重过时的Git。不过,您 可以 仍然可以用它完成工作;你只需要更明确一点,by 运行ning:
HOME=/dev/null git fetch origin +refs/heads/8.9.170:refs/remotes/origin/8.9.170
这次 将 更新 refs/remotes/origin/8.9.170
(强制更新,因为有加号),或者更简单地说:
HOME=/dev/null git fetch origin
它获取所有内容并根据 fetch =
行更新所有名称。请注意,这将遵守您对 refs/branch-heads/
实体的额外规则,更新您所有的远程跟踪名称 (refs/remotes/origin/*
) 和这些奇怪的名称(无论它们是什么)。
尽管如此,您只是将新的提交哈希 ID 放入特殊的 .git/FETCH_HEAD
文件中,git fetch
将其写入其中,以便 git pull
可以找出什么刚被拿走。既然你不是运行宁git pull
,这对你来说用处不大。但这就是为什么我们看到提到 FETCH_HEAD
.
的输出
现在,我们可以继续 git push
,您需要对其进行更改。您正在使用(并获得):
$ git push origin refs/heads/8.9.170
error: src refspec refs/heads/8.9.170 does not match any
您没有名为 8.9.170
的分支。即使你有一个现代的 Git(而不是 pre-1.8.4 Git),你仍然没有一个名为 [=39= 的 分支 ].相反,您将拥有一个名为 8.9.170
的 远程跟踪名称 。因此,此时您有两个选择:
创建一个名为 8.9.170 的 分支 。然后,您的命令将按原样运行。
从您拥有的名称或哈希 ID 推送。
对于选项 1,如果您有一个创建了远程跟踪名称的现代 Git,此方法效果更好。您可以简单地 运行 git switch 8.9.170
或 git checkout 8.9.170
,这将创建该分支,然后将其检出。或者,为了避免必须检查它(这需要一点时间:铬源很大),您可以 运行 git branch 8.9.170 origin/8.9.170
,它从 origin/8.9.170
创建 8.9.170
。缺少其中任何一个,您可以从 .git/FETCH_HEAD
中提取提交哈希 ID,或使用名称 FETCH_HEAD
来创建该分支。
对于更简单的选项 2,您可以 运行 此命令:
git push origin FETCH_HEAD:refs/heads/8.9.170
这是前面的 TL;DR。名称 FETCH_HEAD
指的是(暂时!)由 git fetch
获得的哈希 ID,由于您的 Git 是古老的,因此无法创建远程跟踪名称。这个临时 FETCH_HEAD
存储会持续到 next git fetch
,它会覆盖它,所以这必须很快完成。 (这就是为什么这适用于 git pull
,仅 运行 秒 git fetch
,然后 立即 运行 秒 Git 命令使用 .git/FETCH_HEAD
中的值,然后 它们可以被替换。)
这种偶尔出现的 Git 细微差别让我感到困惑。有人可以解释这里发生了什么吗?我正在从一个存储库中获取(忽略来自配置的重定向规则)并推入另一个存储库(应用来自配置的重定向规则):
$ HOME=/dev/null git fetch origin refs/heads/8.9.170
* branch 8.9.170 -> FETCH_HEAD
$ git push origin refs/heads/8.9.170
error: src refspec refs/heads/8.9.170 does not match any
$ git rev-parse refs/heads/8.9.170
refs/heads/8.9.170
fatal: ambiguous argument 'refs/heads/8.9.170': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
url = https://chromium.googlesource.com/v8/v8.git
fetch = +refs/heads/*:refs/remotes/origin/*
fetch = +refs/branch-heads/*:refs/branch-heads/*
[branch "master"]
remote = origin
merge = refs/heads/master
与此同时,获取不存在的 branch/ref 会引发明显的错误:
$ HOME=/dev/null git fetch origin refs/heads/obviously/invalid
fatal: couldn't find remote ref refs/heads/obviously/invalid
TL;DR
考虑使用:
git push origin FETCH_HEAD:refs/heads/8.9.170
查看原因的详细答案。
长(大概)
你的 .git/config
的这一部分看起来有点奇怪,但并非完全奇怪:
[remote "origin"] url = https://chromium.googlesource.com/v8/v8.git fetch = +refs/heads/*:refs/remotes/origin/* fetch = +refs/branch-heads/*:refs/branch-heads/*
第二行 fetch =
乍一看似乎不太可能匹配任何内容:Git 本身不使用名称空间 refs/branch-heads/
做任何事情。如果它根本不匹配,那很好;这是无害的。如果它确实匹配某些内容,它将强制更新您获取的任何 refs/branch-heads/
个名称。你明确地没有获取任何东西,但起初,这似乎是一件奇怪的事情。
但事实证明 https://chromium.googlesource.com/v8/v8.git
里面有一大堆 refs/branch-heads/
个名字(我检查了 git ls-remote
并看到他们)。他们的目的是什么,我不知道。他们也有标准的 refs/heads/
分支名称。因为他们确实有这些 refs/branch-heads/
名称,所以您应该格外小心,我注意到您可以在下面做一个完整的 fetch
。
同时,这里输出:
$ HOME=/dev/null git fetch origin refs/heads/8.9.170 * branch 8.9.170 -> FETCH_HEAD
表明您拥有一个真正古老的 Git 二进制文件。这加上其他一些项目可能是您随后所有麻烦的根源。 Git 从 1.8.4 开始的版本将打印:
$ HOME=/dev/null git fetch origin refs/heads/8.9.170
* branch 8.9.170 -> FETCH_HEAD
<hash>..<hash> 8.9.170 -> origin/8.9.170
因为现代 Git 将根据 fetch =
设置“机会性地更新”任何获取的分支,并且当您有一个非标准设置时,它之前是标准设置。所以你一定有一个严重过时的Git。不过,您 可以 仍然可以用它完成工作;你只需要更明确一点,by 运行ning:
HOME=/dev/null git fetch origin +refs/heads/8.9.170:refs/remotes/origin/8.9.170
这次 将 更新 refs/remotes/origin/8.9.170
(强制更新,因为有加号),或者更简单地说:
HOME=/dev/null git fetch origin
它获取所有内容并根据 fetch =
行更新所有名称。请注意,这将遵守您对 refs/branch-heads/
实体的额外规则,更新您所有的远程跟踪名称 (refs/remotes/origin/*
) 和这些奇怪的名称(无论它们是什么)。
尽管如此,您只是将新的提交哈希 ID 放入特殊的 .git/FETCH_HEAD
文件中,git fetch
将其写入其中,以便 git pull
可以找出什么刚被拿走。既然你不是运行宁git pull
,这对你来说用处不大。但这就是为什么我们看到提到 FETCH_HEAD
.
现在,我们可以继续 git push
,您需要对其进行更改。您正在使用(并获得):
$ git push origin refs/heads/8.9.170 error: src refspec refs/heads/8.9.170 does not match any
您没有名为 8.9.170
的分支。即使你有一个现代的 Git(而不是 pre-1.8.4 Git),你仍然没有一个名为 [=39= 的 分支 ].相反,您将拥有一个名为 8.9.170
的 远程跟踪名称 。因此,此时您有两个选择:
创建一个名为 8.9.170 的 分支 。然后,您的命令将按原样运行。
从您拥有的名称或哈希 ID 推送。
对于选项 1,如果您有一个创建了远程跟踪名称的现代 Git,此方法效果更好。您可以简单地 运行 git switch 8.9.170
或 git checkout 8.9.170
,这将创建该分支,然后将其检出。或者,为了避免必须检查它(这需要一点时间:铬源很大),您可以 运行 git branch 8.9.170 origin/8.9.170
,它从 origin/8.9.170
创建 8.9.170
。缺少其中任何一个,您可以从 .git/FETCH_HEAD
中提取提交哈希 ID,或使用名称 FETCH_HEAD
来创建该分支。
对于更简单的选项 2,您可以 运行 此命令:
git push origin FETCH_HEAD:refs/heads/8.9.170
这是前面的 TL;DR。名称 FETCH_HEAD
指的是(暂时!)由 git fetch
获得的哈希 ID,由于您的 Git 是古老的,因此无法创建远程跟踪名称。这个临时 FETCH_HEAD
存储会持续到 next git fetch
,它会覆盖它,所以这必须很快完成。 (这就是为什么这适用于 git pull
,仅 运行 秒 git fetch
,然后 立即 运行 秒 Git 命令使用 .git/FETCH_HEAD
中的值,然后 它们可以被替换。)