2020-08-08
|~3 min read
|498 words
Pruning is part of the Git’s garbage collection. It’s a way to prune references to unreachable or “orphaned” Git objects.
Typically, pruning has to do with local objects that have become detached. An object can become orphaned in a number of ways, but if you ever get the following message from Git, you know you’ve reached an orphan:
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b <new-branch-name>
HEAD is now at 5178bec... an awesome new feature!
Common ways this happens is when altering history, for example with a git reset
or git rebase
.
If we wanted to remove the detached objects, we can use git gc
and git prune
in tandem. This, however, is quite different from the more common place I’ve seen the term prune
in Git, which is as an option of the fetch
command.
git fetch --prune
This will keep your local references to the remote repository up-to-date. It does not delete a local version of the branch, only the ref to the remote version. An example might be helpful to visualize this:
You had pull down the branch feat-abc
from master:
git checkout -t origin/feat-abc
git branch --all
Will print the following:
* feat-abc
main
remotes/origin/HEAD -> origin/main
remotes/origin/feat-abc
remotes/origin/main
Later, feat-abc
is deleted from the remote and you fetch:
git fetch --prune
git branch --all
The print out will reflect that feat-abc
is no longer in the remotes:
* feat-abc
main
remotes/origin/HEAD -> origin/main
remotes/origin/main
If, after cleaning up the remote refs, you want to remove any deleted branches, you can use this one liner to help:
git branch -vv | grep '[origin/.*: gone]' | awk '{print $1}' | xargs git branch -d
I wrote more about how this works previously, here.
If you want to make this clean up done by default, you can indicate this within the .gitconfig
One setting I’ve seen suggested added to the global Git config is:
#...
[fetch]
prune = true
Or, setting this from the command line:
git config --global fetch.prune true
Using git prune
is typically used as a child command of git gc
and not needed to be executed directly most of the time. That said, I have found it helpful to keep things organized by updating my global git config to always prune on pull - though there are some good arguments against this as well.
For more on git prune
, Atlassian has put together a nice tutorial.
Hi there and thanks for reading! My name's Stephen. I live in Chicago with my wife, Kate, and dog, Finn. Want more? See about and get in touch!