Using git fetch --prune deletes local remote tracking branches when the branch on the remote machine has been deleted. Setting remote.origin.prune to true using the following...
git config --global fetch.prune true
...makes using the fetch command always implicitly use the --prune option.
I am putting together a best-practices/introduction to git for some developers in my group who aren't quite familiar with it. I want to be sure I know this is not a dangerous behavior before advising them to do so. I at least give them a heads up of what to watch out for if there is some extraneous mishap case.
It doesn't seem like this is a destructive operation because it doesn't delete any local (non-remote) branches. It also seems like this is a great way to not build up remotes that aren't in use anymore without periodically specifying git fetch --prune or git remote prune.
If this is all true, why is this not the default behavior for git?
git fetch --prune is the best utility for cleaning outdated branches. It will connect to a shared remote repository remote and fetch all remote branch refs. It will then delete remote refs that are no longer in use on the remote repository.
The prune option removes any remote tracking branch in your local repository that points to a remote branch that has been deleted on the server. With the local branch deleted, the remote tracking branch deleted, and all instances of the remote git branch deleted as well, the remote Git branch should be gone forever.
git remote prune origin This command deletes branch references to remote branches that do not exist. A remote branch can be deleted as a result of a delete-branch-after merge-operation.
Git Fetch Options Below is the list with commonly used options when working with git fetch : --all - Fetch all remotes. --append ( -a ) - Appends to existing fetched contents without overwriting. --depth=<depth> - Limit to a specific number of commits starting from the tip of each remote branch history.
It's not fundamentally dangerous, and I have been tempted to set it in my own --global
settings, but I never have: primarily because it also has relatively little value to me.1
As you note, the intent is, in essence, to remove origin/zorg
once branch zorg
is no longer present on origin
. Since this has no direct effect on your own zorg
, if you have one at all, it's generally harmless, and declutters your view of remote-tracking branches. The only two possible downsides are:
If someone mistakenly deletes zorg
on the upstream repository, and all the downstream copies prune their origin/zorg
, you lose the ID of the commit (and perhaps many commits themselves) that was the tip of zorg
in that upstream repository. So it magnifies the effect of some mistakes. (Of course, if the upstream repository is that important, you probably should be making backups anyway—though if you choose to use the clones as backups, automatic pruning has a downside there. Of course, you can always disable automatic pruning specifically on these backups.)
Suppose you do have your own zorg
that is tracking origin/zorg
, and the upstream zorg
gets deleted (on purpose this time). Note that it has been your origin/zorg
that provides you with git status
information telling you how many commits you were ahead of origin/zorg
. Suppose that you would now like to move these commits, but not commits-that-used-to-be-upstream, to another of your own branches. In this case, automatically pruning your own origin/zorg
makes it difficult to tell which commits were yours, and which were already in the upstream.
Note that in case 2, you do not lose any commits. What you lose is the ability to tell that, e.g., only the last three commits currently on your zorg
were your own, with several before that (that are not on any other branch now) having originally been on origin/zorg
.
1Over the years, the pruning code has sometimes been somewhat broken, mostly in terms of failing to prune. This implies that the Git developers themselves probably don't use it much (but things should be better now since there are now tests in Git's internal test-suite to make sure pruning works correctly in new releases). So between "low value" and "insufficient testing in the past", that was, at least at the time, sufficient reason not to set it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With