@@ -22,6 +22,7 @@ In this chapter you will learn:
2222- How to find the commit that introduced a bug using bisect
2323- How to automate tasks with Git hooks
2424- How garbage collection and the reflog protect and clean up orphaned commits
25+ - How packfiles compress objects for efficient storage and network transfer
2526
2627## 2. Configuration
2728
@@ -417,6 +418,109 @@ $ git branch recovered abc1234 # create a branch pointing to it
417418Once a branch points to the commit again, it is no longer orphaned and
418419will not be removed by garbage collection.
419420
421+ ## 10. Packfiles
422+
423+ When you create a commit, Git stores each new blob, tree, and commit
424+ as a separate file in ` .git/objects/ ` . These are called ** loose
425+ objects** — one file per object, individually compressed with zlib.
426+ This works well for small repositories, but as history grows, thousands
427+ of small files waste disk space and slow down operations.
428+
429+ Git solves this with ** packfiles** — a single binary file that bundles
430+ many objects together using delta compression.
431+
432+ ### Loose objects vs packfiles
433+
434+ ``` text
435+ # Loose objects — one file per object
436+ .git/objects/
437+ ├── 3b/18e512dba79e... # blob
438+ ├── 5f/a3c201af34d2... # tree
439+ ├── a1/b2c3d4e5f678... # commit
440+ └── ... # thousands more
441+ ```
442+
443+ ``` text
444+ # After packing — two files replace thousands
445+ .git/objects/pack/
446+ ├── pack-abc123.pack # all objects, delta-compressed
447+ └── pack-abc123.idx # index for fast lookup
448+ ```
449+
450+ A ` .pack ` file contains the compressed object data. The ` .idx ` file
451+ is an index that maps each object hash to its offset inside the pack,
452+ so Git can find any object without scanning the entire file.
453+
454+ ### Delta compression
455+
456+ Packfiles do not just concatenate objects — they use ** delta
457+ compression** . When two objects are similar (for example, two versions
458+ of the same file), Git stores one in full and the other as a set of
459+ differences (a delta) relative to the first. This is especially
460+ effective for files that change incrementally across commits.
461+
462+ ``` text
463+ $ git verify-pack -v .git/objects/pack/pack-abc123.idx
464+ a1b2c3d4 blob 1200 450 120
465+ f6e7d8c9 blob 80 65 570 1 a1b2c3d4
466+ ```
467+
468+ In this example, ` f6e7d8c9 ` is stored as a delta against ` a1b2c3d4 ` .
469+ Its original size is 80 bytes, but it takes only 65 bytes in the pack
470+ because Git stores just the differences.
471+
472+ ### When does packing happen?
473+
474+ Git packs objects automatically during garbage collection:
475+
476+ ``` text
477+ $ git gc # packs loose objects, removes unreachable ones
478+ $ git repack -a -d # repack all objects, delete old packs
479+ ```
480+
481+ Packing also happens automatically when:
482+
483+ - The number of loose objects exceeds ` gc.auto ` (default: 6700)
484+ - You run ` git push ` or ` git fetch ` — Git builds a packfile
485+ specifically for network transfer
486+
487+ ### Packfiles and network transfer
488+
489+ When you push or fetch, Git does not send loose objects one at a time.
490+ It builds a ** thin packfile** — a temporary pack that contains only
491+ the objects the other side is missing, delta-compressed against objects
492+ both sides already have. This makes network operations fast even for
493+ large repositories.
494+
495+ ``` text
496+ $ git push origin main
497+ Enumerating objects: 5, done.
498+ Counting objects: 100% (5/5), done.
499+ Delta compression using up to 8 threads
500+ Compressing objects: 100% (3/3), done.
501+ Writing objects: 100% (3/3), 320 bytes | 320.00 KiB/s, done.
502+ Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
503+ ```
504+
505+ The "Delta compression" and "Compressing objects" lines show Git
506+ building the packfile for transfer.
507+
508+ ### Inspecting packfiles
509+
510+ ``` text
511+ # List all packs
512+ $ ls .git/objects/pack/
513+
514+ # Show pack contents with sizes and deltas
515+ $ git verify-pack -v .git/objects/pack/pack-abc123.idx
516+
517+ # Count loose vs packed objects
518+ $ git count-objects -v
519+ count: 12 # loose objects
520+ packs: 1 # number of packfiles
521+ size-pack: 4820 # total packed size in KiB
522+ ```
523+
420524## Exercises
421525
422526All exercises use the ` concepts-lab ` repository from previous chapters.
0 commit comments