Build CoreOrdered learning track

fsck, Lost Found, and Dangling Objects

Learn Git In Action - Part 029

Deep dive tentang git fsck, lost-found, dangling object, unreachable object, object recovery, dan repository integrity check untuk incident recovery.

12 min read2272 words
PrevNext
Lesson 29126 lesson track24–68 Build Core
#git#version-control#recovery#forensics+2 more

Part 029 — fsck, Lost Found, and Dangling Objects

Target: setelah bagian ini, kamu tidak lagi melihat dangling commit, unreachable blob, atau .git/lost-found sebagai pesan misterius. Kamu akan memahami object reachability, kapan object dianggap aman dipulihkan, kapan harus dibiarkan, dan bagaimana menjalankan recovery tanpa memperparah kerusakan.

Pada part sebelumnya kita sudah memakai reflog sebagai mesin waktu lokal. Reflog membantu ketika kamu tahu ref mana yang pernah bergerak. Tetapi ada kelas masalah yang lebih rendah levelnya:

  • branch sudah dihapus dan reflog-nya juga sudah expired;
  • commit dibuat dalam detached HEAD lalu tidak pernah diberi nama;
  • stash di-drop tetapi object-nya belum dipruning;
  • rebase/merge/cherry-pick gagal dan meninggalkan object sementara;
  • repository dicurigai corrupt;
  • object ada, tetapi tidak lagi reachable dari branch/tag manapun;
  • file pernah masuk object database tetapi tidak jelas berasal dari commit mana.

Di titik ini, kamu perlu melihat Git bukan sebagai workflow tool, tapi sebagai object database dengan graph reachability.

Dokumentasi resmi git fsck mendeskripsikan command ini untuk memverifikasi konektivitas dan validitas object di database Git. Opsi --lost-found dapat menulis dangling object ke .git/lost-found/commit/ atau .git/lost-found/other/ sesuai tipenya. Untuk blob, isi blob ditulis sebagai isi file, bukan hanya nama object. Referensi utama: https://git-scm.com/docs/git-fsck.


1. Mental Model: Object Ada Belum Tentu Reachable

Git object database berisi object:

  • blob — isi file;
  • tree — snapshot direktori;
  • commit — snapshot + parent + metadata;
  • tag — annotated tag object.

Sebuah object bisa berada di .git/objects atau packfile, tetapi Git hanya menganggap object itu bagian dari history aktif jika reachable dari salah satu root:

  • branch ref: refs/heads/main, refs/heads/feature/x;
  • remote-tracking ref: refs/remotes/origin/main;
  • tag ref: refs/tags/v1.2.0;
  • stash ref: refs/stash;
  • reflog entry yang masih hidup;
  • ref internal lain seperti notes, replace refs, worktree refs.

Diagramnya:

X1, X0, dan B9 mungkin masih ada secara fisik. Tetapi kalau tidak ada ref/reflog yang menunjuk ke mereka, mereka tidak masuk history yang bisa ditemukan lewat git log --all.

Invariant penting:

Git menyimpan object berdasarkan content identity. Tetapi survivability object bergantung pada reachability dan garbage collection policy.

Artinya:

  • object bisa ada tanpa branch;
  • commit bisa dipulihkan jika hash-nya ditemukan;
  • blob bisa ditemukan tanpa path asal;
  • dangling object belum tentu bug;
  • unreachable object belum tentu data yang harus dipulihkan;
  • git gc --prune bisa menghapus object unreachable yang sudah melewati expiry.

2. Vocabulary: Dangling vs Unreachable vs Corrupt

Istilah ini sering dicampur. Di incident Git, beda istilah berarti beda tindakan.

IstilahArtiBiasanya berbahaya?Tindakan
Reachable objectBisa dicapai dari ref/reflog aktifTidakNormal
Unreachable objectTidak reachable dari root yang diperiksaBelum tentuAudit dulu
Dangling objectObject yang tidak direferensikan oleh object lain yang reachable/relevanBelum tentuBisa kandidat recovery
Missing objectAda object yang direferensikan tetapi object-nya tidak adaYaPerlu restore/fetch/backup
Corrupt objectObject ada tetapi gagal checksum/formatYaPerlu investigasi storage/backup
Broken linkCommit/tree/tag menunjuk ke object hilangYaRepository integrity failure

