Does Git's Default Reflog Window Make Schema-Change Rollback Safe?
0 reputation · 31 Jan 2023, 04:58 UTC
0 reputation · 31 Jan 2023, 04:58 UTC
A repository that tracks schema migrations needs a defined rollback safety net: if a migration commit has to be undone weeks after it landed, the pre-change state should still be recoverable. The mechanism under consideration is Git's reflog, which records HEAD movements for a configurable retention period, 90 days by default, adjustable through gc.reflogExpire.
The open question is whether that mechanism is dependable for this purpose. Reflog entries expire once the retention window passes, after which recovery depends on already knowing the commit hash or holding an external copy. The reflog is also maintained per clone, so it only helps in the working copy where the original operations happened. Meanwhile, git reset --hard discards uncommitted work outright, while git revert requires identifying the exact commit to undo.
Does the default 90-day window make the reflog a reliable safety net for reversing schema changes, or should gc.reflogExpire be raised deliberately for migration-heavy repositories? Which rollback approach preserves recoverability when the original commit hash is no longer known?
32775 reputation · 31 Jan 2023, 05:44 UTC
No. The default 90-day reflog window is not a dependable safety net for rolling back schema-change commits weeks or months later, and raising gc.reflogExpire alone does not make it reliable.
Reflog is local and ephemeral. It can help you find a lost HEAD position on the exact clone where the operation happened, within the retention window. It does not provide shared, long-term recoverability for a team, and it does not help when the commit hash is unknown and the entry has expired.
.git/logs/ and is not pushed to a remote.gc.reflogExpire and gc.reflogExpireUnreachable. The commonly cited default is 90 days for reachable reflog entries, with a longer default for unreachable entries. Exact defaults can vary by Git version and existing config.git reset --hard moves HEAD and discards working tree changes. It does not delete commits immediately, but recovery after the reflog expires depends on knowing the commit hash.git revert creates a new commit that undoes a previous commit. It requires identifying the exact commit to revert.For a migration-heavy repository the risk is per-clone isolation and expiry. If the developer who applied the migration deletes their clone, runs aggressive git gc --prune=now, or the 90-day window passes, the reflog entry that points to the pre-migration state disappears. The commit may still exist in the object database until garbage collection, but without a reference it becomes unreachable and eventually unrecoverable.
Raising gc.reflogExpire lengthens the window on that clone only. It does not create a shared safety net.
git tag schema/pre-2026-10-15 origin/main and push the tag.git reflog --oneline -n 50. Note the commit hash, then create a permanent reference: git branch schema-rollback- and push it.git revert -m 1 on a shared branch rather than git reset --hard, which rewrites history.Assumption: you are using Git 2.x with standard garbage collection behavior. Uncertainty remains around the exact default values on your installations; verify with git config --get gc.reflogExpire.
One diagnostic that changes the recommendation: are migration commits required to be recoverable across all team clones and CI environments, or only on a single long-lived operations clone? If cross-clone recovery is needed, reflog is unsuitable and tags/protected branches or an external backup are required.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.