Agenda
Introduction
Git Prune
Usage
Example
Differences
git prune
git fetch --prune
git remote prune
Conclusion
Introduction
We do commit after every small change we make in the source code to be sure all the changes are reserved. But in reality when we make final push to master there would be several commits we may need to ignore or detach.
As we know git is very careful of about deleting data, and hard to lose any commits. Due to this the downside is lots of stale data is reserved even if its not going to used.
One of the method to do clean up is using prune.
Git Prune
The git prune command is an internal house keeping utility that is used to clean up the unreachable or orphaned git objects.
Unreachable objects are those which are not accessible by any refs.
For an example, say you have made two commits. And the latest have reset commit to different head, by calling the git reset <commit id> command. Though the git log command will not show the commit info. But internally git still stores as dangling object.
Usually we as users need not call git prune directly whereas call git gc the git garbage collection command. As this will prune along with many other house keeping tasks.
Usage
Here we will prune syntax and its options.
git prune –-dry-run
To not to perform the prune operation rather show the output what it will be performed
git prune –-verbose
Will report all the actions and its associated objects
git prune –-progress
Will show the progress made by the command
git prune –-expire <time>
Will remove only for the objects which are older than the given time
Example
# Cloning one of the git repository, else you can create your own repository using git init
% git clone https://github.com/hasura/graphql-engine.git
Cloning into 'graphql-engine'...
remote: Enumerating objects: 66417, done.
remote: Counting objects: 100% (5997/5997), done.
remote: Compressing objects: 100% (2118/2118), done.
remote: Total 66417 (delta 3840), reused 5775 (delta 3718), pack-reused 60420
Receiving objects: 100% (66417/66417), 77.20 MiB | 3.11 MiB/s, done.
Resolving deltas: 100% (44018/44018), done.
Updating files: 100% (5104/5104), done.
# Create sample file and insert first line
% cat >> hello.txt
This is the first line
# Add and commit the file
% git add hello.txt
% git commit -m "add the file hello"
[master bec274f52] add the file hello
1 file changed, 1 insertion(+)
create mode 100644 hello.txt
# Update the file adding second line
% cat >> hello.txt
This is the second line
% cat hello.txt
This is the first line
This is the second line
# Add and commit the same file again
% git add hello.txt
% git commit -m "added second line in the file hello"
[master 3af6fea8d] added second line in the file hello
1 file changed, 1 insertion(+)
# Check the log, need to find two git commit
% git log
commit 3af6fea8dbb44973ddeed856036d0792d15a4ad7 (HEAD -> master)
Author: xxxxxxx <xxxxxxx@xxxxxxx>
Date: Sun Jun 13 20:29:00 2021 +0530
added second line in the file hello
commit bec274f5264140c9ff1f9b8b6f956c69295a29d4
Author: xxxxxxx <xxxxxxx@xxxxxxx>
Date: Sun Jun 13 20:27:39 2021 +0530
add the file hello
# Lets now reset the head version of the file to the previous commit
% git reset --hard bec274f5264140c9ff1f9b8b6f956c69295a29d4
HEAD is now at bec274f52 add the file hello
# Check the git log, the last created commit would have been vanished
% git log
commit bec274f5264140c9ff1f9b8b6f956c69295a29d4 (HEAD -> master)
Author: xxxxxxx <xxxxxxx@xxxxxxx>
Date: Sun Jun 13 20:27:39 2021 +0530
add the file hello
# Find the dangling commit, as said git still remembers
% git fsck --lost-found
Checking object directories: 100% (256/256), done.
Checking objects: 100% (66417/66417), done.
dangling commit 3af6fea8dbb44973ddeed856036d0792d15a4ad7
# Check the detail if it was the same commit
% git show 3af6fea8dbb44973ddeed856036d0792d15a4ad7
commit 3af6fea8dbb44973ddeed856036d0792d15a4ad7
Author: xxxxxxx <xxxxxxx@xxxxxxx>
Date: Sun Jun 13 20:29:00 2021 +0530
added second line in the file hello
diff --git a/hello.txt b/hello.txt
index d3e2104b9..81bc58de5 100644
--- a/hello.txt
+++ b/hello.txt
@@ -1 +1,2 @@
This is the first line
+This is the second line
# When prune is run now, there might be no affect. As git might be maintaining the reference, possibly not fully detached.
# Run the reflog to expire all the entries that are older than now
# Note: This is not advisable to do, prefer git gc always than git prune
% git reflog expire --expire=now --expire-unreachable=now --all
# Before running the prune, always run the dry run to check the changes
% git prune --dry-run --verbose --progress --expire=now
142cc07007d0107e8ff91b28e2a7b078a6f56d1c tree
3af6fea8dbb44973ddeed856036d0792d15a4ad7 commit
81bc58de5525b0c16f8cb74b89799017b6986981 blob
# Run the actual prune command
% git prune --verbose --progress --expire=now
142cc07007d0107e8ff91b28e2a7b078a6f56d1c tree
3af6fea8dbb44973ddeed856036d0792d15a4ad7 commit
81bc58de5525b0c16f8cb74b89799017b6986981 blob
# Now the dangling commit would have been cleared
% git fsck --lost-found
Checking object directories: 100% (256/256), done.
Checking objects: 100% (66417/66417), done.
Differences
git fetch --prune
Another way to clean up, is for the branches by again using prune option but now with git fetch and git remove.
Orphaned branches are branches that are not connected to any others and have been left unused.
It is a good practice to prune the branches that are not being used.
The simplest way to prune is by using git fetch -–prune. This will fetch all the remote branch refs and delete the remote refs that are no longer in used in the remote repository.
Its advisable to use the dry run before execution, such as,
$ git fetch --prune origin --dry-run
git remote prune
Same as git fetch -–prune, this command will also remove the refs to the branches which don't exist on the remote.
But the difference, we can use git remote prune when we would want to perform prune and do not fetch the remote data.
The git maintains both the local/origin and remote /origin refs. Using this command it will only prune the refs from the remote/origin. This way it will safely leave the local/origin untouched.
git prune
As seen above this is different from git remote prune, as it deletes only locally the detached commits.
Conclusion
Today we have seen the usage and different options of the git prune. Hope henceforth you will have handy way to maintain your git clean.
Reference and Credits:
https://www.atlassian.com/git/tutorials/git-prune
https://external-preview.redd.it/Tboo_FCn9vTgptJmXn5-rcz-SQEyjpl7hitfpihXYAY.jpg?auto=webp&s=4a4d37b370447857ec1a3254a81e261c1ad89e48
Original Blog Posted in OSFY
https://www.opensourceforu.com/2021/11/git-prune-check-out-this-housekeeping-utility/
For further research and updates maintaining the blog here.

No comments:
Post a Comment