TortoiseGit Clean up: Turning git gc into a Windows Maintenance Habit
TortoiseGit's Clean up dialog wraps git gc in a familiar Windows interface, but the checkboxes hide real trade-offs. Here is how to use it as a maintenance routine without losing data.
28 Aug 2025, 00:29 UTC

A Windows repository can look perfectly healthy in TortoiseGit's Log dialog while its .git directory quietly accumulates thousands of loose objects. Clones slow down, disk usage creeps upward, and status checks start to feel sluggish. The cause is usually not corruption—it is fragmentation. Git stores new commits as loose objects until a garbage-collection pass packs them together. TortoiseGit exposes that maintenance through its Clean up dialog, but treating it as a one-click "make faster" button skips decisions that matter.
The useful takeaway: TortoiseGit's Clean up command is a safe, scheduled maintenance routine if you understand what each checkbox controls, when to avoid aggressive optimization, and how to verify the result. It wraps git gc and related plumbing commands, but GUI labels and available options can vary across TortoiseGit versions and installed Git versions, so map the concepts rather than memorizing exact wording.
What the Clean up dialog actually controls
The dialog generally exposes options that map directly to Git's housekeeping plumbing. While exact labels differ by version, the underlying behaviors are consistent:
- Expire unreachable objects removes objects that no reference points to, similar to
git prune. This is the core space-saving step. - Expire reflog entries clears the reference log, which is the local safety net for recovering accidentally dropped commits. Once expired,
git reflogno longer shows those entries. - Aggressive optimization asks Git to spend extra CPU time repacking objects more thoroughly. It often reduces pack count, but it can take significantly longer and may not help small or already-packed repositories.
- Pack reindexing rebuilds the index files that make pack lookups fast.
Because these options change what Git keeps on disk, they are not cosmetic. A standard cleanup without reflog expiry is usually the right default for day-to-day maintenance.
A worked example: maintenance after a long-lived merge
Suppose a feature branch ran for several weeks and you have just merged it into main. The repository now contains many loose objects from the merge commits, and the branch ref is gone. This is a natural moment for a standard cleanup.
Before you start, confirm that TortoiseGit and your command-line tools use the same Git installation. Open TortoiseGit > Settings, check the configured Git version path, then run the following in a Git Bash or Command Prompt window inside the repository root. Standard user permissions are sufficient for these read-only checks:
git version
Expected check: the version string should correspond to the Git binary TortoiseGit points to. If they differ, your CLI verification steps may not reflect what the GUI actually ran.
Next, capture a baseline. In the same terminal, run:
git count-objects -v
This reports loose object counts, pack counts, and disk usage. Note the count and in-pack values. You can also open the .git folder properties in Windows Explorer and record its size.
Now run the cleanup. In Windows Explorer, right-click the repository folder, choose TortoiseGit > Clean up, and select only the standard options—expire unreachable objects and pack reindexing. Leave aggressive optimization and reflog expiry unchecked unless you have a specific reason. The operation changes on-disk state; there is no undo.
After the dialog finishes, verify in TortoiseGit's Log dialog that the merge commit and recent history are intact. Then re-run the baseline command:
git count-objects -v
Expected check: the loose count should drop, and in-pack should rise or stay stable as objects are consolidated. Finally, run an integrity check:
git fsck
This is read-only, but on large repositories it can take time. A clean result means no reachable objects were lost. If you see unexpected dangling objects, investigate before pushing.
Once you are satisfied, push the cleaned repository to the shared remote.
Trade-offs and limitations
Aggressive optimization is not free. It can reduce pack count and improve long-term performance, but it often takes significantly longer. On very large repositories during active development hours, the extra CPU and I/O can slow concurrent Git operations for everyone on the team.
Reflog expiry removes a safety net. If a prior operation failed unexpectedly and left unreachable objects that you actually needed, expiring the reflog makes recovery harder. Only enable it when you are certain the reflog is not needed.
Shared bare repositories need coordination. Running cleanup on a shared bare repository changes object storage on disk and can briefly increase I/O load for concurrent clones or fetches. Schedule it during low-traffic windows.
Cleanup is not a backup. It prunes unreachable objects, which may include data you intended to keep if a prior operation failed unexpectedly. Keep separate backups.
A practical routine
Treat Clean up as scheduled hygiene, not a rescue tool. A reasonable pattern for a workstation repository is:
- Run
git count-objects -vand note the.gitsize before major merges or monthly. - Perform a standard cleanup via the context menu after merging long-lived branches.
- Re-run
git count-objects -vandgit fsckto confirm consolidation and integrity. - Reserve aggressive optimization for large repositories during off-hours, and only when pack counts justify the extra time.
- Leave reflog expiry off unless you have a specific recovery policy in place.
This keeps repositories lean without gambling with history you might need later.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.