Reputation: 31161
Given a git branch with some commits on it (C is the most recent commit):
A -> B -> C
How do I reset my workspace so that all the files are in the state they were at commit B, but HEAD is still at C?
I've looked at git-reset
, but none of the options seem to help. The man page suggests that all the different modes will move HEAD:
--soft Does not touch the index file or the working tree at all (but resets the head to <commit>, just like all modes do).
I've tried git reset HEAD~
but that moves HEAD.
Upvotes: 23
Views: 4830
Reputation: 5252
git checkout [-p|--patch] [<tree-ish>] [--] <pathspec>...
git checkout with <paths>
or--patch
is used to restore modified or deleted paths to their original contents from the index or replace paths with the contents from a named<tree-ish>
(most often a commit-ish).
So you need to run this at root of your repository (works fine for any sub-tree or file(s) too):
git checkout HEAD~ -- .
This will result in git applying changes necessary to revert files to HEAD~
state not counting file removals, the changes will be in the index. Add --no-overlay
flag to allow removal of files added since HEAD~
:
git checkout --no-overlay HEAD~ -- .
From man git-checkout
(git v2.44.0):
--overlay
,--no-overlay
In the default overlay mode,git checkout
never removes files from the index or the working tree. When specifying--no-overlay
, files that appear in the index and working tree, but not in<tree-ish>
are removed, to make them match<tree-ish>
exactly.
Upvotes: 20
Reputation: 167
As pointed out in this answer to a similar question, you can use git restore
for that in Git 2.23+, like so:
git restore -s HEAD~ .
According to its manpage, git restore
[restores] specified paths in the working tree with some contents from a restore source.
You use -s
(or --source
) to specify which commit you want to use as the restore source (here HEAD~
) and specify the path(s) to restore (here everything, so .
) at the end.
Upvotes: 4
Reputation: 114300
You could use a combination of hard and soft resets:
git reset --hard B
git reset --soft C
The first would move HEAD
to B
and make all your files look like B
. The second would then move it back to C
without changing any files.
This method has the advantage that you are not in a detached-head state and all the differences between B
and C
will just show up as inverse diffs of your last actual commit. You will still be on your original branch.
You would probably have to specify C
as a SHA-1 rather than a ref name, unless you specifically created one for the purpose.
Upvotes: 16
Reputation: 4794
Just use git checkout
:
$ git checkout HEAD~
$ # Or
$ git checkout HEAD^
$ # Or
$ git checkout B
This will bring you into a detached head state where the HEAD is detached from a branch.
Upvotes: -1