To revert a specific file to its previous state in the last commit:
|
|
Or if you just want to restore the file locally without amending the commit yet:
|
|
This replaces the file with its version from one commit before, staging it automatically.
But All Traces of the File’s Commit Aren’t Gone
As described in the previous article, any history rewrite (amend, rebase, etc.) leaves the old commit object and its associated tree/blob objects as dangling. It doesn’t matter whether you removed a file or just reverted a change—the previous version of that blob stays in .git/objects until garbage collected.
The same cleanup applies:
|
|
The reflog is actually the main thing keeping those objects “reachable.” Git’s reflog records where HEAD and branch tips previously pointed, so even after rewriting, the old commits are referenced there for a default of 90 days. That’s why you need to expire it first before gc will prune anything.
The official Git documentation explains that “the expiration time is taken from the configuration setting gc.reflogExpire, which, in turn, defaults to 90 days.”
Worth noting: unreachable entries have a separate setting gc.reflogExpireUnreachable, which defaults to 30 days. So after a history rewrite, the old entries are unreachable and would become prunable after 30 days, not 90.
Follow me
Thanks for reading this article. Make sure to follow me on X, subscribe to my Substack publication and bookmark my blog to read more in the future.
Credit: Git Logo by Jason Long is licensed under the Creative Commons Attribution 3.0 Unported License.