I have read the documentation, however I am having a hard time understanding the difference between
git reset --merge
And
git reset --keep
Please provide a simple explaination and/or example.
I agree that the documentation is not very clear. From testing, I have found three differences, relating to what happens to files which:
In summary:
reset --merge
always discards the index (staged changes); aborts if unstaged and staged changes present on any filereset --keep
keeps, but unstages, the index; aborts if the reset target touches the same fileTest scenario:
echo First > file.txt
git add file.txt
git commit -m 'first'
git tag v1
echo Second >> file.txt
git commit -am 'second'
git tag v2
echo New > newfile.txt
git add newfile.txt
git commit -m 'third'
git tag v3
echo 'More stuff' >> file.txt
git add file.txt
We now have three commits, and 'file.txt' changes between v1 and v2, but does not change between commits v2 and v3.
In this situation:
git reset --merge v2
throws away those changesgit reset --keep v2
keeps them, but unstages them.If we instead try to reset to v1:
git reset --merge v1
throws away the changesgit reset --keep v1
refuses:
error: Entry 'file.txt' would be overwritten by merge. Cannot merge.
fatal: Could not reset index file to revision 'v1'.
git echo "Even more things" >> file.txt
Now, both fail, but with slightly different error messages:
git reset --merge v1
error: Entry 'file.txt' not uptodate. Cannot merge.
fatal: Could not reset index file to revision 'v1'.
git reset --keep v1
error: Entry 'file.txt' would be overwritten by merge. Cannot merge.
fatal: Could not reset index file to revision 'v1'.
echo Unrelated > unrelated.txt
git add unrelated.txt
echo Stuff >> unrelated.txt
Now this is somewhat odd:
git reset --merge v1
error: Entry 'unrelated.txt' not uptodate. Cannot merge.
fatal: Could not reset index file to revision 'v1'.
git reset --keep v1
Both sets of changes are kept, but unstaged.
For completeness, these both behave identically: the reset succeeds and the file remains unstaged.