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 --pruneThis 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 --allWill print the following:
* feat-abc
main
remotes/origin/HEAD -> origin/main
remotes/origin/feat-abc
remotes/origin/mainLater, feat-abc is deleted from the remote and you fetch:
git fetch --prune
git branch --allThe print out will reflect that feat-abc is no longer in the remotes:
* feat-abc
main
remotes/origin/HEAD -> origin/main
remotes/origin/mainIf, 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 -dI 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 = trueOr, setting this from the command line:
git config --global fetch.prune trueUsing 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!