As far as I understand, git actually always keeps your changes. It is just the pointers that can be overridden if you force an update. For instance,
git reflog show origin/master
shows even remote forced-updates. So although it looked like the commit was lost, it was still there, just not immediately visible, and was fully recoverable.