GIT-PACK-REFS(1)
π git-pack-refs(1) π
okay so bestie, welcome to the git-pack-refs page β that's section 1 of the Git manual, and yes we're gonna get through it together, hand in hand, because it's actually not that deep and it's kinda iconic. π
-->
β¨ NAME β¨
git-pack-refs β packing up heads and tags so your repo stops being slow, no cap π
β¨ SYNOPSIS β¨
git pack-refs [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude <pattern>]
πΈ DESCRIPTION πΈ
So back in the day β like, traditionally β the tips of branches and tags (we call them refs collectively, iykyk) were stored one file per ref, sitting in a (sub)directory under the $GIT_DIR/refs directory. Cute in theory!! But here's the tea: lots of branch tips get updated constantly, while most tags and some branch tips literally never change. So when a repo has hundreds or thousands of tags, that one-file-per-ref situation is giving storage waste and performance pain. π
This command exists to fix that exact storage-and-performance problem by storing refs in a single file, $GIT_DIR/packed-refs. And when a ref is missing from the traditional $GIT_DIR/refs directory hierarchy, it gets looked up in this file, and used if it's found. slay. β¨
Subsequent updates to branches always create new files under the $GIT_DIR/refs directory hierarchy.
Now, the recommended practice (write this down ποΈ) for a repo with way too many refs is: pack its refs with --all once, then occasionally run git pack-refs. Why? Because tags are by definition stationary and not expected to change. Branch heads get packed with that initial pack-refs --all, but only the currently active branch heads become unpacked β and the next pack-refs (without --all) will leave them unpacked. periodt. π
π OPTIONS π
--allβ bestie listen. By default this command packs all tags and refs that are already packed, and leaves other refs alone. Why? Because branches are expected to be actively developed, and packing their tips doesn't help performance. This option makes all refs get packed too β with the exception of hidden refs, broken refs, and symbolic refs. Super useful for a repo with lots of branches of historical interest. π¦--no-pruneβ normally the command removes loose refs under the$GIT_DIR/refshierarchy after packing them. This option tells it not to. that's it, that's the whole vibe. π--autoβ pack refs as needed, depending on the current state of the ref database. The behavior depends on the ref format your repo uses and may change in the future. Here's the breakdown:- "files": loose references get packed into the
packed-refsfile based on the ratio of loose references to the size of thepacked-refsfile. The bigger thepacked-refsfile, the more loose references need to exist before we repack. - "reftable": tables are compacted so they form a geometric sequence. For two tables N and N+1, where N+1 is newer, this maintains the property that N is at least twice as big as N+1. Only tables that violate this property get compacted.
- "files": loose references get packed into the
--include <pattern>β pack refs based on aglob(7)pattern. β¨ Repetitions of this option accumulate inclusion patterns. If a ref is both included in--includeand--exclude,--excludetakes precedence (exclude is the main character here, sorry π). Using--includewill preclude all tags from being included by default. Symbolic refs and broken refs will never be packed. When used with--all, it will be a noop. Use--no-includeto clear and reset the list of patterns.--exclude <pattern>β do not pack refs matching the givenglob(7)pattern. Repetitions of this option accumulate exclusion patterns. Use--no-excludeto clear and reset the list of patterns. If a ref is already packed, including it with--excludewill not unpack it.
When used with --all, pack only loose refs which do not match any of the provided --exclude patterns.
When used with --include, refs provided to --include, minus refs that are provided to --exclude, will be packed. math! π§
π BUGS π
Older documentation written before the packed-refs mechanism was introduced may still say things like ".git/refs/heads/<branch> file exists" when what it actually means is "branch <branch> exists". so if you see that, don't come for me, it's just old lore π«Ά
π GIT π
Part of the git(1) suite.
and that's the whole page bestie, you ate that π this was Git 2.56.0, dated 2026-09-27 β catch you on the next man page, mwah ππ
π¦ where this page comes from
- arch rolling: git 2.56.0-1 Β· GPL-2.0-only
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms