336

I reset my local master to a commit by this command:

git reset --hard e3f1e37

when I enter $ git status command, terminal says:

# On branch master
# Your branch is behind 'origin/master' by 7 commits, and can be fast-forwarded.

#   (use "git pull" to update your local branch)
#
nothing to commit, working directory clean

Since I want to reset origin/header as well, I checkout to origin/master:

$ git checkout origin/master
Note: checking out 'origin/master'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

HEAD is now at 2aef1de... master problem fixed for master. its okay now.

and reset the header by this command:

$ git reset --hard e3f1e37
HEAD is now at e3f1e37 development version code incremented for new build.

Then I tried to add commit to origin/header that I was not successful.

$ git commit -m "Reverting to the state of the project at e3f1e37"
# HEAD detached from origin/master
nothing to commit, working directory clean

Finally, I checkout to my local master.

$ git checkout master
Switched to branch 'master'
Your branch is behind 'origin/master' by 7 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)

Since, I reset the head of origin/master I expect local and origin should be in same direction but as you see, git is saying that my local/master is behind origin/master by 7 commits.

How can I fix this issue? The things that I'm looking for is Head of local/master and origin/master point to same commit. Following image shows what I did. Thanks.

enter image description here

Hesam
  • 52,260
  • 74
  • 224
  • 365
  • First of all, make sure you are allowed to force push code to a protected branch on your project, otherwise you won't be able... – DarmVillegas Dec 27 '18 at 09:58

6 Answers6

724

origin/xxx branches are always pointer to a remote. You cannot check them out as they're not pointer to your local repository (you only checkout the commit. That's why you won't see the name written in the command line interface branch marker, only the commit hash).

What you need to do to update the remote is to force push your local changes to master:

git checkout master
git reset --hard e3f1e37
git push --force origin master
# Then to prove it (it won't print any diff)
git diff master..origin/master
Simon Boudrias
  • 42,953
  • 16
  • 99
  • 134
  • 14
    that does the requested operation, but keep in mind that it will make unhappy those people who already pulled the commits from master. – mnagel Jul 16 '13 at 06:13
  • I followed this steps and it rolled back. But the origin/HEAD is now pointing to a branch other than master. What can I do to fix this? – Daniil Shevelev Dec 20 '13 at 20:29
  • 1
    You shouldn't care about origin/HEAD, simply push the good ref to origin/ref – Simon Boudrias Dec 20 '13 at 20:53
  • 1
    Agreed, had to do this today after accidentally merging the wrong branches together then pushing to origin. It works well, but it could be *very* disruptive if other people have been checking out the affected branches from origin. Use with caution. – Nick W. May 09 '14 at 01:05
  • 1
    Doesn't work. `remote: error: denying non-fast-forward refs/heads/master (you should pull first)` – m0skit0 Jan 16 '15 at 10:36
  • 1
    @m0skit0 It does work. It is your git server who's doing custom magic with git-hooks. This mean you won't be able to reset origin/master. Your only option is to revert changes in a new commit. – Simon Boudrias Jan 17 '15 at 00:11
  • Erm... No, it doesn't work. I cannot revert all changes because then it says there's a merge. And if I use -m I got the message posted. `git push origin :master`, reverting to commit I want origin to have and pusing it, did work though. – m0skit0 Jan 17 '15 at 17:21
  • @m0skit0 reverting in git words mean creating a new commit on top of a branch changing back the chances introduced in an older commit. So it doesn't change the history of a branch. You can also just ask the person in charge of your git server to re-allow non-fast-forward commits. – Simon Boudrias Jan 19 '15 at 05:01
  • Yes, I know. In this case I don't mind losing the history because all commits are in fact a merge from another branch. I am in charge of the git server and I don't want to allow non-fast-forward commits. – m0skit0 Jan 19 '15 at 11:16
  • After doing this, I have two tagged commits ahead of where I reset master to, which didn't go away. How do I delete those entries? – BadHorsie Oct 22 '15 at 17:29
  • On my machine, it appears to blow away the actual previous pushes you were undoing. For example, after doing the forced push, all future entries in git log are no longer there, so I see no way of recovering the code changes that were undone. – entpnerd Aug 16 '16 at 17:43
  • @entpnerd check `git reflog` to find the commits you deleted. – Simon Boudrias Aug 16 '16 at 18:59
  • @SimonBoudrias when I execute `git reflog` I only see the commits before the reset point in addition to the reset and rebases that were performed by the git reset command. Also, when I check SourceTree, I don't see the commit ID of the pushes to the origin that happened after the reset point. It's like they never happened. That being said, your solution does correctly reset the origin. From my point of view, I just don't the retention of reseted commits, but it did work. :-) – entpnerd Aug 16 '16 at 19:59
  • NOTE: you lose your local commits – Sean Malter Jul 29 '19 at 23:40
  • @SeanMalter commits are never lost. Although it may be that they are no longer in the ancestor hierarchy. – Max MacLeod Mar 09 '20 at 11:11
  • It may be easier if you manually delete that branch from origin, before pushing the edited branch. – Thiago Nov 29 '21 at 12:34
  • http://davidbits.blogspot.com/2022/11/git-reset-or-revert-pushed-commits-on.html – jpulikkottil Nov 08 '22 at 05:14
  • same commands can be done via Git Extensions, reset to commit and push – lyolikaa Jul 07 '23 at 07:47