Analogi database:

  • unreachable mirip row yatim yang tidak lagi diakses dari root query;
  • missing mirip foreign key menunjuk ke row yang tidak ada;
  • corrupt mirip page storage rusak;
  • dangling commit mirip transaction record yang belum masuk index publik.

3. Apa yang Sebenarnya Dilakukan git fsck

git fsck memeriksa object database dan konektivitas graph.

Command dasar:

git fsck

Versi lebih verbose:

git fsck --full --name-objects

Dengan dangling object:

git fsck --full --dangling

Dengan unreachable object:

git fsck --full --unreachable

Dengan lost-found output:

git fsck --full --lost-found

Perbedaan penting:

  • --dangling menampilkan object yang tidak dipakai object lain;
  • --unreachable lebih luas: semua object yang tidak reachable dari root;
  • --lost-found menulis sebagian object ke .git/lost-found untuk inspeksi manual;
  • --name-objects membantu menunjukkan jalur reachability untuk object yang reachable.

Jangan mulai dari git gc. Mulailah dari fsck, reflog, dan backup. Garbage collection adalah langkah pembersihan, bukan langkah investigasi pertama.


4. Repository Integrity Check Playbook

Gunakan playbook ini ketika repository dicurigai rusak, history hilang, atau object aneh muncul.

4.1 Freeze dulu

Sebelum investigasi:

# Jangan lakukan ini dulu:
# git gc
# git prune
# git repack -ad
# git reflog expire --expire=now --all

Buat copy mentah repository:

cd ..
cp -a project project.git-investigation-copy

Atau untuk repo besar:

rsync -a --delete project/ project.git-investigation-copy/

Kenapa? Karena beberapa command recovery bisa mengubah index, refs, reflog, atau working tree. Copy membuat eksperimen aman.

4.2 Snapshot state sekarang

cd project

mkdir -p ../git-incident-notes

git status --porcelain=v2 --branch > ../git-incident-notes/status.txt
git branch -avv > ../git-incident-notes/branches.txt
git tag -n99 > ../git-incident-notes/tags.txt
git reflog --date=iso --all > ../git-incident-notes/reflog-all.txt
git fsck --full --no-progress > ../git-incident-notes/fsck.txt 2>&1

Kalau ada remote:

git remote -v > ../git-incident-notes/remotes.txt
git ls-remote --heads --tags origin > ../git-incident-notes/ls-remote-origin.txt

4.3 Jalankan fsck varian recovery

git fsck --full --dangling --no-progress > ../git-incident-notes/dangling.txt 2>&1
git fsck --full --unreachable --no-progress > ../git-incident-notes/unreachable.txt 2>&1
git fsck --full --lost-found --no-progress > ../git-incident-notes/lost-found.txt 2>&1

Sekarang inspeksi .git/lost-found:

find .git/lost-found -type f -maxdepth 3 -print

5. Cara Membaca Output git fsck

Contoh output:

dangling commit 7a9c2b3f...
dangling blob 8e1d4a0c...
unreachable tree 19b2a9d...
missing blob 4f013c...
broken link from tree 8ab... to blob 4f013c...

Interpretasi:

5.1 dangling commit

Biasanya kandidat recovery terbaik.

Inspeksi:

git show --stat --decorate --summary 7a9c2b3f
git log --oneline --decorate --graph 7a9c2b3f --
git show --name-status 7a9c2b3f

Jika commit valid dan berisi kerja yang ingin diselamatkan:

git branch recovered/incident-2026-07-07 7a9c2b3f

Atau buat tag sementara:

git tag recovery/7a9c2b3f 7a9c2b3f

Prinsip: jangan langsung merge. Pertama beri nama object dengan branch/tag agar tidak hilang, lalu review.

