# How to Recover Lost Commits with Git Fsck

Most lost commits come from three ordinary commands: `git reset, hard`, a deleted branch, and a rebase or merge that was aborted halfway through. The commit data almost never leaves the disk at the moment those commands run. Git keeps the underlying objects in its internal database and simply stops pointing at them, which means the recovery problem is usually a pointer problem, not a data loss problem. The first thing to check is the reference log (`reflog`), a private journal Git keeps of every commit your repository moved to. The second tool, and the subject of this article, is `git fsck`, a built-in integrity checker that scans the entire object database and reports every commit, file snapshot, and message that Git currently considers unreachable. This guide walks through both tools, explains the causes of lost commits from most common to rarest, and gives you a copy-paste diagnostic sequence that works on any command-line Git installation, including the ones most scientists run on Linux servers and high-performance computing clusters.

The stakes in research repos are different from ordinary software projects. A lost commit may hold an analysis script version, a figure-generating notebook, or a documented parameter change that a reviewer asks about a year later. Git was designed so that almost nothing is destroyed immediately, and knowing how to use `git fsck` turns a panicked afternoon into a five-minute fix. The Git project documents this tool in the official `git-fsck(1)` manual page, and the Pro Git book (distributed by the Git project itself) includes a dedicated chapter on undoing mistakes and recovering objects, which this article follows closely in both logic and command usage.

## Start Here: Check the Reflog Before Running Anything Else

The `reflog` (reference log) is a chronological record of where your branch tips, and your `HEAD` pointer, have pointed over time. Every commit, checkout, reset, merge, and rebase updates it. By default, Git keeps reflog entries for 90 days for entries that are still reachable from a branch, and 30 days for entries that have become unreachable. Those retention windows come from the Git configuration defaults for `gc.reflogExpire` and `gc.reflogExpireUnreachable`, described in the official `git-config(1)` documentation.

Run this first:

```bash
git reflog
```

You will see output like this:

```text
a1b2c3d HEAD@{0}: reset: moving to HEAD~3
e4f5a6b HEAD@{1}: commit: Finalize differential expression table
7g8h9ij HEAD@{2}: commit: Add batch correction step
```

Each line shows the short commit hash, a positional label such as `HEAD@{0}` for the most recent state, and a description of what changed. If the commit you lost appears here, your fastest fix is to restore a branch or your working state directly to it:

```bash
git branch recovered-work e4f5a6b
```

That command creates a new branch named `recovered-work` pointing at the lost commit without touching your current branch. You can then inspect it, merge it, or cherry-pick from it at leisure. Never use `git reset, hard` as the first recovery move, because a second careless reset is how one lost commit becomes two.

**Safety note:** any command containing `reset, hard` overwrites your working directory with the contents of the target commit. Uncommitted edits to files are destroyed and cannot be recovered by Git at all. Before running any recovery command, make a complete backup copy of the repository directory:

```bash
cp -a myproject myproject-backup
```

This one command is the single highest-value action in this entire article. It converts every remaining step from "potentially destructive" to "fully reversible."

## What git fsck Actually Does

`fsck` stands for filesystem check, and the name is borrowed from the Unix utility of the same purpose. Git's internal storage is an object database: every file snapshot (a `blob`), every directory listing (a `tree`), every commit (a `commit` object), and every tag is stored as an object identified by a cryptographic checksum called its object ID or SHA-1 hash. Commit messages reference parent commits, forming a directed graph of history. Branches and tags are just human-readable names, called `refs`, that point into this graph.

When you run `git reset, hard`, delete a branch, or have a rebase rewrite history, Git moves the refs. The old commit objects remain on disk, but nothing points to them. Git calls these `dangling` or `unreachable` objects. They sit in the object database, invisible to `git log`, until Git's garbage collection (`git gc`) removes them. Garbage collection respects a grace period. The default is two weeks for objects that became unreachable while a reflog entry still referenced them, controlled by the `gc.pruneExpire` setting in the official Git configuration documentation.

`git fsck` walks the entire object database, verifies internal integrity, and prints every object it considers dangling. The command is read-only by default. Running it does not delete, modify, or repair anything, which makes it safe to run at any time, on any repository, without a backup.

The most useful invocation for recovery is:

```bash
git fsck --full
```

The `-full` flag tells Git to inspect objects inside packfiles (the compressed bulk-storage format Git uses) as well as loose objects, giving you the complete picture. Typical output after a hard reset looks like this:

