如何解决 git 远程分支跟踪不一致问题?
我有一个 git 存储库,它似乎对其分支跟踪配置感到困惑,我需要一些帮助来理顺它。我正在运行 git 版本 2.21.0.windows.1
。
问题是 gitbranch -a 仍然列出了我删除的远程,并且它显示的分支跟踪与 gitremote-v 和 gitremoteshoworigin 不一致。以下是显示存储库当前状态的命令:
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
我很困惑为什么 gitbranch -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
存储库:
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
。我怎样才能把它弄直?
谢谢!
I have a git
repository that seems to be confused about its branch tracking configuration, and I need some help straightening it out. I'm running git version 2.21.0.windows.1
.
The problem is that git branch -a
still lists a remote I deleted, and it shows branch tracking that is inconsistent with git remote -v
and git remote show origin
. Below are commands showing the current state of the repo:
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
I'm stumped as to why git branch -a
still lists localrepo
and does not show local branch dev-mdbootstrap
tracking remotes/origin/dev-mdbootstrap
.
An explanation of the history of this repository is needed.
I originally cloned a local git repository, created a new branch named dev-mdbootstrap
, and began working. So at that point origin
was the local repository.
Later, I wanted to configure an existing github.com repository as origin
, so I did the following:
C:\dev> git remote rename origin localrepo
C:\dev> git remote add -t master origin https://github.com/MyOrganization/MyProject.git
All of this seemed to work just fine. (The https://github.com/MyOrganization/MyProject.git remote previously contained only the master
branch.)
I pushed the local dev-mdbootstrap
branch to the newly configured 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'.
Eventually, I decided to remove the localrepo
repository:
git remote rm localrepo
I'm very puzzled why git branch -a
still shows localrepo
. How can I straighten it out?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在 Git 内部,远程跟踪名称的存在(以及存储的值)与远程本身是否存在无关。也就是说,它们只是符合
refs/remotes/r/name
模式的文本字符串,其中r< /code>
是远程名称,
name
是在该远程上找到的分支名称。用于更新遥控器的
git remote
命令(add
、rename
和rm
)应该< /em> 管理适当子命名空间中的远程跟踪名称。因此,当您运行 git Remote rm localrepo 时,这应该会删除所有 refs/remotes/localrepo/* 名称。显然没有;追踪为什么没有发生——错误在哪里——需要一个重现器。您可以使用低级“管道”命令
git update-ref
手动删除每个“坏”名称,该命令绕过所有正常机制并直接进入 Git 内部:我们可能永远不会知道为什么 git Remote rm 没有在此处自行清理。
(我怀疑您可能已将
origin
设置为单分支远程。检查:输出通常应该是单行:
任何其他内容都表明设置不正常。不一定错误,只是不寻常。)
Internally in Git, the existence (and stored values of) remote-tracking names are independent of whether the remote itself even exists. That is, they are just text strings that fit the
refs/remotes/r/name
pattern, wherer
is a remote-name andname
is a branch-name as found on that remote.The
git remote
commands that update remotes—add
,rename
, andrm
—are supposed to manage the remote-tracking names in the appropriate sub-namespace. So when you rangit remote rm localrepo
, this should have erased all therefs/remotes/localrepo/*
names. Apparently it didn't; tracking down why it didn't—where the bug is—would require a reproducer.You can manually remove each "bad" name using the low-level "plumbing" command
git update-ref
, which bypasses all the normal mechanisms and goes straight into the Git internals:We'll probably never know why
git remote rm
did not clean up after itself here.(I suspect you might have set up
origin
as a single-branch remote though. Check with:The output should normally be a single line:
Anything else indicates an unusual setup. Not necessarily wrong, just unusual.)
您尝试运行 git prune 吗?
您可以使用 --dry-run 来查看哪些分支将被修剪
Did you try to run git prune?
You can use --dry-run to see what branches will be pruned
@torek 让我走上了正确的道路。非常感谢!不过,完整的清理工作涉及更多,所以我想记录下来,以防它对某人有帮助。 (请注意,因为我不确定我是否走在正确的道路上,所以在继续之前我对我的
.git
存储库文件夹进行了完整备份。)从我在中注意到的这个混乱的分支配置开始最初的问题:
根据@torek的指导,我跑了:
这导致了以下结果。请注意
忽略损坏的引用
警告消息:我摸索着试图解决这个问题。首先,我按照@torek的建议重新检查了
git config
。查看 git config --get-all ...:由于
localrepo
仍然出现在配置中,并且我不确定具体的git config ...
命令会清理它,我只需运行 git config -e 来在文本编辑器中编辑 .git\config 文件。最初,该文件包含:我将
[remote "origin"]
部分简化为以下内容,并保留其他所有内容不变:但是,这对
gitbranch -a
没有影响代码>输出。我直接检查了 C:\dev\.git\refs\remotes 文件夹。它包含一个
origin
和一个localrepo
文件夹。后者包含一个名为HEAD
的文件,其内容如下:我四处寻找一种使用
git update-ref -d ...
命令清除此内容的方法,但是我尝试的任何方法都不起作用,所以我最终手动删除了“C:\dev.git\refs\remotes\localrepo”文件夹。这有帮助!在
gitbranch-a
和gitbranch-vv
返回以下内容之后:但是为什么显示“origin/dev-mdbootstrap: gone” ?我尝试了 git remote show origin,它返回了以下内容。请注意
dev-mdbootstrap new(下次获取将存储在remotes/origin中)
行。看来,在我的 git 配置被打乱期间,我之前的命令(例如 git fetch origin dev-mdbootstrap 等)试图强制本地 dev-mdbootstrap 分支track
origin/dev-mdbootstrap
根本没有效果。但由于 git 指示需要
next fetch
,我运行:然后:
最后, 'gitbranch -a -vv' 返回:
现在一切看起来都很干净,并且
git
是表现得像我通常期望的那样。再次感谢 @torek 让我走上正确的道路。这可能不是解决此问题的最佳或最正确的方法,但它完成了工作。@torek set me on the right course. Thanks much! The full cleanup got more involved though, so I wanted to document it in case it helps someone. (Note that, because I was not sure if I was going down the right path, I made a complete backup of my
.git
repo folder before proceeding.)Starting from this scrambled branch configuration that I noted in the original question:
Per @torek's guidance, I ran:
This resulted in the following. Note the
ignoring broken ref
warning message:I fumbled forward trying to resolve this. First I reexamined
git config
, following @torek's suggestion. Looking atgit config --get-all ...
:Since
localrepo
still showed up in the config and I was not sure what individualgit config ...
commands would clean it up, I simply rangit config -e
to edit the.git\config
file in my text editor. Originally, the file contained:I simplified the
[remote "origin"]
section to the following, and left everything else unchanged:However, this had no impact on the
git branch -a
output.I inspected
C:\dev\.git\refs\remotes
folder directly. It contained both anorigin
and alocalrepo
folder. The latter contained a single file namedHEAD
with the contents:I poked around for a way to clear this out using a
git update-ref -d ...
command, but nothing I tried worked, so I finally just deleted the ``C:\dev.git\refs\remotes\localrepo` folder manually.This helped! After this
git branch -a
andgit branch -vv
returned the following:But why did this show "origin/dev-mdbootstrap: gone"? I tried
git remote show origin
, which returned the following. Note the linedev-mdbootstrap new (next fetch will store in remotes/origin)
.It seems that during the time my git configuration was scrambled, my earlier commands such as
git fetch origin dev-mdbootstrap
and others to try to force the localdev-mdbootstrap
branch to trackorigin/dev-mdbootstrap
were simply having no effect.But since git indicated a
next fetch
was needed, I ran:and then:
Finally, 'git branch -a -vv' returns:
Now everything looks clean, and
git
is behaving as I normally expect it to. Again, props to @torek for setting me on the right course. This may not be the optimal or most correct way to fix this, but it got the job done.