5.2 dangling blob

Blob tidak punya path metadata. Kamu hanya punya isi file.

Inspeksi tipe:

git cat-file -t 8e1d4a0c

Lihat isi:

git cat-file -p 8e1d4a0c | sed -n '1,120p'

Simpan ke file investigasi:

mkdir -p ../git-recovered-blobs
git cat-file -p 8e1d4a0c > ../git-recovered-blobs/8e1d4a0c.blob

Cari kemungkinan path asal dari content:

# Jika content punya class/function name unik
rg "UniqueClassName|unique_function|specific_config_key" .

# Atau cek apakah blob ini pernah ada di history reachable
for c in $(git rev-list --all); do
  git ls-tree -r "$c" | grep 8e1d4a0c && echo "found in $c"
done

Untuk repo besar, loop semua commit mahal. Batasi range:

git rev-list --since='30 days ago' --all |
while read c; do
  git ls-tree -r "$c" | grep 8e1d4a0c && echo "found in $c"
done

5.3 unreachable tree

Tree sendirian sulit dipakai tanpa commit. Tetapi bisa diinspeksi:

git ls-tree -r 19b2a9d

Buat archive dari tree:

git archive 19b2a9d | tar -tvf -
git archive 19b2a9d | tar -xf - -C ../recovered-tree

5.4 missing blob atau broken link

Ini serius. Ada object reachable yang menunjuk ke object yang tidak ada.

Kemungkinan penyebab:

  • clone/fetch tidak lengkap;
  • disk corruption;
  • file di .git/objects terhapus manual;
  • packfile rusak;
  • interrupted filesystem operation;
  • bug storage layer;
  • object ada di alternate/promisor remote tapi tidak bisa diambil.

Tindakan:

# Coba fetch ulang object dari remote
git fetch --all --prune --tags

git fsck --full

Jika masih missing, bandingkan dengan clone baru:

cd ..
git clone <url> clean-clone
cd clean-clone
git fsck --full

Kalau clean clone sehat, repo lokal rusak. Kalau clean clone juga rusak, remote/source of truth bermasalah.


6. Recovery Dangling Commit: Jalur Aman

Misal git fsck memberi:

dangling commit a1b2c3d4e5f6

Jangan langsung reset --hard ke commit itu. Lakukan ini:

# 1. Inspect object type
git cat-file -t a1b2c3d4e5f6

# 2. Inspect metadata
git show --no-patch --pretty=fuller a1b2c3d4e5f6

# 3. Inspect patch
git show --stat a1b2c3d4e5f6
git show --name-status a1b2c3d4e5f6

# 4. Name it safely
git branch recovered/a1b2c3d4 a1b2c3d4e5f6

# 5. Compare with current branch
git log --oneline --graph --decorate --boundary main...recovered/a1b2c3d4
git diff --stat main...recovered/a1b2c3d4

Baru setelah itu pilih strategi:

KondisiStrategi
Commit memang kerja yang hilangmerge/cherry-pick ke branch kerja
Commit adalah hasil rebase lamagunakan range-diff sebelum apply
Commit berisi secretjangan revive; lakukan secret response
Commit berisi binary besarpertimbangkan artifact boundary
Commit hanya temporary WIPtag/branch sementara lalu review

6.1 Membuat branch recovery

git switch -c recovered/lost-work a1b2c3d4e5f6

Atau tetap di branch sekarang:

git branch recovered/lost-work a1b2c3d4e5f6

6.2 Mengambil patch tanpa memindahkan branch

git cherry-pick a1b2c3d4e5f6

Atau hanya file tertentu:

git restore --source=a1b2c3d4e5f6 -- path/to/file

6.3 Membandingkan dengan patch series lain

git range-diff old-base..old-tip main..recovered/lost-work

Ini berguna ketika dangling commit berasal dari rebase/amend lama.


7. Recovery Setelah Branch Dihapus dan Reflog Minim

Skenario:

git branch -D feature/payment-rule-engine