```text
Checking object directories: 100% (256/256), done.
Checking objects: 100% (1205/1205), done.
dangling commit e4f5a6b9c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6
dangling commit 7g8h9ijk (abbreviated in real output)
```

Each `dangling commit` line is a recoverable lost commit. The long hexadecimal string is the full object ID you will use to restore it.

## Why Commits Go Missing: Causes From Most to Least Common

Understanding the mechanism behind each failure mode tells you which recovery path to try first. The causes below are ordered by how often they account for lost commits in practice, based on the operations Git documents as history-rewriting in the Pro Git book and the `git-rebase(1)`, `git-reset(1)`, and `git-branch(1)` manual pages.

### Cause 1: git reset, hard

A hard reset moves the current branch pointer backward and then forces the working directory to match. Every commit that was between the old tip and the new position drops out of the branch. The commits themselves survive in the object database and appear in the reflog, so this is the easiest case to fix. The reflog entry reads `reset: moving to ...` and the commit immediately before that line is the one you want.

A subtler variant is `git reset, hard` run after an interactive rebase, where the reader loses track of which hash represents the pre-rebase state. In that situation, search the reflog for the entry labeled `rebase (finish)` or `rebase: aborting` and take the hash from the line above it.

### Cause 2: A Deleted Branch

`git branch -D experiment` deletes the branch ref and, because `-D` bypasses the safety check that `-d` performs, it works even when the commits are not merged anywhere. The commits become unreachable from any branch. The reflog for that specific branch still exists briefly, but the simpler recovery path is `git fsck`, which lists the branch tip as a dangling commit. Once you identify the tip hash, recreating the branch is one command:

```bash
git branch experiment e4f5a6b
```

Because a branch ref points to a single tip commit and the full ancestry hangs below it in the graph, restoring the tip restores the entire branch history. This is a direct consequence of how Git stores parent links inside each commit object, as described in the Pro Git chapter on Git internals.

### Cause 3: An Interrupted or Aborted Rebase, Merge, or Cherry-Pick

History-rewriting operations create temporary refs that people do not know to look for. After an aborted rebase, check `ORIG_HEAD`, a special ref Git sets before performing dangerous operations:

```bash
git log --oneline ORIG_HEAD -5
```

Also check `FETCH_HEAD`, `MERGE_HEAD`, and the reflog entries labeled `rebase`, `merge`, and `cherry-pick`. If `ORIG_HEAD` and the reflog both fail, `git fsck, full` will list the orphaned pre-rebase commits as dangling objects. Rebase in particular creates a completely new chain of commits and abandons the old chain wholesale, so a failed or wrongly aborted rebase often produces a large cluster of dangling commits at once. Recognizing that cluster is easy: the dangling commits will share a common tip, and `git log, oneline` on that tip will show your familiar commit messages.

### Cause 4: An Amended or Rebased-Away Commit

`git commit, amend` replaces the previous commit with a new one and leaves the original dangling. Interactive rebase does the same to every commit it rewrites. Authors frequently amend a commit, realize the amendment lost a file or a change, and need the original back. The reflog entry labeled `commit (amend)` records both the new and the prior state, and `git fsck` lists the original as dangling. Recovery is the same as for any dangling commit: branch from it, inspect it, and cherry-pick or merge whatever you need.

### Cause 5: Garbage Collection Pruned the Objects

If weeks have passed since the loss, or if a scheduled `git gc` ran in the meantime, the dangling objects may have passed the two-week grace period and been physically deleted. The reflog itself also expires on its 90-day and 30-day schedules. At this stage the local repository no longer holds the data, and recovery shifts from local forensics to alternative copies, covered in the section on remote and clone recovery below.

### Cause 6: Repository Corruption or an Interrupted Operation

The rarest cause is genuine corruption: a crash mid-write, a full disk, or a filesystem problem leaves the object database incomplete. `git fsck` reports this differently from dangling objects. Messages such as `missing blob`, `missing tree`, `broken link from ... to ...`, or `sha1 mismatch` indicate damaged or absent objects rather than healthy but unreachable ones. The fix in this case is not recovery from local dangling objects but replacement from an intact copy, either a remote, another clone, or a backup. The Git maintenance documentation treats a verified remote clone as the authoritative repair source for a corrupted local object database.

## The Core Troubleshooting Table

![Decision path asking if the reflog shows the commit, if fsck lists a dangling commit, and if a remote or clone has it.](/article-images/illustrations/git-fsck-recover-lost-commits-recovery-triage.webp)

