Understanding git repack and git prune options in Bitbucket Data Center
Platform Notice: Data Center Only - This article only applies to Atlassian apps on the Data Center platform.
Note that this KB was created for the Data Center version of the product. Data Center KBs for non-Data-Center-specific features may also work for Server versions of the product, however they have not been tested. Support for Server* products ended on February 15th 2024. If you are running a Server product, you can visit the Atlassian Server end of support announcement to review your migration options.
*Except Fisheye and Crucible
Summary
Learn how Bitbucket Data Center uses git repack and git prune commands for repository maintenance, and what each option means for performance, data retention, and disk space.
Solution
Let's understand what the following Git maintenance commands do and how each flag affects repository maintenance, especially when Bitbucket Data Center invokes the underlying operations:
git repack -adfln --keep-unreachable --depth=20 --window=200
git repack -Adfln --depth=10 --window=200 --unpack-unreachable=72.hours.ago
git prune --expire=72.hours.agoIt is intended to help Bitbucket administrators and advanced Git users understand the impact of these options on repository size, performance, and data retention.
Bitbucket Data Center does not run git gc. It invokes low‑level Git operations such as git pack-refs, git repack, and git prune directly. Administrators should avoid running git gc on Bitbucket repositories and instead rely on these underlying commands or Bitbucket’s built‑in GC mechanisms.
What git repack and git prune does?
git repack
Rewrites Git objects into new packfiles to reduce redundancy.
Consolidates loose objects and fragmented packs into fewer, optimized packs.
Can significantly reduce repository size and improve performance for operations that read objects from disk.
git prune
Permanently deletes unreachable objects from the object store.
Only affects objects that are not referenced by any branch, tag, or reachable reflog entry (subject to the
--expirecutoff).Once pruned, these objects cannot be recovered via normal Git history operations.
Understanding the options below helps you evaluate maintenance strategies for large or long‑lived repositories.
Example commands and flags
This section explains what each flag does in the following Git maintenance commands, using the official git-repack and git-prune documentation as reference:
git repack -adfln --keep-unreachable --depth=20 --window=200
git repack -Adfln --depth=10 --window=200 --unpack-unreachable=72.hours.ago
git prune --expire=72.hours.agoCommand 1
git repack -adfln --keep-unreachable --depth=20 --window=200Purpose
Performs an aggressive repack that:
Packs all referenced objects into new, optimized packfiles.
Uses deeper delta compression (
--depth=20) and a large delta search window (--window=200) to improve compression.Preserves unreachable objects by keeping them packed (
--keep-unreachable), rather than letting them be pruned when old packs are removed.Skips updating HTTP/FTP “server info” metadata (
-n), but still repacks.
Flag explanations
-aPacks all objects referenced by any ref into a single pack, instead of only packing unpacked objects. Frequently combined with-d.-dAfter creating the new pack, removes redundant old packs and runsgit prune-packedto delete loose objects that are now safely stored in a pack.-fPasses--no-reuse-deltatogit pack-objects. This recomputes all deltas instead of reusing existing ones, which can improve compression at the cost of additional CPU.-lPasses--localtogit pack-objects. Only packs objects from the local object store, ignoring objects from alternates (if configured).-nPreventsgit update-server-infofrom being run.--keep-unreachableInstructs Git to preserve unreachable objects during repack rather than dropping them. Typically, unreachable objects are collected into a separate pack instead of being pruned when old packs are removed. This helps ensure you don’t lose unreachable data during this repack step.--depth=20Limits the maximum delta chain depth to 20. Deeper chains usually result in better compression but can make unpacking more expensive and increase repack CPU cost.--window=200Sets the number of candidate objects considered when looking for a delta base. A larger window (200) improves compression opportunities but increases CPU and memory usage during repack.
Command 2
git repack -Adfln --depth=10 --window=200 --unpack-unreachable=72.hours.agoPurpose
Performs another aggressive repack that:
Packs all referenced objects, with special handling for unreachable objects when combined with
-dand-A.Uses a moderate delta depth (
--depth=10) with a large window (--window=200) for balanced compression.Controls which unreachable objects are unpacked (loosened) from packs (
--unpack-unreachable).Skips updating server info (
-n), but still repacks.
Shared flags with Command 1
-d– Remove redundant packs and rungit prune-packedafter repack.-f– Pass--no-reuse-delta(recompute deltas).-l– Pass--local(only local objects).-n– Do not rungit update-server-info.--window=200– Large delta search window.
Different/additional flags
-AWithout
-d, behaves the same as-a.With
-d, any unreachable objects that were stored in old packs are unpacked into loose objects instead of being left in packs that are about to be deleted.This avoids silently losing unreachable objects just because the old pack is removed; they are left as loose objects so they can later be pruned according to normal expiry rules.
--depth=10Limits delta chain depth to 10. This is less aggressive than 20, trading a bit of compression for reduced CPU and somewhat simpler delta chains.--unpack-unreachable=<when>(here--unpack-unreachable=72.hours.ago)When loosening unreachable objects (e.g., due to
-A -d),Unreachable objects newer than
72.hours.agoare unpacked (left as loose objects).Unreachable objects older than
72.hours.agoare not unpacked and they remain in packs and may be pruned later when those packs are discarded.
Command 3
git prune --expire=72.hours.agoPurpose
Runs a garbage collection step that:
Permanently deletes unreachable objects whose timestamp is older than 72 hours.
Keeps unreachable objects that are newer than 72 hours.
This is an irreversible cleanup and should only be performed when older unreachable data is no longer required.
Flag explanation
--expire=<time>(here--expire=72.hours.ago)Only prunes unreachable objects older than the specified cutoff.
Provides a safety window so recent operations that temporarily create unreachable objects (such as recent force pushes or branch rewrites) are not immediately removed.
How these commands fit together conceptually
While Bitbucket Data Center manages garbage collection internally using similar low‑level commands, it can be helpful to think of maintenance in three phases:
Repacking
git repackconsolidates objects into optimised packfiles and removes redundant packs (-d).Flags such as
--depthand--windowcontrol how aggressively objects are delta‑compressed.
Handling unreachable objects
--keep-unreachable,-A(with-d), and--unpack-unreachablecontrol whether unreachable objects are:Preserved in new packs,
Unpacked into loose objects (to be pruned later),
Or left in packs that may later be deleted.
Pruning (data removal)
git prune --expire=72.hours.agoremoves older unreachable objects to reclaim disk space, based on the expiry window.
Was this helpful?