首页 > 解决方案 > Git:很难让现有的 Git 存储库跟踪新的裸远程存储库

问题描述

摘要: 我很难让现有的本地存储库跟踪新的裸远程存储库。

我尝试过的: 在设置上游跟踪时,我尝试将本地存储库推送到新的裸存储库。Git 告诉我正在进行上游跟踪,但我仍然没有在本地 repo 的日志中看到正在跟踪的分支,即使在获取远程 repo 之后也是如此。

我还尝试从本地存储库创建一个裸克隆,希望这会以类似于克隆另一个本地存储库的方式工作,其中自动设置跟踪,但我仍然没有在本地存储库的日志中看到跟踪的迹象.

请求: 是否有人能够查看下面的背景信息,并指导我可能出错的地方,或者可能对如何让我现有的 repo 跟踪新的裸远程 repo 有不正确的理解?谢谢,我已经尽力研究这个了。

背景 我在一个小团队中担任制造工程师。我们想为团队使用中央共享远程 Git 存储库设置工作流。我一直在尝试设置一个演示如何运行,下面的“centralRepo.git”目录是我们的中央仓库,并且让其他文件夹团队成员可以将中央遥控器克隆到。

因为我们已经有现有的工作,但没有现有的中央远程仓库,我们将从“davesClones”中的现有仓库开始,该仓库将被推送到中央远程,然后根据需要克隆到其他团队成员文件夹,例如“stevesClones” 。”

文件夹示例

我期望看到跟踪是否有效: 如果我克隆一个常规的本地 repo,跟踪会自动设置,并且日志会显示我的克隆自己的分支,以及它从它所在的目录跟踪的“原始”分支克隆自,如下图蓝色圈出的截图所示:

预期跟踪结果

尝试#1:使用--Set-Upstream 推送:

我已尝试使用如下所示将现有的本地存储库推送到新的中央远程存储库 git push --set-upstream <remote> master,即使输出似乎显示已设置跟踪,我也没有像克隆常规时那样在 git 日志中看到任何跟踪回购,即使在使用 fetch 之后。下面的示例显示了在尝试上述步骤后我如何在日志中丢失了原始跟踪分支:

--set-upstream 不起作用

尝试#2:克隆-裸:

我还尝试将现有存储库克隆到新的裸存储库,希望这会自动建立跟踪,但如下所示,日志似乎没有显示任何跟踪发生,即使在获取之后:

将 daveClones 克隆到裸回购尝试

获取没有帮助

知道为什么我在日志中没有看到跟踪吗?(这意味着在克隆标准本地 repo 后,我看到了一个跟踪 [origin/master, origin head] 但在使用 push --set-upstream 将本地 repo 推送到远程或使用时无法在我的日志中获取此信息git clone --bare 将本地 repo 克隆到裸远程?)

此外,本地存储库中确实有提交,因此在推送或克隆到远程时它不是空的。

谢谢!

标签: gitgit-pushbareremotes

解决方案


TL;博士

您需要通过在自己的 Git 存储库中设置远程来开始整个过程​​:

git remote add <name> <URL-or-path>

之后,您必须使用您使用的name部分,而不是输入(可能更长的)URL 或路径。也就是说,您将执行以下操作:

git remote add origin /d/Seafile/...
git push --set-upstream origin master

首先让我说我真的不喜欢这里的跟踪这个词,因为它误导了每个人。它也对你这样做了。

我们必须使用git remote来创建或以其他方式操作遥控器。远程只是一个短名称——比如origin,它是远程使用的标准名字——它将存储一个 URL(以及一些其他更多的 Git 内部信息)。

我正在从您的屏幕截图中重新输入,所以我可能会引入拼写错误,但关键在这一行:

git push --set-upstream /d/Seafile/Development/gitTest/centralRepo.git master

让我们快速浏览一下 Git 文档。的语法在文档的 SYNOPSIS 行中git push描述为(缩写):

git push [options] [repository [refspec...]]

在这里,您唯一的选择是--set-upstream(这本身就很好)并且您的存储库作为路径名给出,/d/Seafile/.... 如果你跳到 OPTIONS 部分,repository 参数的描述太简单了,如下所示:

<repository>
作为推送操作目标的“远程”存储库。此参数可以是 URL ... 或远程 ... 的名称。

不幸的是,这里省略了--set-upstream,并且您想要的跟踪类型仅在给定参数是 remote 时才有效

/d/Seafile/...像您的 Git 内部翻译成的路径名(如D:/Seafile/...您在其他输出中看到的那样)算作 URL,而不是“远程”。

遥控器和远程跟踪名称

与其说分支名称跟踪其他名称,我更喜欢使用短语has 作为 upstream。不幸的是,这个短语有点尴尬(因此 Git 使用track作为动词)。任何分支名称都可以没有上游,也可以有一个上游。当分支确实有上游时,可以是:

  • 另一个分支名称,例如,develop可以master作为其上游,或
  • 远程跟踪名称,例如origin/master.

我将名称称为origin/master 远程跟踪名称(Git 文档主要称为这些远程跟踪分支名称)。它们是通过将远程的名称(例如)与分支名称串在一起而存在的:当您的 Git 使用存储在该分支下的URLorigin呼叫另一个 Git 时,您的 Git 与之对话的 Git 中分支的名称“偏僻的”。

当你使用git fetchorgit push时,你的 Git 手机会启动另一个 Git。有两个 Git;每个 Git 都有自己的分支。你的 Git 有你的分支,他们的 Git 也有他们的。你的 Git 提供为你记住他们的名字,作为一项服务......但是为了让你的 Git 记住他们的分支名称,你的 Git 必须为每个不干扰你自己的分支名称的名称提供一个名称。你的 Git 通过在他们的分支名称前面粘贴一些东西来做到这一点。1

此处粘贴在前面的部分是远程名称,例如origin. 如果没有遥控器(使用 URL 代替),就没有什么可以粘贴到前面的,所以前面的粘贴永远不会发生。该--set-upstream选项变得无效。

那么为什么你的 Git 打印:

Branch 'master' set up to track remote branch 'master' from 'D:/Seafile/Development/gitTest/centrapRepo.git'.

? 这里唯一可能的答案是 Git 非常 Gitty。它只是说它做了一些它在物理上做不到的事情,因此没有做。


1从技术上讲,远程跟踪名称位于单独的命名空间中:分支名称具有以 开头的完整拼写名称refs/heads/,因此实际上masterrefs/heads/master. 远程跟踪名称以远程名称和另一个斜线开头refs/remotes/并继续包含远程名称。名称的其余部分是在远程 URL 上看到的精简分支名称。所以他们refs/heads/master变成了你的refs/remotes/origin/master,它被简化为origin/master.


推荐阅读