daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

git-reset.md (8312B)


      1 ---
      2 title: "Git Reset & Undo"
      3 description: "Undo work safely: reset soft/mixed/hard, restore, revert, reflog recovery and stash rescue."
      4 category: git-workflow
      5 tags: [git, undo, recovery]
      6 tools: [git]
      7 difficulty: intermediate
      8 updated: "2026-08-09"
      9 source: "vault:Git/Resetting.md"
     10 ---
     11 
     12 # Git Reset & Undo
     13 
     14 Working-tree inspection, diffing, restoring, and amending — knowing which of Git's three zones a change lives in determines which command undoes it safely.
     15 
     16 > **Prerequisites —**
     17 > 1. Must be inside a valid Git repository (`git init` or cloned).
     18 > 2. `git restore` requires **Git 2.23.0+** (2019) — use legacy equivalents on older versions.
     19 > 3. For `--amend`: must be on a **local-only** branch — do not amend commits already pushed to a shared remote.
     20 
     21 > **Working tree state — conceptual overview:** Git tracks files across three zones:
     22 > 1. **Working Tree** — your local filesystem; where you edit files.
     23 > 2. **Staging Area (Index)** — files queued for the next commit via `git add`.
     24 > 3. **Repository** — committed history; each snapshot has a unique SHA hash.
     25 >
     26 > Understanding which zone a file lives in determines which command to use.
     27 
     28 > **Output state reference —**
     29 >
     30 > | Status Message | Meaning |
     31 > |---|---|
     32 > | `Changes not staged for commit` | Modified in working tree, not yet staged |
     33 > | `Changes to be committed` | Staged; ready for next commit |
     34 > | `nothing to commit, working tree clean` | Working tree matches last commit exactly |
     35 > | `Untracked files` | New file Git has never seen |
     36 
     37 > **Diff output prefix reference —**
     38 >
     39 > | Prefix | Meaning |
     40 > |---|---|
     41 > | `---` | Old version of the file |
     42 > | `+++` | New version of the file |
     43 > | `-` | Line removed in new version |
     44 > | `+` | Line added in new version |
     45 > | (none) | Unchanged context line |
     46 >
     47 > `@@ -1 +1 @@` indicates line numbers affected in the old (`-`) and new (`+`) file.
     48 
     49 ## Inspecting Working Tree State
     50 
     51 ```bash
     52 # Check current state of working tree and staging area
     53 git status
     54 ```
     55 
     56 > **Command breakdown — `git status`:**
     57 > 1. No flags required — produces full human-readable output by default.
     58 > 2. `-s` / `--short` — terse, machine-friendly output format.
     59 > 3. Read-only; generates no network traffic and no Git history artefacts.
     60 
     61 ## Diffing Working Tree vs. Last Commit
     62 
     63 ```bash
     64 # Diff all modified files against staging area / last commit
     65 git diff
     66 
     67 # Explicitly diff working tree against latest commit on current branch
     68 git diff HEAD
     69 
     70 # Diff a specific file against a specific commit hash
     71 git diff 4620193 example.html
     72 ```
     73 
     74 > **Command breakdown — `git diff`:**
     75 > 1. (no args) — compares working tree against the staging area; equivalent to last commit if nothing is staged.
     76 > 2. `HEAD` — explicitly targets the latest commit on the current branch.
     77 > 3. `<commit> <file>` — targets a specific file at a specific commit SHA.
     78 > 4. Read-only; no history artefacts created.
     79 
     80 > **Warning — Pager mode:** If output fills the terminal, Git enters pager mode (usually `less`). Scroll with arrow keys; press `q` to exit. Pager behaviour is controlled by the `$PAGER` environment variable.
     81 
     82 > **No output shown —** The file may already be staged; staged changes are invisible to `git diff` (no args). Use `git diff --staged` to compare staged changes against the last commit.
     83 
     84 ## Discarding Local (Unstaged) Changes
     85 
     86 > **Danger — Destructive operation:** `git restore` on the **working tree** permanently discards uncommitted edits. Changes are **not recoverable** unless a stash or reflog entry exists. Always run `git diff` first to review what will be lost.
     87 
     88 ```bash
     89 # Restore all files in the current directory to last committed state
     90 git restore .
     91 
     92 # Restore a single named file only
     93 git restore hello.html
     94 
     95 # Restore a subdirectory
     96 git restore src/
     97 ```
     98 
     99 > **Command breakdown — `git restore` (working tree):**
    100 > 1. `.` — restores all files in the current directory recursively.
    101 > 2. `<file>` — restores a single named file only.
    102 > 3. `<path/>` — restores an entire subdirectory.
    103 > 4. `--worktree` — explicit flag for this mode; same as omitting it (default behaviour).
    104 > 5. No network activity; modifies only local files.
    105 
    106 ```bash
    107 # Confirm clean state after restoring
    108 git status
    109 # Expected: nothing to commit, working tree clean
    110 ```
    111 
    112 > **Result —** `git restore` produces no output on success. Confirm with `git status` — should show `nothing to commit, working tree clean`.
    113 
    114 > **Common errors —**
    115 > 1. `error: pathspec 'X' did not match any file(s)` → check filename spelling and current working directory.
    116 > 2. Accidentally discarding intended work → always run `git diff` before `git restore`.
    117 
    118 > **Tip — Legacy equivalent:** `git checkout -- <file>` performs the same action but is superseded. Prefer `git restore` on modern installs (Git 2.23.0+).
    119 
    120 ## Unstaging Staged Changes
    121 
    122 ```bash
    123 # Unstage all staged files — edits are preserved in working tree
    124 git restore --staged .
    125 
    126 # Unstage a single file — edits preserved
    127 git restore --staged hello.html
    128 
    129 # Unstage AND discard working tree changes in one step (destructive)
    130 git restore --staged --worktree .
    131 ```
    132 
    133 > **Command breakdown — `git restore --staged`:**
    134 > 1. `--staged` — operates on the staging area (index) rather than the working tree; non-destructive.
    135 > 2. `--staged --worktree` — unstages **and** discards working tree changes in a single command; destructive.
    136 > 3. After `--staged` alone: file appears under `Changes not staged for commit` — edits still present.
    137 > 4. After `--staged --worktree`: `git status` shows `nothing to commit, working tree clean`.
    138 
    139 > **Warning — Easy to confuse:** `git restore .` ≠ `git restore --staged .` — the first only affects the **working tree**; it does not unstage. After `--staged` alone, edits are **not gone** — run `git restore .` separately if you also want to discard them.
    140 
    141 > **Tip — Legacy equivalent:** `git reset HEAD <file>` performs the same unstaging action. Available on Git versions older than 2.23.0.
    142 
    143 ## Fixing the Last Commit — `--amend`
    144 
    145 > **Danger — History-rewriting warning:**
    146 > 1. `--amend` **replaces** the last commit — a new SHA is generated; the old one disappears locally.
    147 > 2. **Do not amend commits already pushed to a shared remote** — this requires `git push --force`, which is visible to all collaborators.
    148 > 3. The old commit object remains accessible via `git reflog` until garbage-collected.
    149 > 4. On shared branches, prefer adding a new fix commit rather than amending.
    150 
    151 ```bash
    152 # Fix only the commit message inline
    153 git commit --amend -m "Added HTML tags to hello.html"
    154 
    155 # Add a forgotten file and update the message in one step
    156 git add hello.html
    157 git commit --amend -m "Added H1, HTML, and BODY tags to hello.html"
    158 
    159 # Amend message interactively via default text editor (vim/nano)
    160 git commit --amend
    161 ```
    162 
    163 > **Command breakdown — `git commit --amend`:**
    164 > 1. `--amend` — replaces the most recent commit with a new one (new SHA generated).
    165 > 2. `-m "<msg>"` — sets the new commit message inline; omit to open the configured text editor.
    166 > 3. Pre-stage additional files with `git add` **before** running `--amend` to include them in the amended commit.
    167 > 4. Git prints the updated commit summary including the new amended SHA on success.
    168 
    169 > **Common editor traps —**
    170 > 1. **Stuck in vim** (opened by omitting `-m`) → press `Esc`, type `:wq`, press `Enter` to save and exit.
    171 > 2. **Stuck in nano** → `Ctrl+O` to save → `Enter` to confirm filename → `Ctrl+X` to exit.
    172 > 3. **Amended a pushed commit** → coordinate with the team before force-pushing; prefer a new fix commit on shared branches.
    173 
    174 > **Tip — Best-practice workflow:**
    175 > 1. Stage any missed files: `git add <file>`
    176 > 2. Review what will change: `git diff --staged`
    177 > 3. Amend with corrected message: `git commit --amend -m "<message>"`
    178 > 4. Verify result: `git log --oneline -1`
    179 
    180 ## References
    181 
    182 - [git-status Documentation](https://git-scm.com/docs/git-status)
    183 - [git-diff Documentation](https://git-scm.com/docs/git-diff)
    184 - [git-restore Documentation](https://git-scm.com/docs/git-restore)
    185 - [git-commit --amend Documentation](https://git-scm.com/docs/git-commit#Documentation/git-commit.txt---amend)
    186 - [Atlassian — Rewriting Git History](https://www.atlassian.com/git/tutorials/rewriting-history)