0

I know this question has been asked many times. But my scenario is different. I am having two branches, master and development. I never touch master branch, but mistakenly i push the entire data on master. I was on my development branch when I run following command.

git push origin development:master

My entire commits of development are pushed on master with the above command. The command is having "colon" in it, which possibly replaced my code.

According to this article Ref: Why Git use the colon (:<branch>) to delete remote branch, it replaces the code.

How can I revert this?

Community
  • 1
  • 1
rank
  • 83
  • 7
  • Note that `git push origin development:master` is a **fast-forward merge**. **It does not replace code**. It would only overwrite code if you force pushed with `-f`. –  Jul 07 '14 at 04:49

3 Answers3

2

git push -f origin master:master

Rui Chen
  • 56
  • 4
  • 1
    Note that this is a force push, which will overwrite the remote branch. If other people pushed new work, you'll end up deleting it on the remote, but in this situation that new work is kind of invalid anyways, since it's based off a dev branch that wasn't supposed to be pushed yet. –  Jul 07 '14 at 04:48
2

This command that you used,

git push origin development:master

updates the master branch on the remote with the development branch locally, or in other words, it does a fast-forward merge of development into the master branch on the remote.

It does not "replace" work on the master branch, since it's not a force push with the --force or the -f options.

Solution

You can attempt to force push the master branch to the remote. Note that if another user has already pushed additional work onto the master branch since you fast-forwarded it to the development branch, than that user's work will be over-written by your force-push. However, if that work is based on the development branch instead of master, then it's already sort of invalid, in my opinion.

You can force push using

git push origin master -f

If you feel that you have to be extra safe when force-pushing so as to not over-write someone else's push, then you can use the --force-with-lease (since Git version 1.8.5?)

git push origin master --force-with-lease

That will only force-push to the remote if the master branch is still in the same state that it was when you did your last push (the expected state, based on your local remote-tracking branch). Note that if you alter your remote-tracking branch with git fetch, then you'll need to pass additional (documented) options to --force-with-lease in order to do this correctly.

If someone happens to have pushed new work before this, then the master branch won't be in the "expected state", and the force-push will be rejected, as a safety feature.

Of course, if someone already fetched your accidentally pushed commits into their local repo, then they might still need to rebase their new work when you force push, if they based their new work on the accidental commits.

Alternative solution

Instead of force-pushing the master branch's previous state, you can choose to revert the commits instead, in case you cannot force-push the master branch (for example, if you simply cannot overwrite new commits pushed onto master, even though development was merged in by accident). However, once you are ready to actually merge in the development branch, you'll need to revert the changes made by your last revert, in order to restore the full changes of the development branch in master.

I will not go into the details of this solution here, because it's well documented at

Community
  • 1
  • 1
1

Your question's title is a bit misleading, so here's how to undo the most recent merge commit that you don't particularly care for, should someone stumble upon this via The Googles. Check out this commit:

If I had just made this merge and I wanted to revert it, the thing I need to know is that the two "heads" (timelines that I have combined) listed above, always starts with the original - the order is, "mine, theirs".

So, to make it go away, the command I want to run is:

git reset 05ace60

which will reset my branch to the timeline it was right before this merge. If you use this on old merges, you will definitely lose commits though, only use this on an unpushed merge you just made that you want to undo. (in a pinch, you can do that reset, then git push -f origin master, but you're in immediate danger of angering your coworkers should you do this incorrectly).

Community
  • 1
  • 1
Ana Betts
  • 73,868
  • 16
  • 141
  • 209
  • Rather than creating this answer because of the title, I would have just edited the title to be clearer. There's already a question for [Undo a Git merge?](http://stackoverflow.com/questions/2389361/undo-a-git-merge). –  Jul 07 '14 at 04:46
  • There's also [Undo the last Git commit?](http://stackoverflow.com/q/927358/456814) and [Revert to a previous Git commit](http://stackoverflow.com/q/4114095/456814). –  Jul 07 '14 at 04:53
  • Also note that if a user accidentally pushes something that they weren't supposed to, `--force-with-lease` is *a little* safer than just `-f`, since the force-push will be rejected if the remote branch is not in the same "expected" state (e.g. someone pushes new commits), though any coworkers who fetched the accidental commit(s) might still have to redo (or rebase) their work in case of an accepted force-push. –  Jul 07 '14 at 05:27