SovranCode
HomeCourses Git & GitHub Git Reset
This device
Course contentsGit Reset · 41 topics

1. Git Fundamentals

Git IntroductionGit Version ControlGit vs GitHubGit InstallationGit Working TreeGit RepositoryGit CommitGit .gitignoreGit Project: Learning Journal

2. Git History

Git LogGit DiffGit ResetGit RevertGit StashGit Project: Messy Repository

3. Branches & History

Git BranchGit MergeGit Merge ConflictsGit RebaseGit Cherry-PickGit TagsGit Project: Feature Branch

4. Remotes and GitHub

Git RemoteGitHub AuthenticationGitHub RepositoryGitHub ForkGitHub IssuesGitHub PagesGit Project: Two Clone Sync

5. GitHub Collaboration

GitHub Pull RequestsGitHub Code ReviewGit Branching WorkflowGitHub Branch ProtectionGitHub CollaborationGitHub ContributingGit Project: Reviewed Pull Request

6. Automation and Professional Git

GitHub ActionsGit InternalsGit RecoveryGitHub SecurityGit Project: Team Repository CIProject
Learn Git & GitHub40 complete · 1 planned

1. Git Fundamentals

Git IntroductionGit Version ControlGit vs GitHubGit InstallationGit Working TreeGit RepositoryGit CommitGit .gitignoreGit Project: Learning Journal

2. Git History

Git LogGit DiffGit ResetGit RevertGit StashGit Project: Messy Repository

3. Branches & History

Git BranchGit MergeGit Merge ConflictsGit RebaseGit Cherry-PickGit TagsGit Project: Feature Branch

4. Remotes and GitHub

Git RemoteGitHub AuthenticationGitHub RepositoryGitHub ForkGitHub IssuesGitHub PagesGit Project: Two Clone Sync

5. GitHub Collaboration

GitHub Pull RequestsGitHub Code ReviewGit Branching WorkflowGitHub Branch ProtectionGitHub CollaborationGitHub ContributingGit Project: Reviewed Pull Request

6. Automation and Professional Git

GitHub ActionsGit InternalsGit RecoveryGitHub SecurityGit Project: Team Repository CIProject
PREVIOUS LESSONGit Diff
NEXT LESSONGit Revert
2. Git History 75 min

Git Reset

Change the last unpublished commit, restore files, and use mixed, soft, and hard reset only when you can name the risk.

Practice in a disposable repository

This lesson intentionally includes commands that can overwrite uncommitted work. Use fake files in a throwaway repository, read status and diffs first, and never paste a hard-reset command into a valuable working tree without understanding its target.

Name the state before choosing the command

AmendReplace the latest unpublished commit with a corrected commit.
RestoreCopy file content from a source into the index or working tree.
ResetMove the current branch and deliberately choose what happens to later states.
ProtectInspect, preserve, and recover before a destructive operation becomes a loss.

Ask three questions before correcting history

  1. SCOPE
    Which state is wrong?

    The latest commit, the staged proposal, an unstaged file, or the current branch tip require different operations.

  2. VALUE
    Which content must survive?

    Name the exact committed, staged, unstaged, and untracked work you intend to keep.

  3. SHARING
    Has the commit been published?

    Rewriting a shared commit changes its ID and can break another person’s ancestry.

  4. EVIDENCE
    Can you prove the current state?

    Capture status, relevant diffs, branch name, and commit IDs before changing pointers or files.

Correction and cancellation are different

Sometimes you want to keep a change but move it between states. Sometimes you want to discard it. State that intention explicitly before selecting a command.

Amend the latest unpublished commit

git commit --amend does not edit a commit in place. It creates a new commit, normally with the same parent as HEAD, then moves the current branch to the replacement. The old and new commits have different object IDs even if only the message changes.

# Inspect before changing the latest commit
git status
git diff
git diff --cached
git show --stat HEAD

# Stage the intended correction, then replace HEAD
git add path/to/file
git commit --amend

# Keep the existing message when only the snapshot changes
git commit --amend --no-edit
SNAPSHOT CORRECTION

Stage the intended content

The replacement commit uses the current index. Review git diff --cached immediately before amending.

MESSAGE CORRECTION

Open the commit editor

Run amend without --no-edit, correct the subject or body, save, and verify the new commit with git show.

Do not amend shared history casually

