For me git reflog was always a lifesaver when a complicated rebase or merge fails. You can always checkout previous SHA and then just return your HEAD to pre screw-up state. In case of remote repo that already ended up "broken" you can still force push to those branches, but others will have to discard theirs. Otherwise you never force push to anything shared.