What is difference between “git checkout -f” and “git reset --hard HEAD”?
问题
I need to revert local changes for deployments. (I'd used svn revert
for this in old skool SVN days.)
And im using git reset --hard HEAD
for this. (Also git fetch
and git merge origin/$branch --no-ff
for syncronizing with upstream branch.)
But some articles points git checkout -f
for reverting changes.
What's key differences between this commands. Which way is the recommended?
回答
The two of them have the exact same effect. I recommend you to choose the solution you're the more comfortable with.
But if in this particular case the effect is the same, with different values it would be completely different. Basically (there is more, see linked topics) with a reset you move the current branch and the HEAD to a specific commit but with a checkout, you only move the HEAD . For more details see below.
Resources:
On the same topic:
- Is there a difference between git reset --hard HEAD and git checkout .?
- Is there a difference between “git reset --hard hash” and “git checkout hash”?
- Can you explain to me git reset in plain english?
Is there a difference between git reset --hard HEAD and git checkout .?
问题
If I make changes to the working tree and have not yet committed, and I would like to revert the changes I have made, is there a difference between
git reset --hard HEAD
and
git checkout .
?
回答
git checkout -- .
will obviously only work on the current directory (and subdirectories thereof), git reset --hard
will operate on the complete working tree.
git checkout -- .
will only update the working tree and leave already staged files as is, whereas git reset --hard
will match index and working tree with the HEAD commit.
when used with a refspec:
reset
will set the current branch head to the given commit (and matches index and working tree)checkout
will switch to that branch, leaving local changes intact, when they touch files which did not change between the current branch and the branch to be checked out
In plain English, what does “git reset” do?
回答2
Remember that in git
you have:
- the
HEAD
pointer, which tells you what commit you're working on - the working tree, which represents the state of the files on your system
- the staging area (also called the index), which "stages" changes so that they can later be committed together
Please include detailed explanations about:
--hard
,--soft
and--merge
;
In increasing order of dangerous-ness:
--soft
movesHEAD
but doesn't touch the staging area or the working tree.--mixed
movesHEAD
and updates the staging area, but not the working tree.--merge
movesHEAD
, resets the staging area, and tries to move all the changes in your working tree into the new working tree.--hard
movesHEAD
and adjusts your staging area and working tree to the newHEAD
, throwing away everything.
concrete use cases and workflows;
- Use
--soft
when you want to move to another commit and patch things up without "losing your place". It's pretty rare that you need this.
--
# git reset --soft example
touch foo // Add a file, make some changes.
git add foo //
git commit -m "bad commit message" // Commit... D'oh, that was a mistake!
git reset --soft HEAD^ // Go back one commit and fix things.
git commit -m "good commit" // There, now it's right.
--
-
Use
--mixed
(which is the default) when you want to see what things look like at another commit, but you don't want to lose any changes you already have. -
Use
--merge
when you want to move to a new spot but incorporate the changes you already have into that the working tree. -
Use
--hard
to wipe everything out and start a fresh slate at the new commit.