I had run this command with misunderstandings while I was deleting my one local branch,
git branch -D branch-name
git fetch -p
but I have
The other answers explain what git fetch --prune
does, but there is one case where it needs to be a bit more precise: when the there is nothing to fetch (no new refs) from the upstream repo.
In that case, it does prune the remote tracking branches (from /remotes/anUpstreamRepo/*
), but it didn't say what upstream repo was the cause of said pruning.
This is fixed by commit 4b3b33a by Tom Miller (tmiller) for git 1.9/2.0 (Q1 2014):
fetch --prune
: always print header urlIf "
fetch --prune
" is run with no new refs to fetch, but it has refs to prune. Then, the header url is not printed as it would if there were new refs to fetch.Output before this patch:
$ git fetch --prune remote-with-no-new-refs
x [deleted] (none) -> origin/world
Output after this patch:
$ git fetch --prune remote-with-no-new-refs
From https://github.com/git/git
x [deleted] (none) -> origin/test
git fetch has the option to prune remote branches, that means for example:
$ git branch -a
develop
master
remotes/origin/HEAD
remotes/origin/develop
remotes/origin/feature/deleted-last-week
remotes/origin/master
If the branch feature/deleted-last-week
nolonger exists on the remote (because someone else deleted it already), running fetch -p
will remove the local reference to it:
$ git fetch -p
remote: Counting objects: 751, done.
remote: Compressing objects: 100% (346/346), done.
remote: Total 697 (delta 399), reused 632 (delta 337)
Receiving objects: 100% (697/697), 785.97 KiB | 377 KiB/s, done.
Resolving deltas: 100% (399/399), completed with 27 local objects.
From github.com:AD7six/project
3ed9793..dece27d develop -> origin/develop
e4b5ae6..94053fd master -> origin/master
x [deleted] (none) -> origin/feature/deleted-last-week
$ git branch -a
develop
master
remotes/origin/HEAD
remotes/origin/develop
remotes/origin/master
as it no longer exists on the remote. Pruning a remote can also be called explicitly as git remote prune.
When you fetch a remote repository, say “origin”, you will get remote branches for each branch that exists on that remote repository. Those branches are locally stored as <remote>/<branch>
.
So assume origin has branches master
, featureX
and featureY
. Then after fetching the following “remote branches” exist in your local repository: origin/master
, origin/featureX
and origin/featureY
.
Now, imagine someone else merges featureX
into master and removes the feature branch from the remote repository. Then origin only has two branches master
and featureY
.
However, when you fetch, the three remote branches will all still exist, including the one that was deleted in the remote repository. This is to prevent you from accidentally losing the branch (imagine someone accidentally removed the branch from the remote, then everyone who fetched from it would also lose it, making it hard to restore it).
Instead, you will need to tell the fetch command to prune any branches that no longer exist on the remote branch. So by executing git fetch --prune origin
or git fetch -p
the remote branch origin/featureX
will be removed too.
Btw. if you want to remove a branch from a remote repository, you will have to push an “empty” branch to it, e.g. git push origin :branchname
will remove the remote branch origin/branchname
both locally and on the remote itself.
Did you trying looking at the help for fetch
? git help fetch
shows:
-p, --prune
After fetching, remove any remote-tracking branches which no
longer exist on the remote.
Typically, when you fetch any new references or updates are made to your refs/remote/<remote-name>
area, with the exception of deleting references. The -p
option ask fetch
(and git remote update
) to go ahead and delete any remote references that no longer exist on the remote. git remote prune
will also remove deleted branches.
For instance, say there is a remote branch foo
. In your local repository, a reference at refs/remote/origin/foo
is kept. The someone deletes the foo
branch. The next time you run git fetch
, your reference still remains intact. If you run git fetch -p
instead, you'll see that refs/remote/origin/foo
is removed.