If the original commit has been pushed and others may have based work on it, prefer a new corrective commit. Replacing published history requires explicit team coordination and protected force-push practices.

QUICK CHECK

Test what you learned

Type the command that replaces HEAD using the staged snapshot while retaining the existing message.

Use restore for file-level state changes

git restore copies content from a source into one or more destinations. By default, the destination is the working tree and the source is the index. With --staged, the destination includes the index and the default source becomes HEAD.

# Discard unstaged changes in one tracked path:
git restore -- path/to/file

# Unstage a path while keeping its working copy:
git restore --staged -- path/to/file

# Restore a path from a named commit into the working tree:
git restore --source=HEAD~1 -- path/to/file

# Update both index and working tree from a named commit:
git restore --source=HEAD~1 --staged --worktree -- path/to/file

Discard unstaged edits

git restore -- file makes the tracked working file match the index. Staged content remains staged.

Unstage but keep edits

git restore --staged -- file resets the index copy from HEAD while preserving the working file.

Recover historical content

--source=REV names the commit or tree to copy from. Review the resulting diff before staging it.

Update both destinations

Combining --staged --worktree overwrites both copies. This is broader and needs explicit evidence.

Restore has no confirmation prompt

Working-tree content overwritten by restore may never have been stored as a Git object. A clean-looking command can permanently discard an uncommitted edit.

Choose restore by scenario

WRONG FILE STAGED

Keep the work, change the proposal

Run git restore --staged -- path. Confirm the file moves from the index column to the working-tree column in short status.

UNWANTED UNSTAGED EDIT

Discard only the working change

Inspect git diff -- path, then run git restore -- path only if every displayed line is disposable.

OLDER VERSION NEEDED

Bring history forward as a new change

Restore the path from a named revision into the working tree, inspect the diff, then commit that result normally.

UNTRACKED FILE

Restore is not the cleanup tool

An untracked path has no indexed copy to restore. Review it manually; do not reach for broad cleanup commands as a shortcut.

QUICK CHECK

Test what you learned

Type the command that unstages config.json while preserving its working content.

Reset moves the current branch

At commit level, git reset TARGET moves the current branch tip to TARGET. The mode controls whether Git also resets the index and tracked working-tree content. This changes which commits the branch reaches, so inspect the graph and copy the current tip ID first.

# Move the current branch; keep index and working tree unchanged
git reset --soft HEAD~1

# Move the current branch; reset index; keep working files
git reset --mixed HEAD~1

# Move the current branch; reset index and tracked working files
git reset --hard HEAD~1

--soft

Move branch: yes. Reset index: no. Reset working tree: no. Former commit content remains staged.

--mixed

Move branch: yes. Reset index: yes. Reset working tree: no. This is the default commit-level mode.

--hard

Move branch: yes. Reset index: yes. Reset tracked working tree: yes. Uncommitted tracked changes can be lost.

Path reset differs

git reset HEAD -- path updates the index for a path but does not move the branch. Prefer restore for clearer unstaging intent.

Predict the result before reset

KEEP AS STAGED

Soft reset

  • Use for a local commit assembled at the wrong boundary.
  • The branch moves back.
  • The index still contains the former snapshot.
  • Review before recommitting.
KEEP AS UNSTAGED

Mixed reset

  • Use to reassemble one or more local commits.
  • The branch moves back.
  • The index matches the target.
  • Working edits remain on disk.
Hard reset is not “make Git work”

It is a precise request to overwrite tracked index and working content. Never use it as generic troubleshooting, and never assume reflog can recover changes that were never committed or staged as objects.

Build a recovery point first

git status --short
git diff
git diff --cached
git log --oneline --decorate -5
git rev-parse HEAD

# Give the current commit a temporary recovery name when appropriate:
git branch recovery/before-reset HEAD

# Verify the ref before changing the original branch:
git show --stat recovery/before-reset

A temporary branch protects committed history by keeping the old commit reachable. It does not preserve unstaged or untracked content. Save or commit valuable uncommitted work using an approved workflow before an operation that could overwrite it.

Prefer a reversible sequence

A new corrective commit, a temporary branch, or a file-level unstage usually leaves clearer recovery options than immediately moving a branch and overwriting files.

Recover a moved branch tip with reflog

The local reflog records recent updates to refs such as HEAD. If reset moved a branch away from a committed tip, inspect the reflog, identify the exact prior commit, and create a recovery branch before doing more work.

git reflog --date=iso
git show --stat HEAD@{1}

# After verifying the object:
git branch recovery/lost-tip HEAD@{1}
git log --oneline --decorate --graph --all

Reflog is local, temporary recovery metadata—not a substitute for a shared remote or a preservation plan. Entries expire, differ between clones, and cannot reconstruct arbitrary working-tree text that Git never stored.

Guided practice: correct without losing work

Create a disposable repository with a README and two source files. Make at least three small commits so every pointer movement is visible.

  1. 01
    Amend locally

    Make a fourth commit with an incomplete README, stage the correction, amend with the same message, and prove the object ID changed.

  2. 02
    Separate staged state

    Edit two files, stage both, then unstage one with restore while keeping both working copies.

  3. 03
    Discard one known edit

    Inspect the unstaged patch for one disposable line and restore only that path.

  4. 04
    Compare reset modes

    Create a recovery branch, then use soft and mixed reset in turn. Record branch, index, and working-tree results.

  5. 05
    Recover the tip

    Locate the prior committed tip in reflog, create a recovery branch there, and draw the complete graph.

Independent lab: repair a mistaken local commit

In a disposable repository, create a clean three-commit history. Then create a fourth commit that combines one intended source edit, one unrelated documentation edit, and an inaccurate message. Without deleting any wanted content:

  1. Record status, both diffs, the graph, and the original HEAD ID.
  2. Create and verify a recovery branch at the original tip.
  3. Use mixed reset to move the original branch back one commit while retaining working files.
  4. Stage and commit the source change with an accurate message.
  5. Stage and commit the documentation change separately.
  6. Add an unstaged disposable edit, prove its exact patch, and restore only that path.
  7. Use reflog and the recovery branch to explain where the original combined commit remains reachable.
  8. Finish with clean status and a graph showing the repaired branch and recovery pointer.
Definition of done

You can account for every wanted line, explain each branch movement, show that no shared history was rewritten, and identify the exact command that changed the commit, index, or working tree at every step.

Common correction mistakes

Amending after push

The replacement commit has a new ID. Prefer a follow-up commit when history may already be shared.

Restoring the wrong source

Defaults change with the destination. Name --source when historical content is intended.

Using hard reset reflexively

It overwrites tracked state and may destroy uncommitted content that no Git object can recover.

Assuming reflog saves everything

It records ref movement, not every version ever typed into a working file.

Ignoring untracked files

Reset modes focus on tracked state. Status and a separate preservation decision are still required.

Skipping post-operation proof

Re-run status, diffs, show, and log to verify the result instead of trusting silence.

Lesson review

You can now correct unpublished history without treating Git’s recovery commands as interchangeable. You can replace the latest local commit, move file content between states, predict each reset mode, preserve a committed recovery point, and use reflog without overpromising what it stores.

  • I know amend creates a replacement commit with a new object ID.
  • I distinguish discarding an unstaged edit from unstaging content I want to keep.
  • I can predict branch, index, and working-tree state after soft, mixed, and hard reset.
  • I inspect and preserve valuable work before moving pointers or overwriting files.
  • I reserve history rewriting for unpublished work or an explicitly coordinated workflow.

Related lessons

  • Git Diff — Inspect the change before you move HEAD.
  • Git Revert — Use revert when the commit is already shared.
  • Git Recovery — Preserve a displaced commit before deciding how to restore history.
KNOWLEDGE CHECK

Check your correction safety model

Choose the operation that changes only the intended commit, index, or working-tree state.

01What does git commit --amend create?
02When is amending usually safest?
03Which command unstages app.js while preserving its working-tree edits?
04What does git restore -- app.js do by default?
05Which reset mode moves the branch and leaves both index and working tree unchanged?
06What is the default mode of git reset when a commit is supplied and no mode is named?
07Why must git reset --hard be treated as destructive?
PREVIOUS LESSONGit Diff
NEXT LESSONGit Revert
ON THIS PAGEGit ResetName the state before choosing the commandAsk three questions before correcting historyAmend the latest unpublished commitUse restore for file-level state changesChoose restore by scenarioReset moves the current branchPredict the result before resetBuild a recovery point firstRecover a moved branch tip with reflogGuided practice: correct without losing workIndependent lab: repair a mistaken local commitCommon correction mistakesLesson reviewKnowledge checkRelated lessons
Course contents