28

In our GitHub repository, a coworker removed a branch named release. But when I run git checkout release locally, I always get the removed branch release. Same, even when I checked out another branch, deleted the release branch with git branch -D release and ran again git checkout release.

Is there something to fix on the GitHub repository, or shall I fix something locally?

11
  • 1
    What does git branch --remote output, after running git fetch? You might need to prune with git fetch -p to forget deleted remote branches. May 18, 2017 at 14:33
  • 2
    If that branch was ever pushed to GitHub, and you pulled after that, then you have a copy of the branch too. Every git repository is complete in and of itself, unless you used a shallow clone or something.
    – muru
    May 18, 2017 at 14:51
  • @StephenKitt: Thanks. git branch --remote output origin/release. Do you mean to run git fetch -p without additional arguments, and will it prune all the deleted remote branches?
    – Tim
    May 18, 2017 at 14:54
  • 1
    Yes, git fetch -p with no additional arguments will prune all the deleted remote branches. May 18, 2017 at 15:07
  • 1
    Welcome to the world of distributed version control! May 18, 2017 at 22:24

4 Answers 4

28

After deleting a branch on the remote side you may still see this formerly fetched remote branch locally, see:

$ git branch -a
[...]
release
remotes/origin/release
[...]

You only removed the "release" but not "remotes/origin/release". Delete it like this:

$ git branch -rd origin/release

Or remove all fetched branches which do not exist on the remote side anymore:

$ git remote prune origin 
4
  • Thanks. In git branch -rd origin/release, what does -r mean? Does -d mean the same as -D? Can git branch -rd origin/release be replaced with git branch -d remotes/origin/release?
    – Tim
    May 18, 2017 at 19:23
  • @Tim: From the manual; -r: List or delete (if used with -d) the remote-tracking branches.; -D: Shortcut for --delete --force.
    – looper
    May 18, 2017 at 20:00
  • Thanks. Can git branch -rd origin/release be replaced with git branch -d remotes/origin/release?
    – Tim
    May 18, 2017 at 20:06
  • @Tim no -r refers to remote branches, it's needed. The local and remote branches are stored in different directories, compare ls -l .git/refs/heads and ls -l .git/refs/remotes. You could also have a local branch called remotes/origin/release which would be delete without -r. This might sound confusing but you could just play around, create branches with strange names and look how does it look in .git/.
    – rudimeier
    May 18, 2017 at 21:15
15

When branches are deleted remotely, you need to prune your local repository — the easiest way to do this is with

git fetch -p

This will update your local repository with all the changes made to the remote repository, but without updating any of your local branches. After running this,

git branch --remote

will no longer show the deleted remote branch.

git repositories are complete, whether on your own system or on the server. So when you first clone a repository, you get a complete copy, and your local git “knows” about all the remote branches as well as your local branches. This information isn’t synced automatically, so when your colleague deleted the release branch on the server, your local git repository didn’t lose its notion of a remote release branch. Syncing with git fetch updates all the local information on remote branches so they match the state on the server (strictly speaking, remote repository, wherever that is), but without deleting any local information on remote branches. Pruning with git fetch -p (or git fetch --prune, or git remote prune) removes the local information on remote branches which have been deleted.

8
  • Thanks. "update your local repository with all the changes made to the remote repository, but without updating any of your local branches". What update is that, given that it is not update of my local branches?
    – Tim
    May 18, 2017 at 15:27
  • It’s all the remote updates. Your local git repository distinguishes your local branches and the remote branches, but remote branches aren’t magically synced with the server — they exist locally too (as in, stored in your local git repository). Fetching syncs your local repository with the remote repository, and updates the state of remote branches; by default deleted remote branches aren’t removed from the local information on remote branches, -p (--prune) forces that. May 18, 2017 at 15:31
  • Thanks. Why didn't deleting the release branch by git branch -D release before git checkout release make git checkout release stop getting the release branch?
    – Tim
    May 18, 2017 at 17:05
  • 1
    Because git checkout release will automatically re-create a branch if there is a remote branch with that name. May 18, 2017 at 17:07
  • By "remote branch", do you mean a branch in my local repository or Github repository? If former, git branch -D release has already deleted the release branch in my local repository; If latter, a coworker has deleted the release branch on GitHub; So i am still not sure why "will automatically re-create a branch if there is a remote branch with that name"?
    – Tim
    May 18, 2017 at 17:10
3

Tim: Git is distributed VCS, so when you clone a repo from remote to your local it clones everything (history). So when you cloned your repo, it had a branch called release. Since your colleague deleted release branch remotely, till you do a prune git fetch -p or delete that branch explicitly your local will have that branch.

1
  • 3
    How does this answer differ from the answers already present? May 18, 2017 at 16:58
1

Perhaps a bit tangential but the perspective of this site might help to understand the general topic of deleting branches:

http://railsware.com/blog/2014/08/11/git-housekeeping-tutorial-clean-up-outdated-branches-in-local-and-remote-repositories/

There is overlap with some of what's already been discussed here but the focus is on housekeeping: deleting branches, remote and local, that are no longer needed in a collaborative environment. In particular the git branch --merged command identifies branches that are safe to delete due to being merged to your mainline (or whatever branch you care about). If you're collaborating, some fancier mini scripts like this one will present things in a nice, digestible format with dates and authors.

for branch in `comm -12  <(git branch --merged|awk '{print($1)}') <(git branch -r --merged|awk '{print($1)}'|awk -F \/ '{print($2)}')`; do echo -e `git show --format="%ci %cr %an" $branch | head -n 1` \\t$branch; done | sort -r

(Unfortunately "nice, digestible" doesn't apply to the formatting of the scripts themselves.)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .