Git: Restore a Commit with Reflog
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.
Basically, git
doesn’t remove commits right away when git reset
happen. It changes references first. In this example, HEAD
is now changed to 6e9be90
. 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 a91929a
.
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>
.