繁体   English   中英

我该如何解决这个 git 远程分支跟踪不一致问题?

[英]How can I fix this git remote branch tracking inconsistency?

我有一个git存储库,它似乎对其分支跟踪配置感到困惑,我需要一些帮助来理顺它。 我正在运行git version 2.21.0.windows.1

问题是git branch -a仍然列出了我删除的远程,它显示的分支跟踪与git remote -vgit remote show origin不一致。 以下是显示回购协议当前 state 的命令:

C:\dev> git branch -a
* dev-mdbootstrap
  master
  remotes/localrepo/HEAD -> localrepo/master
  remotes/localrepo/dev-mdbootstrap
  remotes/localrepo/master
  remotes/origin/master


C:\dev> git remote -v
origin  https://github.com/MyOrganization/MyProject.git (fetch)
origin  https://github.com/MyOrganization/MyProject.git (push)


C:\dev> git remote show origin
* remote origin
  Fetch URL: https://github.com/MyOrganization/MyProject.git
  Push  URL: https://github.com/MyOrganization/MyProject.git
  HEAD branch: master
  Remote branches:
    dev-mdbootstrap tracked
    master          tracked
  Local branches configured for 'git pull':
    dev-mdbootstrap merges with remote dev-mdbootstrap
    master          merges with remote master
  Local refs configured for 'git push':
    dev-mdbootstrap pushes to dev-mdbootstrap (up to date)
    master          pushes to master          (up to date)


C:\dev> git ls-remote origin
2ac96d0912e126f5ccaafef66133e3fbc3f23f1d        HEAD
bd3366870b7c6848c7d182e971307b9a74e0ae48        refs/heads/dev-mdbootstrap
2ac96d0912e126f5ccaafef66133e3fbc3f23f1d        refs/heads/master

我很困惑为什么git branch -a仍然列出localrepo并且不显示本地分支dev-mdbootstrap跟踪remotes/origin/dev-mdbootstrap

需要解释这个存储库的历史。

我最初克隆了一个本地git 存储库,创建了一个名为dev-mdbootstrap的新分支,然后开始工作。 所以那时origin本地存储库。

后来,我想将现有的 github.com 存储库配置为origin ,所以我做了以下操作:

C:\dev> git remote rename origin localrepo

C:\dev> git remote add -t master origin https://github.com/MyOrganization/MyProject.git

所有这一切似乎工作得很好。 https://github.com/MyOrganization/MyProject.git远程以前只包含master分支。)

我将本地dev-mdbootstrap分支推送到新配置的 GitHub origin repo:

C:\dev> git push -u origin dev-mdbootstrap:dev-mdbootstrap
Counting objects: 100% (59/59), done.
[...snipped...]
Branch 'dev-mdbootstrap' set up to track remote branch 'dev-mdbootstrap' from 'origin'.

最终,我决定删除localrepo存储库:

git remote rm localrepo

我很困惑为什么git branch -a仍然显示localrepo 我怎样才能理顺它?

谢谢!

在 Git 内部,远程跟踪名称的存在(和存储的值)与远程本身是否存在无关。 也就是说,它们只是符合refs/remotes/ r / name模式的文本字符串,其中r是远程名称, name该远程上找到的分支名称。

更新遥控器的git remote命令addrenamerm应该在适当的子命名空间中管理远程跟踪名称。 因此,当您运行git remote rm localrepo时,这应该已经删除了所有refs/remotes/localrepo/*名称。 显然没有; 追查为什么它没有——错误在哪里——将需要一个复制器。

您可以使用低级“管道”命令git update-ref手动删除每个“坏”名称,该命令绕过所有正常机制并直接进入 Git 内部:

git update-ref -d refs/remotes/localrepo/HEAD
git update-ref -d refs/remotes/localrepo/dev-mdbootstrap
git update-ref -d refs/remotes/localrepo/master

我们可能永远不会知道为什么git remote rm在这里没有自行清理。

(我怀疑你可能已经将origin设置为单分支远程。检查:

 git config --get-all remote.origin.fetch

output 通常应该是一行:

+refs/heads/*:refs/remotes/origin/*

其他任何情况都表明设置不正常。 不一定是错误的,只是不寻常。)

您是否尝试运行 git 修剪?

git remote prune origin

您可以使用 --dry-run 查看将修剪哪些分支

git remote prune origin --dry-run

@torek让我走上了正确的道路。 非常感谢,虽然全面清理涉及更多。 所以我想记录它以防它帮助某人,(请注意,因为我不确定我是否走在正确的道路上,所以我在继续之前对我的.git回购文件夹进行了完整备份。)

从我在原始问题中注意到的这个混乱的分支配置开始:

C:\dev> git branch -a
* dev-mdbootstrap
  master
  remotes/localrepo/HEAD -> localrepo/master
  remotes/localrepo/dev-mdbootstrap
  remotes/localrepo/master
  remotes/origin/master

根据@torek 的指导,我跑了:

C:\dev> git update-ref -d refs/remotes/localrepo/HEAD
C:\dev> git update-ref -d refs/remotes/localrepo/dev-mdbootstrap
C:\dev> git update-ref -d refs/remotes/localrepo/master

这导致了以下结果。 请注意ignoring broken ref警告消息:

C:\dev> git branch -a
warning: ignoring broken ref refs/remotes/localrepo/HEAD
* dev-mdbootstrap
  master
  remotes/origin/master

我摸索着试图解决这个问题。 首先,我按照@torek 的建议重新检查git config 查看git config --get-all...

C:\dev> git config --get-all remote.origin.fetch
+refs/heads/*:refs/remotes/localrepo/*
+refs/heads/dev-mdbootstrap:refs/remotes/origin/dev-mdbootstrap

由于localrepo仍然出现在配置中,而且我不确定哪个git config...命令会清理它,我只是运行git config -e在我的文本编辑器中编辑.git\config文件。 最初,该文件包含:

[core]
    ...various settings... snipped out...

[remote "origin"]
    url = https://github.com/MyOrganization/MyProject.git
    fetch = +refs/heads/*:refs/remotes/localrepo/*
    fetch = +refs/heads/dev-mdbootstrap:refs/remotes/origin/dev-mdbootstrap
[branch "dev-mdbootstrap"]
    remote = origin
    merge = refs/heads/dev-mdbootstrap
[branch "master"]
    remote = origin
    merge = refs/heads/master

我将[remote "origin"]部分简化为以下内容,并保持其他一切不变:

[remote "origin"]
    url = https://github.com/MyOrganization/MyProject.git
    fetch = +refs/heads/*:refs/remotes/origin/*

但是,这对git branch -a output 没有影响。

我直接检查C:\dev\.git\refs\remotes文件夹。 它包含一个origin和一个localrepo文件夹。 后者包含一个名为HEAD的文件,其内容为:

ref: refs/remotes/localrepo/master

我四处寻找使用git update-ref -d...命令清除此问题的方法,但我尝试的任何方法都不起作用,所以我最终删除了``C:\dev.git\refs\remotes\localrepo`手动文件夹。

这有帮助! 在此之后git branch -agit branch -vv返回以下内容:

git branch -a
* dev-mdbootstrap
  master
  remotes/origin/master

PS C:\dev> git branch -vv
* dev-mdbootstrap bd336687 [origin/dev-mdbootstrap: gone] ...snipped commit message #1...
  master          2ac96d09 [origin/master] ...snipped commit message #1...

但是为什么会显示“origin/dev-mdbootstrap: gone ”? 我尝试git remote show origin ,它返回了以下内容。 请注意dev-mdbootstrap new (next fetch will store in remotes/origin)这一行。

C:\dev> git remote show origin
* remote origin
  Fetch URL: https://github.com/MyOrganization/MyProject.git
  Push  URL: https://github.com/MyOrganization/MyProject.git
  HEAD branch: master
  Remote branches:
    dev-mdbootstrap new (next fetch will store in remotes/origin)
    master          tracked
  Local branches configured for 'git pull':
    dev-mdbootstrap merges with remote dev-mdbootstrap
    master          merges with remote master
  Local refs configured for 'git push':
    dev-mdbootstrap pushes to dev-mdbootstrap (up to date)
    master          pushes to master          (up to date)

似乎在我的 git 配置被打乱的时候,我之前的命令,如git fetch origin dev-mdbootstrap和其他试图强制本地dev-mdbootstrap分支跟踪origin/dev-mdbootstrap的命令根本没有效果。

但由于 git 指示需要next fetch ,我运行了:

C:\dev> git fetch origin
From https://github.com/MyOrganization/MyProject
 * [new branch]        dev-mdbootstrap -> origin/dev-mdbootstrap

然后:

C:\dev> git branch --set-upstream-to=origin/dev-mdbootstrap dev-mdbootstrap
Branch 'dev-mdbootstrap' set up to track remote branch 'dev-mdbootstrap' from 'origin'.

最后,'git branch -a -vv' 返回:

C:\dev> git branch -a -vv
* dev-mdbootstrap                bd336687 [origin/dev-mdbootstrap] ...snipped commit message #1...
  master                         2ac96d09 [origin/master] ...snipped commit message #2...
  remotes/origin/dev-mdbootstrap bd336687 ...snipped commit message #1...
  remotes/origin/master          2ac96d09 ...snipped commit message #2...

现在一切看起来都很干净, git的行为与我通常预期的一样。 再次,支持@torek让我走上正确的道路。 这可能不是解决此问题的最佳或最正确的方法,但它完成了工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM