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!
CodePudding user response:
Did you try to run git prune?
git remote prune origin
You can use --dry-run to see what branches will be pruned
git remote prune origin --dry-run
CodePudding user response:
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, where r
is a remote-name and name
is a branch-name as found on that remote.
The git remote
commands that update remotes—add
, rename
, and rm
—are supposed to manage the remote-tracking names in the appropriate sub-namespace. So when you ran git remote rm localrepo
, this should have erased all the refs/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:
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
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:
git config --get-all remotes.origin.fetch
The output should normally be a single line:
refs/heads/*:refs/remotes/origin/*
Anything else indicates an unusual setup. Not necessarily wrong, just unusual.)