【问题标题】:git - working with remote branches from a bare repogit - 使用来自裸仓库的远程分支
【发布时间】:2021-05-27 09:35:45
【问题描述】:

我想用 github 上的一个项目(不是我的)做一些时髦的事情。所以我想基本上克隆它,但我不想有一个工作树......所以这就是我所做的:我在本地创建一个裸仓库,然后我向 github 仓库添加了一个远程仓库。我取了,我得到了那个 repo 包含的所有东西......我是一个快乐的人......直到我想检查可用的分支:

$ git branch -a
$

好吧...这不是我所期望的。如果我尝试检查 repo 中的任何分支(我知道那里存在),我只会让 git 告诉我引用不存在:

$ git show --summary origin/master
fatal: ambiguous argument 'origin/master': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

如何从我的裸仓库中的远程仓库寻址分支(或实际上任何东西)?

更新

我认为 git 应该能够处理这个问题的假设实际上是正确的。它确实可以正确管理它......但是,因为它是一个大项目,git 在添加远程后运行 fetch 时失败了......并且我之前没有收到该错误消息。 :-O

$ git fetch upstream
remote: Enumerating objects: 60400, done.
remote: Counting objects: 100% (60400/60400), done.
remote: Compressing objects: 100% (32/32), done.
Receiving objects: 100% (4133663/4133663), 1.41 GiB | 12.29 MiB/s, done.
remote: Total 4133663 (delta 60370), reused 60389 (delta 60368), pack-reused 4073263
Connection to github.com closed by remote host.
Resolving deltas: 100% (3134856/3134856), done.

所以……总而言之,显然是我的错。

【问题讨论】:

  • 你比我知道的更多,但我想知道:如果你要获取,那么裸回购的意义何在?正如您所说,您拥有远程存储库包含的所有内容 - 因此您不可能试图节省空间。有“没有工作树”的原因大概是为了让你可以使用 this repo 作为遥控器?这是重点吗?谢谢
  • 使用git show --summary master。裸仓库不需要远程跟踪分支,所以默认没有origin/master这样的分支。
  • @matt 我只是想从中获得一些乐趣,并不打算实际处理任何文件......在我的情况下,我想使用 gource 生成视频。
  • @eftshift0 先试试git remote update
  • @ElpieKay, git remote update 实际上把它拉下来并创建了远程分支和标签。您能否将其添加为答案,并在可能的情况下解释为什么在初始获取后运行git remote update 是必要的?我本来希望获取生成这些引用...实际上在我的情况下,而不是执行git remote add; git fetch,运行git remote add; git update 会成功吗?我应该运行git update 而不是运行git fetch

标签: git git-remote git-bare


【解决方案1】:

我在本地创建一个裸仓库

描述此处使用的确切命令很重要。

通常,我们会创建一个裸镜像克隆:

git clone --mirror <url> foo.git

创建一个用于接收git push 操作的裸克隆:

mkdir foo.git && cd foo.git && git init --bare

你做了这两个序列中的一个,还是其他的?

然后我在 github 仓库中添加了一个遥控器

同样,我们需要精确的操作。我不认为git remote add 尊重core.bare(我的本地测试中没有),但这也可能与 Git 版本有关,因此 Git 版本可能很有趣。

我捡到了……

这是我的测试结果:

$ mkdir tbare
$ git init --bare
Initialized empty Git repository in ...
$ git remote add foo ssh://git@github.com/chris3torek/scripts
$ cat config
[core]
        repositoryformatversion = 0
        filemode = true
        bare = true
[remote "foo"]
        url = ssh://git@github.com/chris3torek/scripts
        fetch = +refs/heads/*:refs/remotes/foo/*

有趣的是,在不命名遥控器的情况下获取现在什么也没做。将foo 重命名为origin,然后获取,得到东西:

$ git remote rename foo origin
$ git fetch -v
remote: Enumerating objects: 35, done.
[the usual, snipped]
 * [new branch]      master     -> origin/master

这大概是因为git fetch 通常会根据当前分支的名称然后其上游设置来选择远程的名称。由于没有当前分支,也就没有上游,这导致git fetch 退回到硬编码的origin。 (并且:这个特定系统上的 Git 是 2.27.0。)

使用git clone --mirror 创建的镜像克隆将默认获取引用规范设置为+refs/*:refs/*。请注意,--mirror 暗示 --bare

【讨论】:

  • 嗯....这很有趣。我就像你对mkdir; git init --bare....所做的那样。 @ 而不是 git fetch,它可以工作。关于if the remote's name is origin then fetch works 的部分听起来像是一个非常不可能的错误(因为我正在尝试一个非常不可能的设置开始)。
  • 我现在不明白的是为什么你的答案得到了 2 分(当之无愧,不要误会我的意思),但我的问题停留在 0。:-D
  • 如果您提供复制器(“minimal reproducible example”)仍然会有帮助。
  • 我想我遇到了一个错误...与我们之前描述的不同。让我进一步挖掘,然后我会回来(这不会在几分钟内发生,所以不要屏住呼吸......我可能需要几天才能看到发生了什么)
  • 哦....我明白发生了什么。没有错误。这是一个很大的仓库,github 在完成之前关闭了连接(我之前没有看到错误消息)。让我发布更新
【解决方案2】:

因此,您正在尝试手动完成设置克隆的步骤。似乎 cmets 的讨论将您引向了一个命令,该命令修补了迄今为止遗漏的某些内容,这很好……但为什么不直接使用直接为您提供所需内容的命令呢?

git clone --bare remote-url

【讨论】:

  • 当然......我意识到了......但这仍然不能帮助我弄清楚我尝试的问题是什么。
  • “这个命令是做你想做的事情的简单、预期的方法”对“我得到结果的复杂尝试没有用?”没有帮助?那么不用担心;既然你不想要实际的帮助,你就不会再从我这里得到它了。
  • 哈哈哈嘿,别把它当作私人的。如果您查看@torek 的帖子,您会发现实际上我们遇到了一些时髦的东西。所以,我知道你提示的工作原理,我知道裸回购的用途......而且我知道我有点延伸这个概念。但是我正在尝试的方式(即使很麻烦)应该可以工作。