Well, this is one area where BK and git differ a lot. BK didn't overload many things onto the same "reset" functionality, but had specific operations for specific cases.
Also BK would never leave a merge in the git kind of half-merged state, because BK refuses to have two branches open. Instead, BK had a special way of handling merges, which worked fine but quite frankly I have very little idea of how it worked (it was some kind of "shadow BK tree", it was called ".bk/RESOLVE/" or something like that - but because the tools were so nice, you never really had any reason to look into it, so I don't know what it did).
BK would never change the working tree itself until the merge was done, so you would never need to do what a plain "git reset --hard" (without any arguments) does.
In many ways the BK thing was very nice, although the git way is perhaps a bit more flexible (because git makes the intermediate tree visible you can easily edit the merge errors, and compile/test the result, before you decide to commit any manual merge).
I really do like the way git does merges now (especially after the last round of git-diff-tree fixes that allow comparing the different stages), but the BK way is in some ways cleaner and leaves less potential for confusion since it avoids ever exposing you to any half-merged state.
You may remember how I initially argued that we should always try to merge stuff outside of the normal working directory. And I still _like_ that approach, although I've since decided that I actually prefer the current git way is even better in practice.
But "git reset" is a lot more than the "revert to previous state". It _also_ does - without the error checking - what "bk fix" used to do (which is to undo the last commit, so that you can re-commit it), and it also does what "bk undo" used to do. It also does "bk unpull".
So "git reset" really does a whole lot of different and _mostly_ related things:
- undo any half-way changes (very similar to just "git checkout -f"), and
just reset to the state of the last successful commit (ie "current
HEAD"):
git reset --hard
BK didn't need this, although if you just want to remove your edits
(which "git reset --hard" also does), you could - like with git - just
do a "checkout" operation, of course.
- undo the last commit, but don't undo the working tree ("soft reset to
parent of head"). git reset HEAD^
I think this was "bk fix -C".
- undo the last commit entirely ("hard reset to previous state"): git reset --hard HEAD^
This was "bk undo"
- undo the last pull ("bk unpull"): "hard reset to ORIG_HEAD": git reset --hard ORIG_HEAD
This was "bk unpull".
where the last two are obviously just special cases of a generic "undo to arbitrary previous commit state".
BK in many ways had more hand-holding (which I think is good, and "git" to some degree has an unnecessarily "hard core" approach to these things).
For example, I think "bk undo" not only asked you about it, but it also only ever undid the last commit (and refused to undo a pull or merge). If you wanted to undo to some arbitrary state, you had to use the "-a" flag, iirc.
Of course, under BK the "undo" operation was final, so BK _had_ to be more careful. With git, if you undo to some arbitrary state, you can still "re-do" all your commits if you just find the old head (and git-fsck-objects will help you do that), so in that sense git doesn't _need_ to be as careful as BK was.
Linus