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.ago

It 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 --expire cutoff).

    • 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.ago

Command 1

git repack -adfln --keep-unreachable --depth=20 --window=200

Purpose

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

  • -a Packs all objects referenced by any ref into a single pack, instead of only packing unpacked objects. Frequently combined with -d.

  • -d After creating the new pack, removes redundant old packs and runs git prune-packed to delete loose objects that are now safely stored in a pack.

  • -f Passes --no-reuse-delta to git pack-objects. This recomputes all deltas instead of reusing existing ones, which can improve compression at the cost of additional CPU.

  • -l Passes --local to git pack-objects. Only packs objects from the local object store, ignoring objects from alternates (if configured).

  • -n Prevents git update-server-info from being run.

  • --keep-unreachable Instructs 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=20 Limits 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=200 Sets 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.ago

Purpose

Performs another aggressive repack that:

  • Packs all referenced objects, with special handling for unreachable objects when combined with -d and -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 run git prune-packed after repack.

  • -f – Pass --no-reuse-delta (recompute deltas).

  • -l – Pass --local (only local objects).

  • -n – Do not run git update-server-info.

  • --window=200 – Large delta search window.

Different/additional flags

  • -A

    • Without -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=10 Limits 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.ago are unpacked (left as loose objects).

    • Unreachable objects older than 72.hours.ago are not unpacked and they remain in packs and may be pruned later when those packs are discarded.

Command 3

git prune --expire=72.hours.ago

Purpose

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:

  1. Repacking

    • git repack consolidates objects into optimised packfiles and removes redundant packs (-d).

    • Flags such as --depth and --window control how aggressively objects are delta‑compressed.

  2. Handling unreachable objects

    • --keep-unreachable, -A (with -d), and --unpack-unreachable control 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.

  3. Pruning (data removal)

    • git prune --expire=72.hours.ago removes older unreachable objects to reclaim disk space, based on the expiry window.

Updated on January 30, 2026

Still need help?

The Atlassian Community is here for you.