Git pack-objects: Construct Pack Archives
Construct Git pack archives from object lists and revisions, control object selection and delta compression, and understand the boundary between low-level pack construction and repository repacking.
Advanced
What `git pack-objects` actually does
`git pack-objects` reads objects or revision arguments and writes a packed archive. A pack stores objects together, potentially using delta compression, and normally has a matching `.idx` file for random access. This is the low-level pack constructor; ordinary users normally reach pack creation through higher-level commands such as `git repack`.
git rev-list --objects --all | git pack-objects --stdout > objects.packQuick check
Which operation is owned by `git pack-objects`?
Explicit object lists
Without `--revs`, the command reads object names from standard input. The names can be supplied directly or obtained from another plumbing command such as `git rev-list --objects`. With `--stdout`, the binary pack is written to standard output instead of a named pack file.
git rev-list --objects HEAD | git pack-objects --stdout > selected.packQuick check
What does `--stdout` change?
Writing a pack and index pair
When a base name is supplied instead of `--stdout`, `pack-objects` writes a `.pack` and corresponding `.idx` pair. The final pack name incorporates a hash derived from the pack contents, and the pack name is also reported on standard output.
git rev-list --objects --all | git pack-objects .git/objects/pack/pack-from-lessonQuick check
What does a base-name invocation produce?
Revision mode with `--revs`
`--revs` changes the standard-input interpretation: Git reads revision arguments in the same style used by `git rev-list --objects`. This lets the command perform the reachability walk itself. `--all` implies `--revs` and includes objects reachable from all refs under `refs/`.
printf '%s\n' HEAD | git pack-objects --revs --stdout > head.pack
git pack-objects --all --stdout </dev/null > all-refs.packQuick check
What does `--all` imply?
Only unpacked objects
`--unpacked` also implies `--revs`, but limits the resulting object set to objects that are not already packed. This is useful when constructing an incremental pack from a repository that already has packfiles.
printf '%s\n' HEAD | git pack-objects --revs --unpacked --stdout > newly-unpacked.packQuick check
What does `--unpacked` restrict?
Incremental and local packing boundaries
`--incremental` ignores objects already in a pack. `--local` ignores objects borrowed from an alternate object store. These options address which existing object storage is eligible for the new pack; they do not mean the same thing as reachability.
printf '%s\n' HEAD | git pack-objects --revs --incremental --stdout > incremental.pack
printf '%s\n' HEAD | git pack-objects --revs --local --stdout > local-only.packQuick check
What is the important distinction?
Delta compression controls
`--window=<n>` controls how many candidate objects are considered for delta compression, while `--depth=<n>` limits the maximum delta-chain depth. `--delta-base-offset` permits offset-based delta references and can make packs smaller, at the cost of compatibility with very old Git versions. The current documentation gives defaults of window 10 and depth 50.
git rev-list --objects --all | git pack-objects --stdout --window=5 --depth=10 --delta-base-offset > tuned.packQuick check
Which option limits maximum delta-chain depth?
Reuse and output controls
`--no-reuse-delta` tells Git to compute deltas rather than reusing existing delta relationships. `--no-reuse-object` goes further and prevents reuse of existing object data; it implies `--no-reuse-delta`. `--non-empty` suppresses creation of an empty pack, while `-q` suppresses progress output and `--progress` forces it.
git rev-list --objects --all | git pack-objects --stdout --no-reuse-delta > fresh-deltas.pack
git rev-list --objects --all | git pack-objects --stdout --no-reuse-object > recompressed.packQuick check
Which option implies `--no-reuse-delta`?
Annotated tags and pack completeness
`--include-tag` includes an annotated tag object when the object it refers to is otherwise included in the resulting pack. This can matter when a pack is being prepared for transfer to a native Git client.
printf '%s\n' HEAD | git pack-objects --revs --include-tag --stdout > with-tag.packThin packs and the `index-pack` boundary
A thin pack can omit common base objects and therefore is not self-contained. The official documentation restricts `--thin` to `--stdout` use and points to `git index-pack --fix-thin` for restoring the self-contained property after reception. This lesson deliberately demonstrates the boundary rather than using a thin pack as an ordinary local archive.
git rev-list --objects HEAD | git pack-objects --stdout --thin > transfer.packQuick check
Why is a thin pack special?
Do not confuse `pack-objects` with `repack`
`git pack-objects` is the low-level pack constructor. `git repack` orchestrates repository-wide pack creation and replacement, including pack cleanup policies. `git index-pack` builds an index for an existing pack, and `git show-index` reads that index. `git verify-pack` verifies an existing pack/index pair. `git pack-refs` is unrelated: it reorganizes refs rather than object packs.
Quick check
Which command is the higher-level repository repacking operation?
Current Git 2.56.0 surface versus local verification
The live Git 2.56.0 manual is broader than the Git 2.47.3 executable used for local verification. The current manual documents newer interfaces including `--stdin-packs`, `--path-walk`, and `--name-hash-version=<n>`, as well as current partial-clone and cruft-related options. They are intentionally not presented here as runnable learner commands because this environment cannot execute and verify them locally. This preserves the project rule: current official documentation defines the semantic target, while every command we teach as runnable must be locally verified.
Practice what you learned
Use the dedicated Git code-completion exercise for this lesson.
Thanks for your feedback.
Mark this learning resource complete to track your learning progress.