This table is the center of the article. Identify your symptom in the first column, confirm the cause in the third, and apply the fix in the fourth. Every command assumes you are inside the repository directory and have made the backup copy described earlier.

| Symptom | Likely cause | How to confirm | Fix |
|--|--|--|--|
| Commits vanished after `git reset, hard` | Branch moved backward, commits dangling | `git reflog`, look for `reset: moving to` | `git branch recover <hash-from-reflog>` or `git reset, hard <hash>` |
| Whole branch gone after `git branch -D` | Branch tip now unreachable | `git fsck, full`, look for `dangling commit` | `git branch <old-branch-name> <dangling-hash>` |
| History rewritten by rebase, old commits gone | Pre-rebase chain abandoned | `git log ORIG_HEAD` then `git fsck, full` | Branch from the dangling tip, cherry-pick or merge |
| Commit content missing after `-amend` | Original commit replaced | Reflog entry `commit (amend)`, or `git fsck, full` | Branch or cherry-pick from the dangling original |
| Stash disappeared after `git stash drop` or `pop` conflict | Stash commit unreachable | `git fsck, full`, dangling commit near timestamp of drop | `git stash apply <dangling-hash>` or branch from it |
| Uncommitted file edits lost (never committed or stashed) | Edits existed only as editor temp state or in index | `git fsck, full` may show `dangling blob` | Inspect with `git show <blob-hash>`, salvage manually |
| `git log` shows errors, objects missing | Corrupt or incomplete object database | `git fsck, full` reports `missing blob` or `broken link` | Fetch or clone from remote, restore affected files |
| Reflog empty or absent, nothing dangling | Objects pruned by `git gc`, or `.git` folder copied incompletely | `git count-objects -v`, check for remote | Recover from remote, another clone, or `git bundle` |
| fsck reports `dangling tree` or `dangling blob` only | Partial operation, no commits lost | Compare `git log` against expectations | Usually harmless, inspect blobs with `git show` |

Two rows deserve extra explanation. The stash row works because a stash is internally just a commit object on the refs/stash ref, so a dropped stash reappears as a dangling commit, and you can recover it with `git stash apply <hash>` or simply `git branch stash-recovery <hash>`. The uncommitted-edits row is the honest limit of Git recovery. Git can only recover content that entered its object database at some point. Text you typed into a file but never added with `git add` and never stashed exists only in your editor, so recovery depends on editor backups and swap files, not Git.

## The Full Diagnostic Sequence for git fsck Recover Lost Commits Workflows

Follow these six steps in order. Each step either solves the problem or eliminates a cause, so by the end you will know exactly what state your repository is in.

### Step 1: Freeze the Scene and Back Up

```bash
cp -a myproject myproject-backup
```

Stop committing, rebasing, and especially running `git gc`, `git prune`, or any command with `-prune` in it. Every one of those can permanently delete the dangling objects you are about to look for. **Safety note:** this is the point of no return for the object database. If you run garbage collection with aggressive settings before recovering, the objects are gone from this copy, and you will depend entirely on remotes or backups.

### Step 2: Read the Reflog

```bash
git reflog
```

Scan for the operation that caused the loss. Useful reflog-specific views:

```bash
git reflog show HEAD
git reflog show mybranch
```

If you find the commit, recover it immediately as shown earlier and skip the rest. If the reflog is short, expired, or missing the commits, continue.

### Step 3: Run fsck With Full Coverage

```bash
git fsck --full
```

Add `-no-reflogs` to treat reflog-reachable objects as unreachable too. This is useful when you want fsck to show you objects that only the reflog is keeping alive, which helps you understand what garbage collection would remove:

```bash
git fsck --full --no-reflogs
```

Expect two categories of output. `dangling commit` lines are recoverable history. Integrity errors such as `missing` or `broken link` lines mean corruption, and you should jump to the corruption section.

### Step 4: Inspect Each Dangling Commit

Use the full hashes from the fsck output. To see what a candidate commit contains:

```bash
git show e4f5a6b9c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6
```

To see its position in history and its ancestry:

```bash
git log --oneline --graph e4f5a6b
```

To see only the changed files:

```bash
git show --stat e4f5a6b
```

Match the commit message, timestamp, and file list to the work you lost. Timestamps are especially helpful when a rebase produced many dangling commits, because the pre-rebase chain will carry its original author dates.

### Step 5: Recover Into a Branch

The non-destructive standard fix is to branch from the dangling commit:

```bash
git branch recovered e4f5a6b
```

Then compare it with your current state:

