Which checkout options to use depends on which version of git you want to pretend you called. Older versions do a forced checkout, but that's destructive in edge cases. Newer versions will refuse to update if there are local changes to files that exist in the target commit (which are all files, by definition), which is roughly what they do on a fast-forward merge; though the error message is slightly different, suggesting that the code paths aren't quite the same.