[英]How can I fix this git remote branch tracking inconsistency?
我有一个git
存储库,它似乎对其分支跟踪配置感到困惑,我需要一些帮助来理顺它。 我正在运行git version 2.21.0.windows.1
。
问题是git branch -a
仍然列出了我删除的远程,它显示的分支跟踪与git remote -v
和git 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
命令add
、 rename
和rm
应该在适当的子命名空间中管理远程跟踪名称。 因此,当您运行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 -a
和git 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.