```bash
git diff main recovered
git log --oneline main..recovered
```

From there you have three standard solutions, all documented in the Pro Git chapter on undoing things:

1. Merge the recovery branch into your working branch to restore the lost history in full.
2. Cherry-pick individual commits: `git cherry-pick e4f5a6b`.
3. Move your branch pointer wholesale with `git reset, hard e4f5a6b`, which is only appropriate when you want the branch to look exactly as it did before the destructive operation.

If the dangling object is a blob rather than a commit, meaning file content that never became part of a commit, inspect it with `git show <blob-hash>` and copy what you need into a file by hand. Blobs carry no filename, message, or date, so identification is manual.

### Step 6: Verify and Write Down the Hash

After recovery, confirm the history is intact:

```bash
git log --oneline --graph -20
git fsck --full
```

Record the recovered hash in your [lab notebook](/knowledge/molecular-biology/lab-notebook) or project log. In research settings, the provenance of a recovery (which commit was restored, when, and why the loss happened) is often as valuable as the code itself when methods must be reproduced later.

## Using fsck Options That Matter for Recovery

The `git-fsck(1)` manual page defines several options that change what the tool reports, and knowing them prevents the most common "fsck found nothing" disappointment.

- `-full` inspects packfiles as well as loose objects. Without it, fsck can miss objects stored in packs.
- `-dangling` is implied by default, printing unreachable objects. `-no-dangling` suppresses them when you only want an integrity check.
- `-unreachable` prints objects unreachable from any ref, a broader class that includes objects the dangling report may summarize differently.
- `-lost-found` writes dangling objects into `.git/lost-found/commit/` and `.git/lost-found/other/` as a safety export, one file per object, so they survive a subsequent garbage collection long enough for you to examine them.
- `-strict` enables stricter checks, catching object corruption that the default checks accept, at the cost of occasionally flagging objects that are technically valid but unusual.
- `-connectivity-only` skips blob content checks and verifies only reachability, which is faster on very large repositories such as genome-scale data repos.

A practical pattern for a large analysis repository, where a full fsck can take minutes, is to run `git fsck, full, connectivity-only` first for speed, then a complete `git fsck, full` overnight or when corruption is suspected.

## How to Fix Lost Commits When Reflog and fsck Come Up Empty

Sometimes both tools find nothing. The objects were pruned, the reflog expired, or the loss happened in a fresh clone. Three sources of recovery remain, in order of preference.

### Recover From a Remote

If you ever pushed the branch, the commits exist on the remote server. GitHub, GitLab, and institutional Git servers keep objects that are no longer referenced by any branch for some period, and your own clone history is not the only copy. Fetch everything and search:

```bash
git fetch origin
git log --oneline --all
git log --all --grep="differential expression"
```

The `-all` flag includes all refs, including remote-tracking branches. Searching by commit message text with `-grep` finds commits whose hashes you never recorded. GitHub additionally exposes ref events through its audit and activity features for organizations, and its support team can sometimes identify recently pushed commit hashes for repository administrators, though you should not rely on that as a designed recovery path.

### Recover From Another Clone or Workstation

Any clone that ever fetched the lost commits holds the objects. A collaborator's clone, a continuous integration server workspace, a cluster scratch directory, or the clone on your laptop all qualify. The minimal transfer is a bundle:

```bash
git bundle create recovered.bundle e4f5a6b
```

produced on the machine that has the commit, then fetched on the machine that lost it:

```bash
git fetch /path/to/recovered.bundle e4f5a6b:recovered
```

This is a routine technique for moving work between an HPC login node and a workstation, and it doubles as an emergency recovery channel.

### Check Dangling Blobs for Salvageable Content

Even when commits are gone, blobs sometimes survive because a later garbage collection had not reached them. `git fsck, unreachable` lists them, and `git show <hash>` prints the content. Searching the output of `git show` across many blobs is tedious, so grep for a distinctive string from the lost file, such as a gene symbol, a figure caption, or a unique parameter name:

```bash
for h in $(git fsck --unreachable 2>/dev/null | awk '/blob/ {print $3}'); do
  if git show "$h" 2>/dev/null | grep -q "DESeq2"; then echo "$h"; fi
done
```

This loop is worth the awkwardness when the alternative is retyping an analysis script from memory.

## Recovering From Corruption Reported by fsck

When fsck reports `missing blob`, `broken link`, or `sha1 mismatch` instead of dangling objects, the object database is damaged. The safe sequence is:

