git reset is generally used to cancel a commit. It happens mainly for two reasons. One is just to cancel it. The other is to modify changes. After changes, a new commit can be created.
git commit --amend is an alternative way to modify it. Both ways can make the same result.
These commands are quite useful and powerful. The thing is that I sometimes want to cancel those and restore the previous commit. After
git reset, it is gone.
git log doesn’t show it anymore.
Then, what would be the way to restore it? Maybe you pushed a branch or a commit to a remote repository before. When
git reset happens only in a local machine, it’s possible to get or restore it from the remote repository. If not, it can be tricky.. Luckily,
git has reference logs. The
git document describes
Reference logs, or “reflogs”, record when the tips of branches and other references were updated in the local repository.
git doesn’t remove commits right away when
git reset happen. It changes references first. In this example,
HEAD is now changed to
git reflog shows those reference change logs. These logs are stored only locally and
git will prune reference logs older than 90 days by default. The below command shows the commit id,
a91929a, before running
git reset HEAD^.
git reset --hard <COMMIT_ID> would restore that commit and references.
The same way is applicable to restore after
git commit --amend. This command is used to apply more changes to the existing commit. Technically,
git commit --amend does’t modify an existing commit. It will create a new commit using the changes of the most recent existing commit. Then,
git adjust references to show only the new commit.
git log doesn’t show that previously existing commit.
It means that it would be easy to restore by knowing that previously existing commit id.
git reflog shows those records. The commit id before amending is
git reset --hard command will restore that commit and references.
One more thing. If you want to learn more on references, try
git cat-file -p <COMMIT_ID|BRANCH>.