16

I have a Git/Gitlab repository. We used to commit straight to master, but we decided to switch to using feature branches like the rest of the world for this release.

We need to reset our remote master to the state it was in immediately after the last release. If someone has already committed to the master directly, how can I reset it to a clean state, removing all history past the last release?

I've spent about an hour googling now and can't find an answer to this specific question. Sorry if it seems redundant, it seems like such a simple task with no obvious answer!

Jonathan S. Fisher
  • 8,189
  • 6
  • 46
  • 84
  • [Force-updating a public repository is usually a bad idea.](http://blog.sensible.io/2012/10/09/git-to-force-put-or-not-to-force-push.html) If the reason behind it is just a policy change, why not leave the master branch where it is and let it catch up at the next release? – user3426575 Mar 26 '14 at 22:30
  • Possible duplicate of [Undo several commits in git which have not pushed to remote](http://stackoverflow.com/questions/16820861/undo-several-commits-in-git-which-have-not-pushed-to-remote) and [How to undo the last Git commit?](http://stackoverflow.com/questions/927358/how-to-undo-the-last-git-commit). –  Mar 26 '14 at 22:58
  • @user3426575 Fair question... because we have to. We started down a rather large release, and some fixes need to go into production before the large feature will be complete. If we would have done feature branches to start, we could have just cut an extra release and rebase the large feature. Instead, we have to backtrack to the last known working piece of code. – Jonathan S. Fisher Mar 27 '14 at 03:29

4 Answers4

39

To reset a local branch,

git branch -f master last-release

To reset a remote branch,

git push -f origin last-release:master

where last-release is the ref (commit id or branch) you want to reset master to.

(Neither of these affect your working tree; you can even do these from a bare repo, if you wish.)

Paul Draper
  • 78,542
  • 46
  • 206
  • 285
  • accepting this answer, probably the "right" way to do it – Jonathan S. Fisher Mar 27 '14 at 03:31
  • When using GitLab as a remote, this doesn't work for the master branch, nor for any other branch which is set as the default branch of the repository in GitLab. It doesn't work for master even if it's not set as the default branch. Tested with GitLab 7.9.0. – akaihola Jan 07 '16 at 12:43
  • @akaihola, this rewrites ("loses") history. Often, master or other important branches will have protections against force pushes. If that is the case, you will have to change the permissions, or else this is not possible. – Paul Draper Jan 07 '16 at 16:34
  • 3
    On GitLab, you may -temporarily- "unprotect" the master branch to allow this, as it is protected by default. It's on your project settings (the cog icon), then "Protected branches". https://gitlab.com/help/user/project/protected_branches – Wiil Oct 18 '16 at 02:56
6

Sometimes, you post on Stack Overflow and you immediately figure it out a second later:

$ git reset --hard HEAD~9
$ git push --all --force

Now delete your local repo, re-clone.

Jonathan S. Fisher
  • 8,189
  • 6
  • 46
  • 84
  • Be careful! This will delete any local commits you have been working on, and it will overwrite any other branches, not just `master`. That may be what works, but know that. – Paul Draper Mar 26 '14 at 22:25
  • @Paul Draper: it won't *delete* anything. Everything will still be available in the reflog for some time (at least 2 weeks by default). – zerkms Mar 26 '14 at 22:27
  • I cloned a separate copy of the repo before doing anything in case we screw up – Jonathan S. Fisher Mar 26 '14 at 22:29
  • @exabrial why did you pass the `--all` flag when all you want to do is to reset the `master` branch? –  Mar 26 '14 at 22:56
  • @zerkms, you are correct. Immediately, it will not delete anything. (Hopefully, if someone does make a mistake, they realize it quickly.) – Paul Draper Mar 27 '14 at 05:29
0

Follow the below steps by checkout out specific commit and push the new branch and remove the branch protection rule and force push new branch into master and add back the branch protection rule which you deleted.

git log --online (to get the commit hash that you wish to revert) 
git checkout <commit-hash>
git branch <new-branch-name> <new-commit-hash> 
git push origin <new-branch-name>

# Goto Github and remove branch protection rule (for master)
git push -f origin <new-branch-name>:master

# Go back to Github and add back the branch protection rule (for master/main)

  • 1
    The above steps work only if you want to delete a series of the latest commits pushed by mistake (For Eg. during hot-fix or release or any commits by mistake into master/main) – Mohammed Maaz Oct 20 '22 at 20:25
0

For remote repo

git push -f origin <last-release-number>:<branch_name>

For local repo

git reset --hard <last-release-number>

"last-release-number" must be the last commit you want to go back to