I have realized that I have committed stuff into my branch that's bad and I want to revert to an earlier commit. I have confirmed that git checkout 8dd018c
brings me to an earlier commit to which I want to revert HEAD to now, I tried the following:
git checkout 8dd018c
git status
HEAD detached at 8dd018c
nothing to commit, working directory clean
git reset --hard 8dd018c
git push origin HEAD:<my_branch>
but got:
! [rejected] HEAD -> my_branch (non-fast-forward)
error: failed to push some refs to 'https://github.com/my/repository.git'
hint: Updates were rejected because a pushed branch tip is behind its remote
hint: counterpart. Check out this branch and integrate the remote changes
hint: (e.g. 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
How do I do this correctly? I'm not the only one working on this repository so I think push -f
is out of the question, is it?
so I think
push -f
is out of the question, is it?
It doesn't matter whether it's out of the question. It is impossible to do what you're trying to do without using force, because you are asking the remote to throw away its references to all the commits after 8dd018c
, and it will not do that willingly.
However, take comfort, because:
No one else depends on this branch; it's yours.
You can push --force-with-lease
, which means, "Please do as I'm telling you to do, but only as long as it is safe" (safe in the sense that no one else has pushed to your branch, which, as it is yours, is pretty well guaranteed).
You could solve the whole problem with no force, just by giving up on this branch entirely. After all, it is only a name. So start a new branch with a different name at 8dd018c
, and push that branch. The remote will happily let you do that. Of course, you would also like to delete the old branch, and again, that will require you to use force in one form or another.
You could solve the whole problem with no force, with a revert
commit. Instead of removing commits, you add a new commit that makes your code go backwards to the same state it was when you were at 8dd018c
. I think that's my favorite solution, actually. Sure, the bad code stays in the commits you already pushed, but who cares? People do make mistakes.
Basically, if you're going to push a branch to a shared remote, you're going to run into this sort of issue and you need to reconcile yourself to it. I personally am very fond of rewriting my branch's history before I push it, and that means I don't want to push it until I'm well and truly finished with it. If I'm concerned that my computer might be hit by a bus, I can make a backup, or I can even add a second remote and push the branch to that instead. Other folks are more cavalier about pushing their branch to the shared remote and changing its history with force
. This is the kind of thing you should talk over with your team.