Why we use git prune function
Git prune
is a git function whose main purpose is cleaning stale or dormant objects from a git repository. A stale object in git becomes unreferenced and cannot be reached. Git stale objects examples include tags, commits and changes in git history that cannot be easily traced.
Git prune operates as a deposable bin for wasted data in the git repository history. Understand that the prune function isn’t directly executed and it’s an offspring of the garbage collection command. The git garbage collection command (gc) is the one responsible for sustaining a repository. It empties all the mess in a repository and keeps it clean.
In this tutorial, we are going to explore scenarios that use the prune operator and demonstrate how to apply the prune function in those scenarios.
git prune syntax
$ git prune < --dry-run>| <-v> | <--progress> |<--expire <time> |<-- > |<head>…
Here,
--dry-run
: this option only reports what has been pruned-v (--verbose)
: outputs all the pruned data--progress
: outputs the cleaning progress--expire <time>
: determines the expiry of the wasted objects--
: regulates the options to input in the function<head>…
: maintain the listed referenced heads history.
git prune workflow
Setting up the lab environment
To practice using git prune
, we shall first set up the lab environment. Let's clone the remote project prune-exprt
 to the local workstation for use in this experiment. I will be using windows 10 pro and git version 2.32.0.windows.2. Now, we shall proceed to run the git clone
command as follows:
$ git clone https://github.com/J-Mulombi/prune-exprt.git
Cloning into 'prune-exprt'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (3/3), done.
We shall move to the next section, where we will experiment using git prune in different scenarios.
git prune examples
To practice using git prune
, we will first add some commits to the local project prune-exprt
and make some of them inaccessible (missing refs).
Scenario-1: git prune unreachable commits from history
When multiple team members are working on a single repository then over a period of time, the commit history piles up with multiple unreferenced commits which may have been deleted in past.
So it is a good idea to clean up the unreachable objects. First let us check the disk consumption on our git repository used by different objects:
$ git count-objects -v count: 55 size: 220 in-pack: 38 packs: 1 size-pack: 5 prune-packable: 0 garbage: 0 size-garbage: 0
Next check the list of unreachable and unreferenced commits and objects in our repository using git fsck command:
$ git fsck --unreachable Checking object directories: 100% (256/256), done. Checking objects: 100% (38/38), done. unreachable blob 01dd0d813550913ec31fe0e51ab0eaa31a88e980 unreachable tree 0a5568b3eb72786b7d025f317905c26d9b2a59ce unreachable blob 0b905be127e5b18c180438eafebce6f23ddf0afb unreachable tree 2a2b1c0dfdb7790feae90e9a28f1e53400c77910 unreachable tree 3076fbe7920eea3b4d6d9db1268e5ba760579411 ... unreachable blob ebc8f5b5ee9f3921340ffaea7f5e3ab2f942ba3c unreachable blob ef5ec28cddbc7789c7797b26c2de4d4a519355dd unreachable tree f515109f390afe9f54a81f105471c8c3ad2c0d34 unreachable blob f9f8d65d14f073dee62ed15a4413a6e277397d50 unreachable commit fa16ae6089b3508e34843a713e46760265eb02ad
So, we have quite some amount of unreachable objects which needs clean up. Next we will go ahead and prune these objects from our repository:
$ git prune --expire=now --verbose 01dd0d813550913ec31fe0e51ab0eaa31a88e980 blob 0a5568b3eb72786b7d025f317905c26d9b2a59ce tree 0b905be127e5b18c180438eafebce6f23ddf0afb blob 0d2ce16261a7c5d6fa12747565905895358cbcc9 commit 14348c010714be703b1fcb99de054e78a2e70c1a tree ... ef5ec28cddbc7789c7797b26c2de4d4a519355dd blob f515109f390afe9f54a81f105471c8c3ad2c0d34 tree f9f8d65d14f073dee62ed15a4413a6e277397d50 blob fa16ae6089b3508e34843a713e46760265eb02ad commit
Check the list of unreachable objects again:
$ git fsck --unreachable
Checking object directories: 100% (256/256), done.
Checking objects: 100% (38/38), done.
Now we don't have any such unreferenced or unreachable objects in our repository. Let us update the storage size of our git repository:
$ git gc
Enumerating objects: 38, done.
Counting objects: 100% (38/38), done.
Compressing objects: 100% (23/23), done.
Writing objects: 100% (38/38), done.
Total 38 (delta 3), reused 38 (delta 3), pack-reused 0
Verify the updated disk consumption status:
$ git count-objects -v count: 0 size: 0 in-pack: 38 packs: 1 size-pack: 5 prune-packable: 0 garbage: 0 size-garbage: 0
You can compare this with our last value, our exercise has cleaned up alot of objects which were not in use in our repository with no impacts to our commits:
$ git log --oneline 08ffd72 (HEAD -> main) commit-3 cb4fcac commit-2 cba988c commit-1 0320b58 commit-E 6d2bc8b commit-D a8afb3c commit-C e3ab8c3 commit-B 54a79f1 commit-A
Scenario-2: git prune a remote branch
Suppose there are multiple members working on a repository, so it is obvious every team member may be creating separate branch for their personal changes.
In such scenarios team members may also delete their branch on the remote repository but if someone had already pulled the remote branch then their local repo would still have reference of stale remote branches. So one can use git remote prune
to remove such stale branches
Here I have two users, deepak
and alisha
who have cloned a repository. Now alisha
decides to delete new-issue-7843
branch from the remote repository:
alisha@ubuntu:~/git_examples$ git push origin --delete new-issue-7843
To gitlab.com:golinuxcloud/git_examples.git
- [deleted] new-issue-7843
While the same branch is still visible for deepak
user:
So user deepak
can execute the following command to prune any such stale branches:
deepak@ubuntu:~/git_examples$ git remote prune origin
Pruning origin
URL: git@gitlab.com:golinuxcloud/git_examples.git
* [pruned] origin/new-issue-7843
Check the list of available remote branches, so new-issue-7843
branch is not shown any more on the remote origin:
Scenario-3: git prune while fetching a remote branch
You can prune a remote branch while fetching as follows;
First, let's run the git branch –a
command to view all the branches in the prune-exprt
project.
$ git branch -a * feature jira master remotes/origin/HEAD -> origin/master remotes/origin/feature remotes/origin/jira remotes/origin/master
Assuming this is a collaborated project, a team member removes the remote jira
branch. To fetch the update and remove the deleted jira remote contents, we will run the git fetch --prune origin
command as displayed below:
$ git fetch --prune origin
From https://github.com/Maureen-Mulombi/prune-exprt
- [deleted] (none) -> origin/jira
To confirm removal of the remote jira
branch let's run the git branch –a
command again as follows:
$ git branch -a feature jira * master remotes/origin/HEAD -> origin/master remotes/origin/master remotes/origin/mybranch
We no longer have the jira remote
branch displayed in the results.
Git prune fetch
command helps to check on stale remote commits that you may not be aware of while working on your remote repository.
Git does not allow deletion of history hence the statement deleted none in the earlier output.
Scenario-4: Remove remote tags using the prune command
To remove tags that are no longer active remotely apply the git fetch --prune --prune-tags
command as illustrated:
$ git fetch --prune --prune-tags
From https://github.com/J-Mulombi/prune-exprt
- [deleted] (none) -> origin/feature
We do not have any remote tags removed yet in the remote feature
branch according to the output.
Summary
We have covered the following topics about the prune operator:
- Understanding the prune function application in git
- Git prune options
- Git prune scenarios