Lalu reflog branch sudah tidak ada atau sulit dicari. Jalur recovery:

git fsck --full --dangling --no-progress |
  awk '/dangling commit/ {print $3}' |
  while read c; do
    echo "--- $c"
    git show --no-patch --pretty='%h %ci %an %s' "$c"
  done

Urutkan kandidat berdasarkan tanggal:

git fsck --full --dangling --no-progress |
awk '/dangling commit/ {print $3}' |
while read c; do
  git show --no-patch --pretty='%ci %h %s' "$c"
done | sort

Jika ada banyak commit, lihat graph dari setiap kandidat:

git fsck --full --dangling --no-progress |
awk '/dangling commit/ {print $3}' |
while read c; do
  echo "===== $c ====="
  git log --oneline --decorate --max-count=10 "$c"
done

Setelah ketemu tip branch lama:

git branch recovered/payment-rule-engine <tip-sha>

8. Recovery Blob: Ketika File Hilang Tapi Commit Tidak Ditemukan

Dangling blob sering berasal dari:

  • git add lalu git reset sebelum commit;
  • conflict resolution sementara;
  • stash/drop;
  • merge/rebase temporary state;
  • file pernah masuk index tapi tidak pernah committed.

Cari semua dangling blob:

git fsck --full --dangling --no-progress |
awk '/dangling blob/ {print $3}' > /tmp/dangling-blobs.txt

Preview ukuran dan tipe:

while read b; do
  size=$(git cat-file -s "$b")
  echo "$size $b"
done < /tmp/dangling-blobs.txt | sort -n

Cari text yang relevan:

mkdir -p ../blob-preview
while read b; do
  git cat-file -p "$b" > "../blob-preview/$b"
done < /tmp/dangling-blobs.txt

rg "RegulatoryCase|EscalationPolicy|enforcement|TODO|secret|password" ../blob-preview

Kalau menemukan blob penting:

cp ../blob-preview/<blob-sha> path/to/recovered-file.ext
git add path/to/recovered-file.ext
git commit -m "Recover lost work from dangling blob"

Keterbatasan: blob tidak menyimpan nama file. Nama file harus direkonstruksi dari content, konteks, atau memory developer.


9. .git/lost-found: Apa, Kapan, dan Bagaimana Memakainya

git fsck --lost-found membuat direktori seperti:

.git/lost-found/
  commit/
    <sha>
  other/
    <sha>

Untuk commit, biasanya file berisi hash atau representasi object yang bisa diinspeksi. Untuk blob, dokumentasi Git menjelaskan bahwa isi blob ditulis ke file.

Workflow:

git fsck --lost-found
find .git/lost-found -type f -print

Inspeksi commit lost-found:

