Soft2Soft Cheat Practical knowledge base
Git

How to Undo the Last Local Git Commit Without Losing Changes

5 views
git коммиты отмена изменений

To undo the last local commit while keeping all changes staged for recommitting, run:

git reset --soft HEAD~1

This command moves the current branch pointer back by one commit without changing the index or working files. The changes from the undone commit remain staged, so you can commit them again immediately.

Prerequisites and Limitations

  • Run the command inside the correct Git repository.
  • The current branch must contain at least one parent commit.
  • The commit being undone should not have been published to a shared remote branch unless rewriting history has been coordinated with the other contributors.
  • Any uncommitted changes that existed before running the command will also remain in the working directory and index.

First, check the current repository and recent commits:

git status
git log --oneline -3

Make sure the first line of the log is the commit you want to undo. Then perform a soft reset:

git reset --soft HEAD~1

The HEAD~1 notation refers to the first ancestor of the current commit, which is the previous commit in the current branch history.

Verifying the Result

After the reset, check the repository status:

git status

The files from the undone commit should appear under changes staged for commit. You can also inspect the contents of the index:

git diff --cached

This command shows the changes that will be included in the next commit. To confirm that the last commit has been removed from the current branch history, view the log again:

git log --oneline -3

The former last commit should no longer be the tip of the current branch. Its data is usually still available through Git's reference log, so an accidental reset can be recovered.

Committing Again After Corrections

If you do not need to modify the file contents, create a new commit with a corrected message:

git commit -m "Исправленное сообщение коммита"

If you need to modify files, edit them and then add the corrections to the index:

git add путь/к/файлу
git commit -m "Исправленное сообщение коммита"

To add all tracked and new files from the current directory, use:

git add .
git commit -m "Исправленное сообщение коммита"

Before committing again, review the staged set of changes:

git diff --cached

How to Keep Changes Unstaged

If the changes should remain in the working files but not in the index after undoing the commit, use a mixed reset:

git reset --mixed HEAD~1

The --mixed option is the default mode for git reset, so the shorter form is also valid:

git reset HEAD~1

In this mode, Git moves the current branch to the previous commit and updates the index without overwriting the working files. After the command finishes, the changes will appear as unstaged:

git status
git diff

You can then selectively stage the required files:

git add путь/к/первому-файлу
git add путь/к/второму-файлу
git commit -m "Новое сообщение коммита"
Command HEAD Position Index Working Files
git reset --soft HEAD~1 Moves backward Unchanged Unchanged
git reset --mixed HEAD~1 Moves backward Reset to the selected commit Unchanged
git reset --hard HEAD~1 Moves backward Reset Overwritten

Do not use git reset --hard HEAD~1 for this task. The --hard mode updates not only the history and index but also the working tree. Uncommitted changes in affected files may be lost.

When You Only Need to Fix the Last Commit

You do not need to undo the commit if you only want to change its message or add forgotten changes. For the latest local commit, you can use git commit --amend.

To change only the message, run:

git commit --amend

Git will open the configured commit-message editor. To provide a new message directly on the command line, use:

git commit --amend -m "Исправленное сообщение коммита"

To add a forgotten file to the last commit:

git add путь/к/файлу
git commit --amend --no-edit

The --no-edit option preserves the existing message. An amend operation creates a new commit object with a different identifier, so it should be used on already published shared history only when you understand the consequences.

What to Do If the Commit Has Already Been Pushed

If the last commit has already reached a branch used by other developers, it is safer not to rewrite history and instead create a reverting commit:

git revert HEAD

git revert creates a new commit that reverses the changes introduced by the selected commit. The existing history remains intact. This approach is usually preferable for shared branches.

After running the command, verify the result:

git status
git log --oneline -3
git show --stat HEAD

If the published commit belongs only to your personal branch and rewriting history is acceptable, you can technically use reset and then force-update the remote branch. However, that is a separate operation with a risk of overwriting someone else's changes. Force-pushing is not required to undo a purely local commit.

Recovering from an Accidental Reset

Git records movements of HEAD in the reference log. To view recent positions, run:

git reflog

Find the entry corresponding to the state before the reset. It may appear as a reference such as HEAD@{1}, but the actual number depends on the operations performed afterward. Do not use the example number without checking your own output.

To return the branch to the identified commit, specify its identifier:

git reset --soft <идентификатор-коммита>

To fully restore the branch, index, and working tree to the identified state, use --hard, but only after saving any uncommitted files you need:

git reset --hard <идентификатор-коммита>

Before performing this operation, you can create a backup branch:

git branch backup-before-recovery

Checking the Version and Local Documentation

The modes described above are part of the standard Git reset command. Check the installed version with:

git --version

The exact rules for the installed version are available in the built-in documentation:

git help reset
git help commit
git help revert
git help reflog

This is especially useful in environments that use an old or modified Git build.

Final Checklist

  1. Run git status and confirm that you are in the correct repository.
  2. Check the latest commit with git log --oneline -3.
  3. To keep the changes in the index, run git reset --soft HEAD~1.
  4. To keep the changes only in the working files, run git reset --mixed HEAD~1.
  5. Verify the result with git status and git diff --cached.
  6. Correct the files or message and create a new commit.
  7. Do not use --hard when the changes must be preserved.
  8. For a shared commit that has already been published, consider git revert HEAD instead of rewriting history.

Sources