21

As a junior git user, I got overwhelmed by a tough merge and must have done something wrong. I ended up committing my conflict resolutions with a whole mess of garbage inside my source files. The commit shows additions of many lines which look like <<<<<<< HEAD and >>>>>>> a7b4de79431c2e73d28621c72c8d14820df1a24b. The commit has been pushed to remote origin already so I unfortunately can't just ammend the commit.

I want to rewind the remote repository to the last good commit, 4a3ba7b0e56cf0be80274c1f879029220a889bde and (if possible) destroy the bad commit d004651972cbc35f70ee5a2145b6e03169c77279.

I tried:

git checkout 4a3ba7
git push -f

and got: fatal: You are not currently on a branch.

Jesse Hallam
  • 6,794
  • 8
  • 48
  • 70

3 Answers3

28

checkout moves your current working directory to a previous commit, but it does not modify branch contents. You need to reset the branch back to an old commit, and then push that.

git checkout ...
git reset --hard 4a3ba7
git push -f

that said, if you are already push -fing to change only the most recent commit, you should be able to use --amend.

git checkout ...
// Fix the file
git commit --amend
git push -f

If there are at least some changes that you want that were committed after 4a3ba7 then you can also do this:

git checkout ...
git reset 4a3ba7
git add -p
// Use the interactive prompt to choose the parts you want
git commit
git push -f

Update

Your error remote: error: denying non-fast-forward refs/heads/master is because the git server that you are using, Assembla, does not allow rewriting history by default. See this answer for fixing that part: Undo git push to Assembla

Community
  • 1
  • 1
loganfsmyth
  • 156,129
  • 30
  • 331
  • 251
  • `error: failed to push some refs to `...` Updates were rejected because the tip of your current branch is behind is remote counterpart. – Jesse Hallam Feb 18 '13 at 00:38
  • @Kivin Which commands did you run? Do you have other branches in the repo? As long as you have the `-f` in there, I wouldn't expect that. – loganfsmyth Feb 18 '13 at 00:41
  • Only branch is master on remote and local. I only ran the first codeblock in your answer: checkout master, reset --hard 4a3ba7, push -f. I'm currently getting the following back on stdout: http://pastebin.com/ZKR6gF7n – Jesse Hallam Feb 18 '13 at 00:47
  • @Kivin What is the server you are pushing to? It sounds like the server is set up to not allow rewriting history. If that is true, then you can just make a new commit that fixes the merge conflict, rather than trying to go back and remove it entirely from history. – loganfsmyth Feb 18 '13 at 00:49
  • I'm pushing to assembla.com. If I can't destroy the bad commit, can I rewrite its commit message to better reflect that its bad news? And how would I get my local repo in to a state where it matches `4a3` and I can commit? – Jesse Hallam Feb 18 '13 at 00:51
14

You don't need to checkout things locally to rewind a remote branch; you can just use

git push -f origin 4a3ba7b0:master

Of course double check your logs before doing anything, as this push will overwrite remote data.

If you receive permission errors, receive.denyNonFastForwards might be set to true in the remote repository; you have to change that for a rewind to work in any case.

Marco Leogrande
  • 8,050
  • 4
  • 30
  • 48
  • 5
    This is the better answer I think. You shouldn't be screwing around with your local copy when you are also rewriting remote history. – backus Feb 07 '16 at 05:57
3

You can do a

git reset --hard *commithash* 

but be warned: This can result in loss of modified data! (You have been warned :))

bssstudio
  • 174
  • 3
  • `error: failed to push some refs to `...` Updates were rejected because the tip of your current branch is behind is remote counterpart. – Jesse Hallam Feb 18 '13 at 00:37