tl;dr
git checkout
is the swiss army of git commands. If you prefer a semantically more meaningful command for restoring tasks, usegit restore
instead.With this command you can ...
- ... do unstaging -
git restore --staged
- ... discard staged changes -
git restore --staged --worktree
- ... discard unstaged changes -
git restore
- ... restore deleted files -
git restore
- ... restore historic versions -
git restore --source
- ... recreate merge conflicts -
git restore --merge
- ... specifiy how unmerged paths are treated by using
--ours
,--theirs
or--ignore-unmerged
- ... choose selectively which diffs are restored -
git restore --patch
You can use
git restore
since git 2.23.
Unstaging
You want to exclude changes for the next commit, you can do this with git restore --staged
.
echo '3.1.2' > .ruby-version
echo 'Some Changes' >> README.md
git status
# Changes not staged for commit:
# modified: .ruby-version
# modified: README.md
git add README.md .ruby-version
# We only want to commit .ruby-version
git status
# Changes to be committed:
# modified: .ruby-version
# modified: README.md
git restore --staged README.md
git status
# Changes to be committed:
# modified: .ruby-version
#
# Changes not staged for commit:
# modified: README.md
Hint
You can also use the short version
git restore -S
.
Info
For this use case you can also use
git reset
.
Discard Changes
You're implementing a new feature and after some try and error you want to discard some changes. You can do this with git restore
.
Discard Staged Changes
echo '3.1.2' > .ruby-version
git add .ruby-version
git status
# Changes to be committed:
# modified: .ruby-version
# Now we want to undo the change
git restore --staged --worktree .ruby-version
git status
# nothing to commit, working tree clean
Hint
You can also use the short version
git restore -S -W
.
Discard Unstaged Changes
echo '3.1.2' > .ruby-version
git status
# Changes not staged for commit:
# modified: .ruby-version
# Now we want to undo the change
git restore .ruby-version
git status
# nothing to commit, working tree clean
Info
For this use case you can also use
git checkout
.
Discard changes selectively
If you decide that you only want to discard specific changes (e.g. you decide to change some implementations details), you can use the --patch
(short: -p
) flag to discard changes selectively, i.e. it allows you whether you want to restore a specific diff or not.
git restore -p
diff --git app/models/test.rb
index eg3c1k1..843c0a2 31143
--- app/models/test.rb
+++ app/models/test.rb
@@ -19,6 +19,10 @@ module RoutingFilter
path = Rails.root / 'app'
+ if true
+
+ end
+
return path
(1/1) Discard this hunk from worktree [y,n,q,a,d,e,?]? ?
y - discard this hunk from worktree
n - do not discard this hunk from worktree
q - quit; do not discard this hunk or any of the remaining ones
a - discard this hunk and all later hunks in the file
d - do not discard this hunk or any of the later hunks in the file
e - manually edit the current hunk
? - print help
You can pass the path for selectively restoring changes in this (file) path as well. When the path is omitted it will check for applied change in the complete repository.
Restore Changes affected by Merge Conflicts
If you encounter merge conflicts, you have several options how to use restore
.
Recreating the initial Merge Conflict
When you just resolved some merge conflicts (e.g. by using git rebase
or git merge
) and are not sure if you made the right merge decisions, you can use the --merge
(short -m
) flag to recreate the conflicted state as in the unmerged path.
If you haven't yet finished the complete merge you might want to use --ignore-unmerged
Only picking theirs or ours Changes
If you want to restore and have unmerged paths, you can specify if you want to keep your or the incoming changes by using the either --ours
or --theirs
.
Ignoring unmerged paths
If you want to ignore unmerged paths which would be affected by restore
, you can set --ignore-unmerged
.
Restore a Deleted File
You have deleted a file and then realize you still need it. You can restore the file with git restore
.
rm -f README.md
ls README.md
# ls: cannot access 'README.md': No such file or directory
git restore README.md
ls README.md
# README.md
Info
For this use case you can also use
git checkout
.
Restore Historic Versions
You want to see if a bug was caused by certain changes, you can restore a history version of a file, e.g. from the master branch. You can do this with git restore --source
.
git branch -a
# * your-feature-branch
# master
# restore a file from master
git restore --source=master my_file.rb
# restore a file from an older version of master
git restore --source=master~5 my_file.rb
# restore a file from a commit hash
git restore --source=commit-hash my_file.rb
Hint
You can also use the short version
git restore -s
.
Info
For this use case you can also use
git checkout
.