Home > Software design >  How can I fix this git remote branch tracking inconsistency?
How can I fix this git remote branch tracking inconsistency?

Time:02-28

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.)

  • Related