08. Recovery - ivomac/GitBasics GitHub Wiki

πŸ”„ Revert: Safe Undo

  • Revert creates a new commit that undoes changes from previous commits.
  • πŸ›‘οΈ Non-destructive: doesn't rewrite history.
  • πŸ”„ Can revert multiple commits or merge commits.

πŸ”„ Revert Scenario

A ◄─ B ◄─ C ◄─ D β—„ main β—„ HEAD
  • After reverting commit C:
A ◄─ B ◄─ C ◄─ D ◄─ E β—„ main β—„ HEAD
  • πŸ”„ E is a new commit that undoes C's changes.
  • πŸ“š Full history is preserved.

βͺ Reset

def reset(target: Commit, mode: ResetMode = "mixed"):
  • 🎯 Reset moves the current branch pointer back to a previous commit.
  • πŸ“š You can keep changes made in the cleared commits on the index and/or workdir.
  • πŸ’₯ Reset is a destructive operation!

βͺ Reset Scenario

  • We want to revert/remove commit C:
A ◄─ B ◄─ C ◄─ D β—„ main β—„ HEAD
  • We first do a soft reset to C:
A ◄─ B ◄─ C β—„ main β—„ HEAD + πš’

     (D's changes are now staged)
  • We then do a hard reset to B:
A ◄─ B β—„ main β—„ HEAD + πš’

     (C's changes were discarded, D's changes are still staged)
  • We commit the index (D's changes):
A ◄─ B ◄─ E β—„ main β—„ HEAD
  • ⚠️ We effectively removed C and its changes from the history.
  • The default reset mode is mixed: changes of reset commits are left in the workdir (not staged).
  • Soft reset stages the changes, and hard reset discards them completely.

πŸ”§ Restore

def restore(files: list[str], source: Commit = HEAD):
  • Restore recovers specific files without affecting commits or branches.
  • πŸ”„ Can restore from any commit, staging area, or working directory.

πŸ”§ Restore Scenarios

A ◄─ B ◄─ C ◄─ D β—„ main β—„ HEAD + πš’πš 

(workdir 𝚠 only contains changes in README.md)
  • Reset README.md to HEAD version (discards workdir changes):
A ◄─ B ◄─ C ◄─ D β—„ main β—„ HEAD + πš’
  • Reset mango.py to B version:
A ◄─ B ◄─ C ◄─ D β—„ main β—„ HEAD + πš’πš 

(workdir 𝚠 contains mango.py as it was in B)

πŸ•ΈοΈ Reflog

  • The reflog (reference log) records every change to branch tips and HEAD in your local repository.
  • πŸ›‘οΈ It's your safety net for recovering "lost" commits, even after destructive operations.
  • ⏰ Reflog entries expire after 90 days by default (30 days for unreachable commits).
  • πŸ” Each reflog entry shows: commit hash, previous hash, action, and timestamp.

πŸ•ΈοΈ Branch Recovery Scenario

A ◄─ B ◄─ C β—„ main
     β–²
     D ◄─ E ◄─ F β—„ feature β—„ HEAD
  • βœ‚ You rebase feature on top of main, resolving conflicts:
         main
          β–Ό
A ◄─ B ◄─ C ◄─ G ◄─ H ◄─ J β—„ feature β—„ HEAD
  • πŸ’€ The commits D, E, F are now unreachable (but still exist).
  • πŸ•ΈοΈ In the reflog, we recognise F's commit message and can see its hash.
  • πŸ”„ We create branch feature-pre-rebase pointing to F by referencing the hash.
         main
          β–Ό
A ◄─ B ◄─ C ◄─ G ◄─ H ◄─ J β—„ feature β—„ HEAD
     β–²
     D ◄─ E ◄─ F β—„ feature-pre-rebase

🌲 Recovery in SourceTree

πŸ”„ Revert Operations

  1. Right-click on commit to revert
  2. Select "Reverse commit..."
  3. Choose whether to commit immediately or stage changes

βͺ Reset Operations

  1. Right-click on target commit
  2. Choose "Reset current branch to this commit"
  3. Select reset mode (soft/mixed/hard)

πŸ•ΈοΈ Viewing Reflog

  1. Go to Repository β†’ Reflog
  2. Browse chronological list of all repository changes
  3. Right-click any entry to create branch or reset to that point