75

The solution found here helped us to update master to a previous commit that had already been pushed:

git checkout master
git reset --hard e3f1e37
git push --force origin e3f1e37:master

The key difference from the accepted answer is the commit hash "e3f1e37:" before master in the push command.

jkovacs
  • 751
  • 5
  • 2
  • 1
    Doesn't work: `remote: error: denying non-fast-forward refs/heads/master (you should pull first)` – m0skit0 Jan 16 '15 at 10:37
  • @m0skit0 as the message say's `you should pull first` :) – intuitivepixel Mar 16 '15 at 19:50
  • The answer to this is at http://stackoverflow.com/a/10544328/1019307 - `git config receive.denynonfastforwards false` but actually I set that manually in my local git repository I have in `/opt/git` that I created to play with the ideas here. I'm not sure how or if can do this for bitbucket, github etc... And @intuitivepixel that is pointless as it reverse what you were trying to achieve with the hard reset. – HankCa Jul 18 '15 at 13:30
  • Hi @jkovacs, I don't want new changes in master to be removed. I just want to push that commit hash "e3f1e37" to origin master. Is it possible by skipping the 2nd command git reset --hard "e3f1e37"? – KarenAnne Aug 17 '15 at 03:34
  • Hi @jkovacs, I just confirmed that I can skip the 2nd step. :) – KarenAnne Aug 17 '15 at 03:45
  • This is the way to do it if you seriously fubar'd your branch, you just want it back to a workable state, and nobody else is working on it remotely. – Keith Pickering Aug 27 '21 at 14:41
15

Assuming that your branch is called master both here and remotely, and that your remote is called origin you could do:

git reset --hard <commit-hash>
git push -f origin master

However, you should avoid doing this if anyone else is working with your remote repository and has pulled your changes. In that case, it would be better to revert the commits that you don't want, then push as normal.

Mahmoud Zaher
  • 559
  • 6
  • 6
1

Since I had a similar situation, I thought I'd share my situation and how these answers helped me (thanks everyone).

So I decided to work locally by amending my last commit every time I wanted to save my progress on the main branch (I know, I should've branched out, committed on that, kept pushing and later merge back to master).

One late night, in paranoid fear of loosing my progress to hardware failure or something out of the ether, I decided to push master to origin. Later I kept amending my local master branch and when I decided it's time to push again, I was faced with different master branches and found out I can't amend origin/upstream (duh!) like I can local development branches.

So I didn't checkout master locally because I already was after a commit. Master was unchanged. I didn't even need to reset --hard, my current commit was OK.

I just forced push to origin, without even specifying what commit I wanted to force on master since in this case it's whatever HEAD is at. Checked git diff master..origin/master so there weren't any differences and that's it. All fixed. Thanks! (I know, I'm a git newbie, please forgive!).

So if you're already OK with your master branch locally, just:

git push --force origin master
git diff master..origin/master
Paul-Sebastian Manole
  • 2,538
  • 1
  • 32
  • 33
1

Here are my suggestions. However, the above answer by Simon Boudrias is also great.

Check out the branch

git checkout master

Soft reset, which means these changes will become un-committed

git reset --soft HEAD~1

Manually delete the branch from origin if not master

Fix your code, or Stack it.

Then, make a new commit with a description of what happened otherwise

git push -f origin master 
Thiago
  • 12,778
  • 14
  • 93
  • 110
-2

Step 1. Reset Branch to specific HEAD. Step 2. Push forcefully changes to your remote branch.

 git reset --hard e3f1e37 /   git reset --hard origin/master
 git push --force origin "Branch name"

Done. Now check your remote branch with reset to the previous commit