Can't Push After git reset --soft HEAD^
Asked Answered
R

4

15

Just now I committed and pushed something (yes, my mistake on the push) that I decided I should 'revert' or 'undo'. So I was told to issue git reset --soft HEAD^ on my end, and I figured this would somehow create a 'revert' commit that once committed would make it as if the change never happened. I don't mind if the history of the change is there at all, that's just what I imagined would happened.

Anyways, after having done that I committed again, and then when I tried to push I got the non-fast-forward error. Now, I know I screwed something up with the reset, something along the lines of my tree and origin tree are 'mismatched' now, but I am wondering how to fix this. Now I just want to go back to the time before I issued the reset, so that I can just manually revert the changes by taking them out manually and then committing, unless someone else can recommend the correct way of reverting a pushed commit, and by this I don't mean that the history has to be gone from the log or anything.

Redo answered 6/1, 2010 at 21:51 Comment(0)
N
8

If I understand your problem correctly you could try the following:

(I'm assuming this is your 'master' branch and you are pushing to 'origin')

Sync up with your remote to get to the same state.

git remote update
git checkout master
git merge origin/master

Now revert your commit

git revert HEAD (or where ever the commit you want to revert is now)
git commit -av

Sync up with your remote

git push
Nedanedda answered 6/1, 2010 at 22:5 Comment(0)
C
17

Although my answer is beyond what you are asking, I think it is actually what you are intending to do.

You used git reset --soft HEAD^ to undo the commit you made. This returns the working copy to the state before your commit (since HEAD points to your current commit, and HEAD^ points to the one before it (assuming there is only one parent).

But now when you git push you are told something like:

 ! [rejected]            <branch> -> <branch>e (non-fast-forward)
error: failed to push some refs to 'ssh://<remote server>/<remote path>'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

This is saying that the commits don't line up and it is there to prevent you from making a mistake. The error message is a bit misleading and you don't want to do what it suggests (a pull to get your branch in sync). You can only know NOT to do this because of your intentions.

You can simply get around this with a --force (or -f) (*):

git push --force

You may need to set the upstream again:

git push --force --set-upstream origin <branch>

Be aware that this will have consequences if others have already pulled your work, since there will be different commits that will be making the same changes (possibly). See https://www.kernel.org/pub/software/scm/git/docs/user-manual.html#problems-With-rewriting-history.

To prevent any problems, only ever do pushes to your branches (not some communal branch - for example the development branch the devs merge all their feature branches into) and be sure to have open communication in your team.

A developer would typically use this pattern for what I call Friday Afternoon commits where you want to save your work before the weekend in-case of hardware failure (but return to the pre-commit state on Monday).

*Friday*

git add --all  # To add all files whether they are tracked or not
git commit -m "Friday afternoon commit"
git --set-upstream push      # --set-upstream is for if the branch doesn't exist on the remote server

*Monday*

git reset --soft HEAD^
git push -f --set-upstream origin <branch>

The advantage of doing it this way, compared to a git revert discussed in another answer, is to avoid extra commits. The reset will have 2 commits and this way will have none (no extra ones). The advantage of git reset is that it will NOT rewrite history so is much safer, especially if you aren't sure of what you are doing.

(*) Typically repositories are configured to NOT let you do this to master - fix on a branch and create a pull request instead. For if you've read the above link, to rewrite history on master will have SERIOUS consequences (unless you are the only person who ever clones that code).

Chesterchesterfield answered 20/11, 2017 at 0:29 Comment(0)
N
8

If I understand your problem correctly you could try the following:

(I'm assuming this is your 'master' branch and you are pushing to 'origin')

Sync up with your remote to get to the same state.

git remote update
git checkout master
git merge origin/master

Now revert your commit

git revert HEAD (or where ever the commit you want to revert is now)
git commit -av

Sync up with your remote

git push
Nedanedda answered 6/1, 2010 at 22:5 Comment(0)
H
5

Now I just want to go back to the time before I issued the reset

If you only want to cancel the git reset --soft you just did, you can look up the former HEAD commit id in the reflogs

 $ git reflog
 $ git reset --soft formerCommit

And then you can prepare your git revert

Hyper answered 6/1, 2010 at 22:9 Comment(4)
Thanks, this is similar to what someone on IRC told me to do, but it's pretty confusing so I'm going to go with rnicholson's answer for documenting purposes.Glyptic
I wasn't familiar with git reflog. Very cool. Learned something new. This is probably a better solution as it condenses the first 3 steps of my answer to one command.Nedanedda
I also could not unsderstand, how this works, I thought that after $ git reset --soft formerCommit i will go back to the previous state, indeed the head points to the previous commit, but then when i treied to push new changes I am getting same error as in question as heads have diverged, so i dn t understadn whats the advantage of this?Hamster
@ArpanBanerjee Any reset which moves HEAD would result in a force push.Hyper
I
0

You wanted to use git revert HEAD to create a new commit that would undo the commit at HEAD. Instead you just moved HEAD back to the commit prior to the current HEAD.

Interjection answered 6/1, 2010 at 22:6 Comment(1)
Thanks, that makes sense, though this probably would've been better as a comment given that it doesn't really fix my problem. Thanks though.Glyptic

© 2022 - 2024 — McMap. All rights reserved.