for f in .git/lost-found/commit/*; do
  sha=$(basename "$f")
  echo "===== $sha ====="
  git show --no-patch --pretty=fuller "$sha"
done

Inspeksi other/blob:

file .git/lost-found/other/*
rg "keyword" .git/lost-found/other

Jangan commit .git/lost-found. Itu metadata repository lokal, bukan bagian working tree normal.


10. Object Corruption: Respons yang Benar

Jika fsck menunjukkan corrupt object:

error: inflate: data stream error
error: unable to unpack header of .git/objects/ab/cdef...
error: abcdef...: object corrupt or missing

Jangan melakukan operasi yang menulis ulang banyak object dulu.

Urutan respons:

  1. copy repository;
  2. cek disk/storage health;
  3. fetch ulang dari remote;
  4. bandingkan dengan clone sehat;
  5. restore object dari backup atau alternate clone;
  6. baru lakukan cleanup.

10.1 Coba ambil dari remote

git fetch --all --prune --tags
git fsck --full

10.2 Ambil object dari clone sehat

Misal clone sehat ada di ../clean-clone.

Cari object path:

sha=abcdef1234567890...
dir=${sha:0:2}
file=${sha:2}

ls ../clean-clone/.git/objects/$dir/$file

Kalau object loose tersedia:

mkdir -p .git/objects/$dir
cp ../clean-clone/.git/objects/$dir/$file .git/objects/$dir/$file
git fsck --full

Jika object ada dalam packfile, cara paling aman biasanya fetch ulang dari remote atau reclone. Manual extraction dari packfile memungkinkan, tetapi untuk incident production, clone ulang sering lebih murah dan lebih aman.


11. git prune, git gc, dan Risiko Menghapus Bukti

git prune menghapus object unreachable dari object database. Biasanya tidak dipanggil langsung; git gc bisa menjalankan pruning berdasarkan expiry policy.

Untuk melihat apa yang akan dipruning:

git prune --dry-run --verbose

Untuk melihat object unreachable dengan tanggal:

git fsck --unreachable --no-progress

Jangan jalankan ini saat recovery belum selesai:

git reflog expire --expire=now --all
git gc --prune=now --aggressive

Kenapa? Karena reflog bisa menjadi akar reachability sementara. Jika kamu expire reflog dan prune sekarang, commit yang tadinya bisa dipulihkan bisa benar-benar hilang.

Decision rule:


12. Dangling Object Bukan Selalu Masalah

Banyak dangling object normal muncul setelah:

  • amend;
  • rebase;
  • reset;
  • failed merge;
  • stash drop;
  • commit sementara;
  • fetch/pull interrupted;
  • garbage collection belum berjalan.

Contoh:

git commit -m "WIP"
git commit --amend -m "Better message"
git fsck --dangling

Commit lama hasil sebelum amend bisa menjadi dangling. Ini normal selama kamu memang tidak butuh commit lama.

Jangan membuat policy “repository harus tidak punya dangling object sama sekali” di machine developer. Itu akan menghasilkan noise dan mendorong cleanup berbahaya.

Policy yang lebih tepat:

ContextDangling object acceptable?Catatan
Local developer repoYaNormal setelah rewrite lokal
CI ephemeral cloneBiasanya tidak relevanClone dibuang setelah job
Release mirrorPerlu lebih ketatFokus missing/corrupt, bukan semua dangling
Bare central repoMonitor, tapi jangan panikInvestigasi jika ada symptom
Regulated archivePerlu documented retentionJangan prune tanpa retention policy

13. Forensic Commands yang Sering Dipakai

13.1 Lihat semua refs

git for-each-ref --format='%(refname) %(objectname) %(committerdate:iso8601) %(subject)'

13.2 Lihat object type dan size

git cat-file -t <sha>
git cat-file -s <sha>
git cat-file -p <sha>

13.3 Batch inspect object

git fsck --dangling --no-progress |
awk '{print $3}' |
git cat-file --batch-check='%(objectname) %(objecttype) %(objectsize)'

13.4 Cari commit yang mengandung path

git log --all -- path/to/file

13.5 Cari commit berdasarkan text change

git log --all -S 'specificFunctionName' -- path/to/maybe-file

13.6 Cari object besar

git rev-list --objects --all |
git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' |
awk '$1 == "blob" {print $3, $2, $4}' |
sort -n |
tail -50

13.7 Verifikasi packfile

git verify-pack -v .git/objects/pack/*.idx | sort -k3 -n | tail -20

14. Recovery Flow: Lost Work Setelah reset --hard

Skenario:

git reset --hard HEAD~5

Jika reflog masih ada, gunakan Part 028. Tetapi kalau ingin cross-check object layer:

git reflog --date=iso

git fsck --full --dangling --no-progress |
awk '/dangling commit/ {print $3}' |
while read c; do
  git show --no-patch --pretty='%h %ci %s' "$c"
done

Jika commit tip lama ditemukan:

git branch recovered/pre-reset <sha>
git log --oneline --graph --decorate recovered/pre-reset --max-count=20

Kemudian:

# Pulihkan branch sepenuhnya, jika memang itu intended
git switch main
git reset --hard recovered/pre-reset

# Atau ambil commit tertentu saja
git cherry-pick <sha1> <sha2>

Untuk shared branch, jangan langsung push hasil reset. Gunakan revert atau PR recovery.


15. Recovery Flow: Stash Hilang

Stash adalah object commit yang direferensikan oleh refs/stash. Jika stash di-drop, commit stash mungkin masih dangling sampai dipruning.

Cari stash commit candidate:

git fsck --full --dangling --no-progress |
awk '/dangling commit/ {print $3}' |
while read c; do
  msg=$(git show --no-patch --pretty='%s' "$c")
  case "$msg" in
    WIP*|On\ *) echo "$c $msg" ;;
  esac
done

Inspeksi:

git show --stat <stash-like-sha>
git log --graph --oneline --decorate <stash-like-sha> --max-count=5

Beri nama:

git branch recovered/dropped-stash <stash-like-sha>

Atau store kembali ke stash:

git stash store -m "recovered dropped stash" <stash-like-sha>

Kita akan bahas struktur stash lebih dalam di Part 030.


16. Integrity Checks untuk CI dan Mirror

Untuk repo source-of-truth, fsck bisa menjadi health check periodik. Tetapi jangan terlalu agresif di path developer biasa.

Contoh job audit untuk mirror:

#!/usr/bin/env bash
set -euo pipefail

repo=${1:?repo path required}
cd "$repo"

git fetch --all --prune --tags

git fsck --full --strict --no-progress > fsck-report.txt 2>&1 || {
  cat fsck-report.txt
  exit 1
}

Catatan:

  • --strict bisa melaporkan issue historis dari object lama; gunakan dengan kebijakan yang jelas;
  • untuk partial clone/promisor remote, beberapa object memang lazy-fetched; jangan samakan dengan repo penuh;
  • mirror bare repository punya karakteristik berbeda dari working clone.

17. Regulated Systems: Evidence Before Cleanup

Untuk sistem enforcement, case management, payment, identity, audit, atau platform yang butuh defensibility, Git recovery bukan hanya soal “file balik”. Kamu perlu bukti.

Checklist evidence:

[ ] Kapan incident terdeteksi?
[ ] Repository mana yang terdampak?
[ ] Ref mana yang berubah?
[ ] Commit/object mana yang hilang atau dangling?
[ ] Apakah remote source-of-truth terdampak?
[ ] Apakah release tag terdampak?
[ ] Apakah object mengandung secret/PII?
[ ] Apakah recovery dilakukan dari reflog, fsck, remote, atau backup?
[ ] Siapa yang melakukan recovery?
[ ] Command penting dicatat?
[ ] Apakah dilakukan cleanup setelah evidence disimpan?

Contoh recovery note:

# Git Recovery Note

Date: 2026-07-07
Repository: enforcement-lifecycle-platform
Symptom: feature branch deleted locally before PR creation
Detection: developer noticed missing branch after reset/rebase session
Evidence:
- fsck report: incident/fsck.txt
- reflog report: incident/reflog-all.txt
Recovered object:
- commit: a1b2c3d4
- branch created: recovered/payment-rule-engine
Decision:
- cherry-pick selected commits into new PR branch
- no force push to protected branch
Risk review:
- no secret detected in recovered commits
- CI full suite passed

18. Common Mistakes

Mistake 1: Running gc --prune=now during panic

Ini bisa menghapus object yang justru ingin kamu pulihkan.

Safer alternative:

git fsck --full --dangling
git reflog --all
cp -a repo repo-copy

Mistake 2: Treating every dangling object as corruption

Dangling object sering normal setelah rewrite. Fokus pada symptom: data hilang, missing object, corrupt object, broken link.

Mistake 3: Recovering commit without review

Dangling commit bisa berisi eksperimen lama, secret, atau state yang sengaja dibuang.

Mistake 4: Confusing blob recovery with file recovery

Blob tidak menyimpan path. Jangan mengasumsikan nama file dari hash.

Mistake 5: Force-pushing recovered branch to shared branch

Recovery lokal harus masuk lewat PR/review kecuali incident commander memutuskan emergency path.


19. Lab: Simulasi Dangling Commit

Buat repo lab:

mkdir git-fsck-lab
cd git-fsck-lab
git init

echo one > app.txt
git add app.txt
git commit -m "Initial commit"

git switch -c feature/lost

echo two >> app.txt
git add app.txt
git commit -m "Add lost work"

lost=$(git rev-parse HEAD)

git switch main
git branch -D feature/lost

Cari dangling commit:

git fsck --full --dangling --no-progress

Pulihkan:

git branch recovered/lost "$lost"
git log --oneline --graph --decorate --all

Validasi:

git show recovered/lost --stat
git diff main..recovered/lost

20. Lab: Simulasi Dangling Blob

mkdir git-blob-lab
cd git-blob-lab
git init

echo committed > file.txt
git add file.txt
git commit -m "Initial"

echo "uncommitted secret-ish draft" > draft.txt
git add draft.txt

# Reset dari index tanpa commit. Blob mungkin masih ada.
git reset HEAD draft.txt
rm draft.txt

git fsck --full --dangling --no-progress

Cari blob:

git fsck --full --dangling --no-progress |
awk '/dangling blob/ {print $3}' |
while read b; do
  echo "===== $b ====="
  git cat-file -p "$b"
done

Pulihkan manual:

git cat-file -p <blob-sha> > draft.txt

21. Operational Decision Table

SituationFirst commandSafe recoveryAvoid
Branch deletedgit reflog --all, git fsck --danglinggit branch recovered/x <sha>gc --prune=now
Commit lost after rebasegit reflog, git fsckbranch old tip, range-diffblind reset
Stash droppedgit fsck --danglinggit stash store <sha>immediate prune
Blob recoveredgit cat-file -psave content manuallyassuming original path
Missing objectgit fsck --fullfetch/reclone/backup restorerewriting history first
Corrupt packgit fsck, git verify-packfetch/reclonemanual pack surgery as first option
Secret in dangling objectsecret incident processrotate, audit, then rewrite if neededjust deleting branch

22. Mental Checklist Before Cleanup

Sebelum menjalankan cleanup destructive:

[ ] Apakah semua branch penting punya remote atau backup?
[ ] Apakah reflog sudah disimpan jika ada incident?
[ ] Apakah dangling commits sudah diaudit?
[ ] Apakah stash penting sudah dipastikan tidak hilang?
[ ] Apakah secret scan sudah dilakukan jika ada object mencurigakan?
[ ] Apakah release tag tidak terdampak?
[ ] Apakah repo copy tersedia?
[ ] Apakah tim tahu jika cleanup dilakukan di shared/bare repo?

Baru setelah aman:

git gc

Atau untuk maintenance modern:

git maintenance run

23. Summary

git fsck bukan command harian untuk semua developer, tetapi merupakan alat penting saat kamu perlu melihat kebenaran di bawah porcelain Git.

Mental model yang harus dipegang:

  1. Git object bisa ada tanpa reachable dari branch/tag.
  2. Dangling object belum tentu corruption.
  3. Missing/corrupt object jauh lebih serius daripada dangling object.
  4. Recovery yang benar dimulai dari freeze, copy, audit, lalu memberi nama object dengan branch/tag.
  5. Jangan menjalankan pruning/GC agresif sebelum recovery selesai.
  6. Blob recovery kehilangan path; commit recovery mempertahankan context jauh lebih baik.
  7. Untuk sistem regulated, evidence trail sama pentingnya dengan keberhasilan teknis.

Di part berikutnya, kita akan masuk ke stash internals: apa sebenarnya yang dibuat oleh git stash, kenapa stash bisa conflict, bagaimana apply dan pop berbeda secara risiko, dan bagaimana memulihkan stash yang hilang dengan aman.


References

Lesson Recap

You just completed lesson 29 in build core. Use the series map if you want to review the broader track, or continue directly into the next lesson while the context is still warm.

Continue The Track

Keep the momentum while the lesson is still fresh. Move backward for review or continue forward into the next concept.