1

How do I uncommit last merge on a protected branch?

git reset --hard HEAD~1

git push -f origin master

I did the following after noticing that the last merge had a UI bug on production, but not local environment.

$ git push -f origin master
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
remote: error: GH006: Protected branch update failed for refs/heads/master.
remote: error: Cannot force-push to this protected branch
To https://github.com/Ivory/Web.git
 ! [remote rejected]     master -> master (protected branch hook declined)
error: failed to push some refs to 'https://github.com/Ivory/Web.git'

However, I can't do a force-push, is there a way to uncommit the changes?

SwissCodeMen
  • 4,222
  • 8
  • 24
  • 34
Sayaman
  • 1,145
  • 4
  • 14
  • 35
  • Reverting the commit (using `git revert`) could work as it creates a new commit reverting the changes. However, I don't know how it deals with merge commits. – dan1st May 26 '21 at 19:28
  • 2
    Either you unprotect the branch temporarily or you push a commit that reverts the changes made by the merge. – Gaël J May 26 '21 at 19:31
  • How can you push a commit that reverts the changes fast without having to do it manually? – Sayaman May 26 '21 at 19:58
  • 3
    Does this answer your question? [How do I revert a Git repository to a previous commit?](https://stackoverflow.com/questions/4114095/how-do-i-revert-a-git-repository-to-a-previous-commit) – matt May 26 '21 at 20:05
  • What do you mean by "fast"? What do you mean by "manually"? – IMSoP May 26 '21 at 20:31
  • @matt I think this question is more about the protected branch than how to do the reset or revert. – TTT May 26 '21 at 20:45
  • @IMSoP my interpretation of "(not) fast" and "manually" is, if you don't know about the `revert` command, then you might think you have to manually copy the old version of the files back in place, and commit that. – TTT May 26 '21 at 21:00
  • @TTT agreed but the proposed duplicate lists all the possibilities. – matt May 26 '21 at 21:26
  • @matt - I guess it's a very subtle difference, "How can I fix this for a protected branch" vs "I need to revert, how do I do that"? So I'd say, different question, same answer. It's almost as if it wasn't a dup until you suggested it was. So technically, "Does this answer your question? A: It does *now*, yes." ;) – TTT May 26 '21 at 22:19

2 Answers2

0

There are different levels of protected branches. I can't tell if in your case the protection requires a PR to merge into master, or if you can push new commits, but just can't force push. Unless you can get someone to temporarily disable the protection or enable you to temporarily force push, then you're going to need to revert the merge:

git fetch # update your branches
git checkout master 
git reset --hard @{u} # make your copy of master look like origin/master
git log # copy the merge commit ID that you want to revert (press q to exit)
git revert -m 1 <commit-id-to-revert>
git log # View the log message of your new commit and verify that it is correct
# verify your code looks correct (obviously)
git push

If the push works, then your "protection" is just preventing force pushes. If it still fails, create a new branch and PR it into master:

git checkout -b fixup-bad-merge # or whatever you want to call this branch
git push
# now create your PR into master and do what needs to be done to complete it
TTT
  • 22,611
  • 8
  • 63
  • 69
0

As other users said in the comments, you have two options:

  1. Unprotect your branch, which I guess it is not an option, otherwise you would not have posted the question
  2. git revert the changes brought in by the merged branch

To make it simple (for now), this is probably the command you need to run:

git revert -m 2 HEAD

where HEAD references the merge commit and -m 2 just means that you want to revert the changes introduced by the second parent. However, when reverting a merge commit, you should be aware that

Reverting a merge commit declares that you will never want the tree changes brought in by the merge. As a result, later merges will only bring in tree changes introduced by commits that are not ancestors of the previously reverted merge. This may or may not be what you want.

From git revert documentation

Basically, after you revert a merge commit, you are only undoing changes, but the history still sees the commits coming from the "reverted branch" as ancestors of the mainline. So, if in the future you want to merge that branch again, even after patching with a new commit in that same branch the bugs found, you won't see the changes brought in by commits belonging to the reverted parent of the merge commit. The solution in this case is to git revert the reverted commit.

I know, it sounds a little complicated without some pictures, Linus Torvalds explained it a lot better than me here.

Marco Luzzara
  • 5,540
  • 3
  • 16
  • 42