linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
Intro
Lessons
Footer
linuxlab-TutorialsPricingAboutPrivacy & cookies
Copyright © 2026 LinuxLab. All rights reserved.
linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
  • Introduction
  • Chapters
  • How it works
  • Lessons
  • Knowledge base
  • Interview prep
home/git/lessons/git-lab-09-1-undo

lesson ── git-labs ── ~22 мин ── 8 шагов

Undoing: reset, revert, reflog

The goal is to walk through three ways to "rewind" and learn when to use each one. reset rewrites history, which suits your own local branch. revert creates a compensating commit and is safe on a shared branch. reflog saves you once everything is already broken.

▶ интерактивный sandbox

Поднимется контейнер gitlab/git-base с git, bash, pre-commit. В браузере откроется терминал, можно сразу git init. Каждый шаг проверяется автоматически. Сеть air-gapped, github.com недоступен.

запустить sandbox →

stack ── git · bash · 256 MB RAM · air-gapped · самоуничтожается через 30 мин простоя

Шаги

  1. 01

    Create a repo with five commits

    bash
    cd /home/student/work
    mkdir -p undo-lab && cd undo-lab
    git init -b main
    for i in 1 2 3 4 5; do
      echo "line $i" >> file.txt
      git add file.txt
      git commit -m "line $i"
    done
    git log --oneline

    Five commits, the file holds 5 lines. This is your practice range for undos.

    ✓ Five commits in place.

  2. 02

    Run reset --soft by one commit

    --soft drops the commit but keeps its content in the index.

    bash
    cd /home/student/work/undo-lab
    git reset --soft HEAD~1       # --soft = move the branch only, do not touch index or working
    git log --oneline             # log is 1 shorter
    git status                    # content of the dropped commit is in the index

    The log is now 4 commits. The index holds line 5 and is ready to recommit with a different message.

    ✓ Commit dropped, the change is in the index.

  3. 03

    Run reset --mixed to clear the index

    --mixed (the default) also clears the index. It leaves the working tree alone.

    bash
    cd /home/student/work/undo-lab
    git reset HEAD~1              # no flag = --mixed: branch + index, do not touch working
    git log --oneline
    git status                    # changes in working as unstaged

    The log is 3 commits. The index is empty. The working tree holds line 4 and line 5 as unstaged changes. Useful when a commit was made with the wrong files in the index.

    ✓ Index cleared. Changes are in working.

  4. 04

    Run reset --hard to wipe everything

    bash
    cd /home/student/work/undo-lab
    git reset --hard HEAD~1       # --hard = branch + index + working, all set to HEAD~1
    git log --oneline
    cat file.txt                  # only 2 lines, everything above is gone
    git status                    # working tree clean

    The log is 2 commits. file.txt holds only 2 lines. The working tree is clean. All the "lost" changes are no longer visible through log, but...

    подсказка

    Dangerous? Yes. But reflog still remembers.

    ✓ Hard reset done. History 'seems' lost.

  5. 05

    Recover what was lost via reflog

    reflog is a local journal of HEAD moves. All the "deleted" commits are still there.

    bash
    cd /home/student/work/undo-lab
    git reflog                    # local log of every HEAD move (90 days)

    You see entries HEAD@{0}, HEAD@{1}, and so on. These are your recent positions. Find the one where there were 5 commits:

    bash
    # HEAD@{n} = "where HEAD was n steps ago" per reflog
    git reset --hard HEAD@{4}
    git log --oneline             # all 5 commits are back

    All 5 commits are back. reflog keeps entries for 90 days by default.

    ✓ Five commits restored. reflog saved you.

  6. 06

    Undo a commit via revert (without rewriting history)

    Suppose commit line 3 is bad, and someone has already pushed it to shared. reset is dangerous here: it rewrites history. Use revert.

    bash
    cd /home/student/work/undo-lab
    # awk '{print $1}' = first column of `log --oneline`, the short sha
    SHA=$(git log --oneline | grep 'line 3' | awk '{print $1}')
    git revert --no-edit $SHA     # --no-edit = take the default message "Revert ..."
    git log --oneline
    cat file.txt                  # line 3 is gone, the rest are kept

    The log grew by one commit (Revert "line 3"). History is preserved, and both of you can see what happened. file.txt now holds line 1, line 2, line 4, line 5, without line 3.

    ✓ Revert created an inverse commit. History was not rewritten.

  7. 07

    Compare the revert result against what reset would have done

    Remember the difference:

    • reset removes commits from history. SHAs after the reset are rewritten. On a pushed branch this disrupts the team's work.
    • revert adds a new commit that undoes the old one. History grows, but no SHAs change.
    bash
    cd /home/student/work/undo-lab
    git log --oneline --graph

    You see a linear history of 6 entries: 5 original ones plus the revert. No "missing" SHAs.

    ✓ Six commits. History intact, the mistake undone.

  8. 08

    Run amend and recover the old version via reflog

    Make a commit:

    bash
    cd /home/student/work/undo-lab
    echo "extra" >> file.txt
    git add file.txt && git commit -m "add extra"
    git log --oneline | head -1

    Note the SHA. Run amend:

    bash
    git commit --amend -m "add extra (corrected)"   # replaces HEAD with a new commit
    git log --oneline | head -1   # different SHA, new message

    The commit's SHA is different. The old version is in reflog:

    bash
    git reflog | head -5          # top 5 entries: both commit and commit (amend) are visible

    Both versions are visible: one commit:, the other commit (amend):. If you want to undo the amend, run git reset --hard HEAD@{1}. The lesson ends here: you know how to undo almost anything you did by accident.

    ✓ Amend and reflog worked. Most of what is 'lost' in Git can be brought back.

Что ты узнал

reset moves the branch pointer back (3 levels of aggressiveness). revert creates a commit that is the inverse by content. reflog keeps every HEAD position for the last 90 days, and even "deleted" commits are recovered from there.

команды

  • git reset --soft HEAD~1drop the commit, keep the index
  • git reset --hard <sha>move to a commit and wipe everything
  • git revert <sha>create an inverse commit
  • git refloglog of every HEAD position
  • git reset --hard HEAD@{n}restore a state from reflog

концепции

  • · reset rewrites history, revert adds to it
  • · reflog sees what log does not
  • · hard reset is dangerous, but reflog almost always saves you

← предыдущая

Merge vs rebase: by hand in one repository

следующая →

git bisect: find a bug with binary search

Footer
linuxlab-
Copyright © 2026 LinuxLab. All rights reserved.
Tutorials
Pricing
About
Privacy & cookies