1. Back up the entire repository directory immediately, including `.git`, so that partial data is preserved for expert recovery.
2. Fetch the missing objects from a healthy remote: `git fetch origin`. Git transfers only objects the local database lacks.
3. Re-verify with `git fsck, full`.
4. If specific files are still broken and the remote has them, restore them by checking out those paths from the remote-tracking branch: `git checkout origin/main, path/to/file`.
5. As a last resort, clone fresh from the remote and reapply any local-only work that you salvaged from the backup or from dangling blobs.

**Safety note:** do not run `git gc`, `git repack`, or `git prune` on a repository with unresolved fsck integrity errors. Repacking a damaged database can consolidate corruption into the new packfiles and destroy recoverable fragments.

## Common Mistakes and Limitations

These are the errors that turn a recoverable situation into a permanent one, plus the honest limits of the technique.

- Running `git gc`, `git prune`, or `git reflog expire` before recovery. The command `git reflog expire, expire=now, all` combined with `git gc, prune=now` deletes every dangling object and every reflog entry immediately. Save it for deliberate, verified cleanup only, never during an emergency.
- Treating fsck output as a list of things to delete. Every `dangling commit` line is potential recovery material. Newcomers see the word dangling, assume it means broken, and run aggressive cleanup. Dangling means unreachable, not damaged.
- Using `git reset, hard` to "fix" the loss. A second hard reset moves the reflog forward past the entry you need and overwrites your working tree. Branch-and-inspect first, reset only when you have verified the target.
- Expecting fsck to recover uncommitted, unstaged edits. Git can only recover content that entered the object database through a commit, an add, or a stash. Everything else lives in editor backups, not Git.
- Copying a repository directory without the `.git` folder, or with a partially synced `.git` folder. This is common when people move project directories with a file manager mid-sync. The resulting folder looks normal but has an incomplete object database, which is why `cp -a` (archive mode, recursive, preserving everything) is the backup command of choice.
- Assuming infinite local retention. The 90-day and 30-day reflog expiries and the two-week unreachable-object grace period are defaults, not guarantees. A scheduled cron job running `git gc` on a cluster home directory can shorten all of them without your knowledge. Check your institutional cron and HPC maintenance jobs.
- Ignoring corruption errors. A repository that fsck reports as corrupted will pass daily work until the moment it matters. Fix it from a remote the same day you see the error.

The limitation to accept is that Git recovery depends on data having entered Git's storage at some point. Recovery likelihood therefore decays with time since the loss, and no local technique can beat a recent push to a remote.

## Prevention Practices for Research Code

For scientists, the cheapest recovery is the one you never need. These practices reflect the recommendations that the Software Carpentry lesson on version control (a widely used, community-maintained curriculum for researchers) and GitHub's own documentation promote for research workflows.

- Push to a remote at the end of every working session. A pushed commit is nearly immune to every failure mode in this article. GitHub, GitLab, and institutional GitLab instances are standard homes for research repositories, and pushing daily converts catastrophic local losses into trivial re-clones.
- Commit small and often, with messages that state what changed and why. A message like `Change FDR threshold 0.05 to 0.01 after reviewer comment` is both documentation and a search key for `git log, grep` during recovery.
- Never run `git gc, prune=now` or `git reflog expire, expire=now` unless you have just verified there is nothing dangling you care about, with `git fsck, full` as the verification.
- Extend retention if you want a wider safety net by setting `gc.reflogExpire` and `gc.pruneExpire` in your global Git configuration, as documented in the `git-config(1)` manual page.
- Teach your lab the branch-and-inspect rule: any destructive-looking situation is handled by creating a branch at the current state first, then deciding. Branches are free, and a branch created in panic costs nothing and prevents almost everything.
- Pair Git with a scheduled backup of the remote, not just the local machine. Research [data management](/blog/guides/data-management-basics-principles-processes-and-best-practices) plans increasingly require this, and a remote backup protects against the one failure Git cannot fix, which is loss of every copy.

## Frequently Asked Questions

### Is git fsck safe to run on my repository?

Yes. By default `git fsck` is a read-only diagnostic that verifies object integrity and reports dangling objects without modifying or deleting anything. The only risk comes from what you do after reading its output, so always branch from a dangling commit rather than pruning it.

### What is a dangling commit in git?

A dangling commit is a commit object that exists in the object database but is not reachable from any branch, tag, or other ref, usually because a reset, rebase, or branch deletion moved the pointers away from it. It remains on disk until garbage collection removes it after the grace period.

### How is git fsck different from git reflog for recovery?

