-1

Jii

I have been learning git and how to use remote branches on GitHub. I had a remote branch origin/other-branch and merged to update the branches, so when I put

git log --oneline --graph --all

I get the following output

  • * 352a7d7 (HEAD -> master, origin/master) merge with other
  • * 1da6f0a (origin/other-branch) other branch
  • * 2b02a4b another commit

So I wanted to remove origin/other-branch but I didn't know how to do it, so I did it from GitHub (the website)

Then, I researched how to remove remote branches (haha, I think I should have done that first) and I get the following command:

git push origin --delete other-branch

What does it mean to send the deletion of the branch, but since it is no longer on the remote I get the message that it cannot find such a branch

error: unable to delete 'other-branch': remote ref does not exist error: failed to push some refs to 'https://github.com/myUserName/remote.git'

so how do I remove this remote branch? Thank you!

It is worth mentioning that this branch was sent by another user, since I no longer want to work on it, I want to delete it from my local

Márquez
  • 91
  • 7
  • The other branch is called `other-commit`, not `other-branch`. (It's a terrible name, but that, according to you, is its name.) So `git push origin --delete other-commit`. – matt Jul 25 '22 at 20:14
  • Also remember to do `git fetch` before anything else, and then do `git branch --all` again, just to make sure that no one _else_ has deleted the remote branch in the meantime. – matt Jul 25 '22 at 20:16
  • @matt haha, my bad, I got confused writing the question, actually I do use other-branch and i get the same error – Márquez Jul 25 '22 at 20:26
  • Well that's why you need to do `git fetch`, and then `get branch --all`, as I said. – matt Jul 25 '22 at 20:38

2 Answers2

1

When you work with remotes on git, your local repository is entirely separate from the remote, and only gets entangled with remote branches when you say so.

The git fetch command is important here (documentation). When you run git fetch, it doesn't really change anything in your local repository. Rather, you can think of it as fetching the information about the remote and its branches, and exposing them to you. If you have fetched a remote, git branch -a will show you all your branches, including those on the remote.

But important to note is that none of those remote branches exist in your local repository. git branch will show you all your local branches. Let's say this is your situation:

Local branches       origin (remote) branches
---                  ---
main                 main
feature1             staging
                     otherFeature2

git branch -a will list all those branches, but only the local ones exist in your repository.

You can set a local branch to "track" a remote one, which can be done a couple of different ways. If you run git checkout staging in the above state, git will say "I don't see a staging branch here, but I see that there is one on origin, so I'll set up a local branch with the same name for you and set it to track origin/staging." If you create a branch locally, you push it with the command git push -u <remote> <branch-name>, where -u means upstream (the name of the remote you wish to track it to), and <branch-name> will be the name of the branch on the remote. That can be different from your local name, but it's usually easier if they're the same. I have aliased git push -u origin `git branch --show-current` because it's such a common command. If a branch with that name doesn't exist on the remote, it will be created, but if it already exists, git will simply start tracking your local branch to it.

Now if the state is this:

Local branches         origin (remote) branches
---                    ---
main          -track-> main
staging       -track-> staging
feature1      -track-> feature1
otherFeature2 -track-> otherFeature2

It should now be more clear what's actually going on. There are 8 branches here: 4 local, and 4 remote. If you go to GitHub and delete a branch there, it will only delete the remote branch - it would be pretty awful if remote branches could reach into your local repository and delete your stuff! But your local repository won't know about the changes made on GitHub until you tell it to grab the remote's info - with git fetch origin. Then, origin/branch-name should stop showing up.

Another way to delete a remote is with the command you mentioned, git push --delete <remote> <branch-name>. Because you run that from your local repository, you won't need to git fetch to update, but your local branch will still be around. That means you still need to delete your local branch using git branch -d <branch-name>.

On the flip side, if you delete a branch locally, its tracked remote branch will happily keep existing. If you want to totally clear the project of this branch, you will have to do both. But take care to ensure that no one else is using it before deleting remote branches!

scatter
  • 903
  • 7
  • 24
0

If the branch no longer exists in the remote repository, but you have fetched before that and still have the remote-tracking branch lying around (usually origin/branchname), use the git remote command to clean up your local repo:

git remote prune origin

To delete all local remote-tracking branches that no longer exist on the remote.

You can also tell fetch to prune before actually fetching:

git fetch -p

You can also enable auto-pruning for fetch, so you don't have to remember adding -p:

git config --global fetch.prune true
git config --global fetch.pruneTags true

Make sure to read and understand the PRUNING section in the man page of git fetch:

To prune references as part of your normal workflow without needing to remember to run that, set fetch.prune globally, or remote..prune per-remote in the config. See git-config[1].

Here’s where things get tricky and more specific. The pruning feature doesn’t actually care about branches, instead it’ll prune local ←→ remote-references as a function of the refspec of the remote (see and CONFIGURED REMOTE-TRACKING BRANCHES above).

Therefore if the refspec for the remote includes e.g. refs/tags/:refs/tags/, or you manually run e.g. git fetch --prune "refs/tags/:refs/tags/" it won’t be stale remote tracking branches that are deleted, but any local tag that doesn’t exist on the remote.

This might not be what you expect, i.e. you want to prune remote , but also explicitly fetch tags from it, so when you fetch from it you delete all your local tags, most of which may not have come from the remote in the first place.

So be careful when using this with a refspec like refs/tags/:refs/tags/, or any other refspec which might map references from multiple remotes to the same local namespace.

knittl
  • 246,190
  • 53
  • 318
  • 364