Create a Safe Git Repository Diagnostic Archive

Someone asks for diagnostics on a misbehaving repository, and git diagnose builds a sensible first attachment without you zipping anything by hand. It produces an archive describing the repository's layout, object counts, packfiles, Git build and available disk space. The normal mode reports repository shape without copying the repository contents at all, which is exactly what makes it the safe first thing to send.

Allow about ten minutes, including a quick look inside the archive. You need Git 2.43.0 or a compatible release, a readable working tree, and a destination with enough free space. The examples below were run with the Debian package's Git 2.43.0. None of it needs sudo: this command reads repository metadata and writes a zip wherever you point it.

1. Check the installed command

Run these ordinary, read-only checks from the repository you want to diagnose:

$ git --version
git version 2.43.0
$ git diagnose --help
usage: git diagnose [(-o | --output-directory) <path>] [(-s | --suffix) <format>]
                    [--mode=<mode>]

The command is a Git subcommand, so it has to run inside a repository. If you are unsure where you are, run git rev-parse --show-toplevel, and change to the correct checkout if that fails. A bare repository has a different layout, so confirm the installed command accepts it before wiring the archive into an automated report.

Checkpoint: the version output identifies the behaviour you are about to rely on, and git diagnose --help shows only the three controls used here: destination, filename suffix and diagnostic mode.

2. Choose a private output directory

Create a directory outside the checkout, then run the default statistics mode. Pick a path that suits your host; the example uses a directory under your home directory and a timestamp suffix:

$ mkdir -p "$HOME/git-diagnostics"
$ git diagnose \
    --output-directory "$HOME/git-diagnostics" \
    --suffix='%Y%m%d-%H%M%S'
Collecting diagnostic info
...
Diagnostics complete.
All of the gathered info is captured in '.../git-diagnostics-20260924-020701.zip'

The output directory has to exist already. The suffix is a strftime(3) format, evaluated in local time. Git names the file git-diagnostics- followed by the formatted suffix and .zip. Skip --output-directory and the archive lands in the current directory instead; skip --suffix and Git falls back to its default timestamp naming.

Tip: do not put the archive inside the repository unless you have a reason to. It becomes an untracked file, and a later git add . could sweep it in by accident. If you use a shared directory, set its permissions and access policy before running the command: the archive itself is not encrypted.

3. Understand what stats mode collects

The default is equivalent to --mode=stats. It records the Git build options, repository root, available filesystem space, packfile names and sizes, and loose-object totals, broken down by .git/objects subdirectory. On the installed Git 2.43.0, a small test repository produced an archive containing diagnostics.log, packs-local.txt and objects-local.txt.

Read the archive before sharing it:

$ archive=$(find "$HOME/git-diagnostics" -maxdepth 1 -type f -name 'git-diagnostics-*.zip' -printf '%T@ %p\n' | sort -n | tail -1 | cut -d' ' -f2-)
$ test -n "$archive" && unzip -l "$archive"
Archive:  .../git-diagnostics-20260924-020701.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
       ...  ...       ...     diagnostics.log
       ...  ...       ...     packs-local.txt
       ...  ...       ...     objects-local.txt

The numbers, timestamp and available-space text will vary. What matters is that the command reported completion, the archive exists, and its listing holds diagnostic files rather than something unexpected.

4. Decide whether all mode is justified

Warning: use --mode=all only when the investigation genuinely needs repository data. It includes stats mode and also copies .git, .git/hooks, .git/info, .git/logs and .git/objects/info into the archive. Those copies can make it possible to reconstruct the full contents of the diagnosed repository, so treat the result as sensitive source data, not a routine log bundle.

Make the decision explicit and use a distinct suffix:

$ git diagnose \
    --output-directory "$HOME/git-diagnostics" \
    --suffix='%Y%m%d-%H%M%S-all' \
    --mode=all
Collecting diagnostic info
...
Diagnostics complete.

Before sending this archive, check its ownership, permissions and contents. Look for private hooks, reflogs, configuration fragments and object data. Never upload it to a ticket or mailing list just because somebody asked for "diagnostics": confirm the recipient and the disclosure boundary first. There is no Git option that strips sensitive material out of an archive after the fact. Delete an unshared archive only once you have checked no investigation still needs it, using your normal file-management process.

Common traps

Done means