The reflog is a journal of where your branch tips and HEAD have pointed, and it is the fastest recovery tool when the loss happened locally and recently. `git fsck` scans the object database itself and finds unreachable objects even when reflog entries are missing, expired, or were never created, such as in a fresh clone or after a deleted branch's dedicated reflog is gone.

### How long do lost commits survive before git deletes them?

![Timeline of Git retention defaults: reflog entries at 90 and 30 days, unreachable objects pruned after two weeks, then recovery only from remotes.](/article-images/illustrations/git-fsck-recover-lost-commits-retention-windows.webp)

Reflog entries expire after 90 days for reachable states and 30 days for unreachable states by default, and garbage collection prunes unreachable objects after a default grace period of two weeks. These are configurable defaults from the Git project, so your institution or cron jobs may use different values.

### Can git fsck recover uncommitted changes to files?

Only if the content entered Git's object database, for example through `git add`, `git stash`, or a commit that was later discarded. In those cases fsck may report dangling blobs or commits holding the content. Text you never added or stashed exists only in your editor and is outside Git's reach.

### Can I recover a deleted branch with git fsck?

Yes, in most cases. The deleted branch's tip commit shows up as a dangling commit in `git fsck, full` output, and `git branch <name> <hash>` restores the branch together with its entire history, because every commit links to its parents.

### What should I do if git fsck reports missing or corrupt objects?

Back up the repository directory immediately, then fetch from a healthy remote so Git can download the missing objects, and re-run `git fsck, full` to verify. Do not run garbage collection or repacking on a corrupted repository until the integrity errors are resolved.

### Does GitHub keep commits that are no longer on any branch?

Commits you pushed remain on GitHub's servers as objects, and they can often be found by fetching and searching all refs, or by asking repository administrators to check activity records. Treat this as a recovery avenue rather than a guarantee, and rely on regular pushing and remote backups as the actual safeguard.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "Is git fsck safe to run on my repository?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Yes. By default git fsck is a read-only diagnostic that verifies object integrity and reports dangling objects without modifying or deleting anything. The only risk comes from what you do after reading its output, so always branch from a dangling commit rather than pruning it."
      }
    },
    {
      "@type": "Question",
      "name": "What is a dangling commit in git?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "A dangling commit is a commit object that exists in the object database but is not reachable from any branch, tag, or other ref, usually because a reset, rebase, or branch deletion moved the pointers away from it. It remains on disk until garbage collection removes it after the grace period."
      }
    },
    {
      "@type": "Question",
      "name": "How is git fsck different from git reflog for recovery?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "The reflog is a journal of where your branch tips and HEAD have pointed, and it is the fastest recovery tool when the loss happened locally and recently. git fsck scans the object database itself and finds unreachable objects even when reflog entries are missing, expired, or were never created, such as in a fresh clone or after a deleted branch's dedicated reflog is gone."
      }
    },
    {
      "@type": "Question",
      "name": "How long do lost commits survive before git deletes them?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Reflog entries expire after 90 days for reachable states and 30 days for unreachable states by default, and garbage collection prunes unreachable objects after a default grace period of two weeks. These are configurable defaults from the Git project, so your institution or cron jobs may use different values."
      }
    },
    {
      "@type": "Question",
      "name": "Can git fsck recover uncommitted changes to files?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Only if the content entered Git's object database, for example through git add, git stash, or a commit that was later discarded. In those cases fsck may report dangling blobs or commits holding the content. Text you never added or stashed exists only in your editor and is outside Git's reach."
      }
    },
    {
      "@type": "Question",
      "name": "Can I recover a deleted branch with git fsck?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Yes, in most cases. The deleted branch's tip commit shows up as a dangling commit in git fsck, full output, and git branch <name> <hash> restores the branch together with its entire history, because every commit links to its parents."
      }
    },
    {
      "@type": "Question",
      "name": "What should I do if git fsck reports missing or corrupt objects?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Back up the repository directory immediately, then fetch from a healthy remote so Git can download the missing objects, and re-run git fsck, full to verify. Do not run garbage collection or repacking on a corrupted repository until the integrity errors are resolved."
      }
    },
    {
      "@type": "Question",
      "name": "Does GitHub keep commits that are no longer on any branch?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Commits you pushed remain on GitHub's servers as objects, and they can often be found by fetching and searching all refs, or by asking repository administrators to check activity records. Treat this as a recovery avenue rather than a guarantee, and rely on regular pushing and remote backups as the actual safeguard."
      }
    }
  ]
}
</script>