无法追踪 origin/master

Can't track origin/master

我无法将 origin/master 作为跟踪分支添加到本地主分支

git checkout --track origin/master
fatal: 'origin/master' is not a commit and a branch 'master' cannot be created from it

我的 fork 已经有一些提交了。 Remote(fork) 也有 1 个带有 README 的提交。可能是什么问题?

编辑:在运行git fetch origin之后,错误信息变化:

git checkout --track origin/master
fatal: A branch named 'master' already exists.
  • 获取最新版本
    git fetch -apt
  • 检查您的遥控器是否正确
    git remote -v
    如果遥控器不正确,请git remote add origin <your repo>
  • 使用标签保存您当前的主分支:
    git tag -l old-master
  • 删除你的本地主控(你已经用标签保存了它)
    git branch -D master
  • 获取最新的远程主机
    git switch -c <branch> --track <remote>/<branch>

我不清楚您最初是如何创建本地存储库的,但我怀疑您是这样做的:

mkdir new-repo
cd new-repo
git init

然后创建了一些文件并git add编辑了它们并提交了结果。这将为您留下一个只有一个提交的新存储库,并且没有 origin 远程,因此您将不得不 运行:

git remote add origin ssh://git@github.com/your/repo.git

或类似的。

我不清楚你是如何在 GitHub 上创建 your/repo.git(或者它的路径可能是什么),但我怀疑你使用了 "create a new repository with a README file in it" 按钮。

如果所有这些 "suspects" 都是正确的,这就说明了一切。您的初始错误:

fatal: 'origin/master' is not a commit and ...

发生是因为您尚未将 Git 连接到 GitHub 的 Git,该集线器包含您在 GitHub 上创建的存储库。

你然后运行git fetch origin,让你的Git连接到他们的Git并获得他们的(单)包含 README 文件的提交。您的 Git 将他们的提交复制到您的存储库中。您的 Git 然后创建了您自己的 origin/master 远程跟踪名称,以记住他们(单个)提交的哈希 ID。

您现在有 两个 初始(从无到有)提交,Git 调用 root 提交。如果我们绘制您的存储库的图表,它可能看起来像这样:

A   <-- master

B   <-- origin/master

您的第一次提交,此处表示为 A——无论其实际哈希 ID 可能是什么——包含您提交的文件。您的 b运行ch 名称 master 标识了这一次提交。

他们的 第一次提交,这里表示为 B,包含他们提交的文件。您的远程跟踪名称 origin/master 标识了这一次提交。

你现在要求你的 Git 创建一个新的 b运行ch 名称 master 指向提交 B,使用你的 origin/master,通过失败的命令:

git checkout --track origin/master
fatal: A branch named 'master' already exists.

错误消息的原因很明确:您已经有一个 b运行ch 名称 master,指向现有的提交 A;不可能创建一个新的但相同的 b运行ch 名称 master 指向现有提交 B.

怎么办

从这里开始,您有多种选择。它们主要涉及创建新提交 C.

您可以使用 git merge 将您的历史记录(您的单独提交)加入到他们的历史记录(他们的单独提交)中。为此,您将需要 --allow-unrelated-histories 选项,除非您的 Git 版本太旧以至于 没有 选项。旧的 Git 只是假设 --allow-unrelated-histories 应该始终被暗示。

如果他们的单独提交 B 是自动生成的,那么合并这样的历史记录就有点傻了。完全放弃他们的承诺会更有意义。从他们的提交 B 中获取你认为有用的任何内容,并制作你自己的新常规提交 C:

A <-C   <-- master

B   <-- origin/master

您的新提交 C 将仅指向您现有的 A。您现在可以强制他们放弃他们的提交 B,向他们发送您的新 C.

或者,您可以继续合并两个提交:

A
 \
  C   <-- master
 /
B   <-- origin/master

您现在可以向他们发送提交 C 并要求他们让他们的 master 记住 C,这会同时记住 AB

向他们发送新提交 C(这将带来 A,并指向 A,也可能指向 B,具体取决于您如何制作 C),使用 git push origin master。这将发送 C(和 A)并以礼貌的请求结束,如果他们愿意,请将他们的名字 master 指向 C。如果您故意 抛出 B,而不进行合并,则需要将礼貌请求升级为命令:git push --force origin master.

完成后,他们的 master 也将指向(他们现在共享的副本)提交 C。您的 Git 将更新您自己的 origin/master 以记住他们的 master 记住 C,并且你们都同意 C 是您和他们的兄弟运行兄弟,都被命名为master.

同时,您自己的 master 不会将 origin/master 设置为其 上游 。没有理由 必须 ,但如果您希望如此——参见 Why do I need to do `--set-upstream` all the time?——你可以使用 git branch --set-upstream-to,或者你可以结合你的 git push-u 选项:

git push -u origin master

或:

git push --force -u origin master

(仅当您告诉他们时才需要 --force 选项:*忘记您的提交 B,它没用,请改用我的 C——这不是必需的如果你的 C 指向 B).

除了合并 覆盖之外,您还有更多选择,这也会创建一个新的提交 C。您可以:

  • 使用 git rebase -i --root
  • 在他们的 B 上重新设置 A 的基准
  • 将你的 A 复制到一个新的提交 C ,它位于他们的 B 之上,在一个新的 b运行ch not 命名为 master.

rebase 的工作原理是复制,然后放弃原来的 A 以支持这个新的 C:

A   [abandoned / lost - will eventually be garbage collected]

B   <-- origin/master
 \
  C   <-- master

或:

A   <-- master

B   <-- origin/master
 \
  C   <-- newbranch

然后您可以将 master 重命名为 old-master 并将 newbranch 重命名为 master:

A   <-- old-master

B   <-- origin/master
 \
  C   <-- master

最后,您现在可以 git push -u origin master 向他们发送提交 C(这次根本不发送 A)并要求他们设置他们的 master指向新提交 C.

如何理解这一切

回去重新检查所有早期的图表并思考这样的事情:

  • 对 Git 重要的是 提交 ,它永远不会改变(但可以被放弃并最终完全扔掉)。
  • Names,如 masterorigin/master,仅用于按某种顺序查找 last 提交提交数。
  • 任何提交的哈希 ID——你会在 git log 输出中看到这些丑陋的大哈希 ID——是 Git 找到提交的方式。通过在每个名称中存储 last 哈希 ID,Git 可以找到所有最后一个。每个提交本身都存储其直接前身的丑陋的大哈希 ID:提交 C 指向提交 A 或提交 B,或两者兼而有之,具体取决于我们的制作方式。

真正重要的是提交。 Git 给你名字,因为名字对人类有意义(谁不记得又大又丑的哈希 ID),然后使用这些名字来 找到 提交。 Git 可以通过名称找到的那些提交,存储早期提交的哈希 ID。那些较早的提交存储更早提交的哈希 ID,等等。 git log 命令从当前的 end 开始并向后工作,显示你的提交。

我们在 Windows 机器 运行 与 google 驱动器同步的文件夹上的 gitbash 中遇到了这个确切的错误。

这是由于启用了“启用实验性内置文件系统监视器”功能造成的。

在禁用此功能的情况下卸载并重新安装 gitbash 后,它已修复。