Read more

Git restore vs. reset for reverting previous revisions

Avatar
Felix Eschey
September 14, 2023Software engineer at makandra GmbH

The git doc states Show archive.org snapshot on the difference of these two commands:

  • git-restore[1] is about restoring files in the working tree from either the index or another commit. This command does not update your branch. The command can also be used to restore files in the index from another commit.
  • git-reset[1] is about updating your branch, moving the tip in order to add or remove commits from the branch. This operation changes the commit history.

git reset can also be used to restore the index, overlapping with git restore.

Background

git restore

Illustration online protection

Rails Long Term Support

Rails LTS provides security patches for old versions of Ruby on Rails (2.3, 3.2, 4.2 and 5.2)

  • Prevents you from data breaches and liability risks
  • Upgrade at your own pace
  • Works with modern Rubies
Read more Show archive.org snapshot

Regarding the git doc Show archive.org snapshot restore does by default:

The command can also be used to restore the content in the index with --staged, or restore both the working tree and the index with --staged --worktree.

By default, if --staged is given, the contents are restored from HEAD, otherwise from the index.

What does this mean?

  • git restore --staged <path> reverts changes from the staging area to match the content of HEAD.
  • git restore --worktree <path> reverts changes from the working tree to match the index from the current revision of HEAD including all files added to the index in previous commits.
  • git restore --staged --worktree <path> discrads local changes and overwrites both to match the current HEAD.

But what about --source?
As the doc states

Use --source to restore from a different commit.
it is a hint that it acts as if it would restore changes from the checked out state of that commit.

The git doc Show archive.org snapshot also states on the source option:

If not specified, the contents are restored from HEAD if --staged is given, otherwise from the index.

This means it will use the index and the HEAD as if that commit was checked out, such that git restore --worktree --staged --source <commit hash> uses the index and the HEAD of the checked out state.

git reset

git reset <commit hash> moves HEAD to a specified commit and resets the state of the repository to that commit. The different options let you decide how to deal with changed differences compared to the command, i.e. reverting it the index/working directory or not.

--mixed (default)

Resets to the state of that commit by setting the working tree to the state of the given commit and discarding changes in the staging area. It keeps changes in the working directory untouched.

--soft

Resets to the state of that commit by setting the staging area to the state of that commit and keeping changes in the working and in the index untouched.

--hard

Resets to the state of the given commit by resetting all introduced changes in the working tree and the staging area.

Difference

So as we've seen both can be used to revert revisions within the index and the working directory. Here is a short overview of the main differences:

  • It is especially unique about git restore that you can revert the working directory compared to a given index.
  • git restore does not move the HEAD, this is especially useful if changing the HEAD may lead to side effects, since commits may be lost after resetting and pushing.
    • If you use git reset with a path it also does not move the HEAD, so in this case you can use these commands quite similar.

Also see

Avatar
Felix Eschey
September 14, 2023Software engineer at makandra GmbH
Posted by Felix Eschey to makandra dev (2023-09-14 11:34)