Skip to content
Foxipa

Suggest an edit

Tell us what should be corrected, clarified, or improved. Submission will be connected to Foxipa’s contribution service later.

No information is sent anywhere yet. Your suggestion is only prepared in your browser.

Learning

Git Repository Maintenance: gc and maintenance

Perform controlled Git repository housekeeping with git gc and the task-oriented git maintenance interface, while separating maintenance from integrity checking and storage inspection.

Levels: Advanced ~30 min read

Advanced

What repository maintenance is for

Git stores objects, references, reflogs, worktree metadata, and auxiliary indexes as a repository evolves. Maintenance performs housekeeping that can reduce storage overhead and keep later Git operations responsive. It is different from `git fsck`: maintenance changes or reorganizes repository data, while fsck primarily diagnoses object validity and connectivity.

bash
git gc
git maintenance run --task=gc

Quick check

Which distinction is correct?

Automatic housekeeping and `git gc --auto`

Git can trigger automatic housekeeping after commands that add repository data. `git gc --auto` asks Git to decide whether housekeeping thresholds require work. If the thresholds do not require it, the command can exit without performing a full cleanup.

bash
git gc --auto

Quick check

What is the purpose of `git gc --auto`?

Controlled garbage collection

`git gc` runs a collection of housekeeping tasks. The exact work can include repacking objects, pruning eligible unreachable data, packing references, and maintaining ancillary data. Use it as a repository-maintenance operation, not as a substitute for diagnosing corruption.

bash
git gc
git gc --no-prune
git gc --cruft

`--no-prune` prevents pruning of loose objects during that run. `--cruft` stores expiring unreachable objects in cruft-pack storage instead of leaving them as loose objects; current Git documentation describes cruft packs as the normal mechanism for unreachable-object packing.

Quick check

Why can `git gc --no-prune` be useful during an investigation?

Pruning is a destructive boundary

The default pruning grace period exists for safety: unreachable data may still be useful for recovery, for example through reflogs or recent history changes. `git gc --prune=now` removes eligible loose unreachable objects without waiting for the normal grace period. The official documentation warns that pruning immediately increases the risk of corruption if another process is concurrently writing to the repository. Use such a command only in a controlled disposable repository when demonstrating its effect.

bash
git gc --prune=now

Quick check

Which statement about `git gc --prune=now` is correct?

Do not reach for `--aggressive` by reflex

`git gc --aggressive` asks Git to spend substantially more time optimizing object deltas. The official documentation warns that the additional work is not automatically worthwhile and recommends considering tailored performance measurements before using it. A normal maintenance run is not equivalent to aggressive repacking.

bash
git gc --aggressive

Quick check

What is the key trade-off of `git gc --aggressive`?

`git maintenance run`: task-oriented housekeeping

`git maintenance run` provides a task-oriented interface. With `--task=<task>`, you choose a specific maintenance task; with `--auto`, Git decides whether configured automatic thresholds warrant work. This makes it possible to request maintenance without treating the monolithic `git gc` command as the only interface.

bash
git maintenance run
git maintenance run --auto
git maintenance run --task=gc

Quick check

What does `--task=gc` do?

Checking and registering background maintenance

`git maintenance register` adds the current repository to the user's maintenance repository list and configures recommended scheduled-maintenance settings. `unregister` removes the repository from that list. For a reproducible lesson, the commands below use `--config-file` so the experiment writes to a disposable configuration file rather than the learner's normal global Git configuration.

bash
git maintenance register --config-file ./maintenance.config
git maintenance unregister --config-file ./maintenance.config

On current Git, registration establishes maintenance configuration intended for scheduled runs. The official 2.56.0 documentation describes the recommended incremental strategy and the background scheduler used by `git maintenance start`. Because scheduler installation is platform-specific, this lesson verifies the portable registration/unregistration interface locally rather than pretending that a Linux-specific scheduler setup is identical on every platform.

Quick check

Why does this lesson use `--config-file` in the registration exercise?

How the surfaces fit together

Use `git count-objects`, `git repack`, and `git verify-pack` when you are inspecting storage mechanics (V477). Use `git fsck` when you need integrity/connectivity diagnostics (V476). Use `git gc` or the task-oriented `git maintenance` interface when you intentionally want Git to perform housekeeping. These are related but different jobs.

bash
git count-objects -v -H
git fsck --full
git maintenance run --task=gc

Quick check

Which command is the appropriate first choice when the question is 'are objects missing or invalid?'

Practice what you learned

Use the dedicated Git code-completion exercise for this lesson.

Verification and official-source note

Verification note: every learner-facing command form in this lesson was executed in disposable repositories with Git 2.47.3: `git gc`, `--auto`, `--no-prune`, `--cruft`, `--prune=now`, `--aggressive`, `git maintenance run`, `--auto`, `--task=gc`, `git maintenance register --config-file`, and `git maintenance unregister --config-file`. The current official Git 2.56.0 `git-maintenance` documentation and the official `git-gc` documentation were used as the semantic sources. The current `git-gc` manual reports no changes from 2.53.0 through 2.56.0; the `git-maintenance` manual is updated in 2.56.0.

This lesson intentionally does not teach the newer 2.56.0-only or locally unavailable forms that cannot be executed by the installed Git 2.47.3 verifier. Local execution evidence is never silently generalized to every Git release.

Was this page helpful?

Mark this learning resource complete to track your learning progress.