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
- Right-click on commit to revert
- Select "Reverse commit..."
- Choose whether to commit immediately or stage changes
βͺ Reset Operations
- Right-click on target commit
- Choose "Reset current branch to this commit"
- Select reset mode (soft/mixed/hard)
πΈοΈ Viewing Reflog
- Go to Repository β Reflog
- Browse chronological list of all repository changes
- Right-click any entry to create branch or reset to that point