12

Let's say I have this:

hg clone public_repo my_repo
touch a b c d
hg add .
hg commit -m a a
hg commit -m b b
hg commit -m c c
hg commit -m d d
hg push
# let's say revX is the revision that added a 
hg strip revX

In my repository's history, the commits are gone. However, if I try to do a push after the strip, it tells me no changes found. Can the strip be applied to the public repo?

EDIT: the question is just hypothetical :). I am not in this situation, I just thought it would be interesting to find out how this works.

Helgi
  • 5,428
  • 1
  • 31
  • 48
Geo
  • 93,257
  • 117
  • 344
  • 520

5 Answers5

10

You need to run hg strip there. If it's bitbucket repo, you can do it from the admin panel. If not, SSH.

Cat Plus Plus
  • 125,936
  • 27
  • 200
  • 224
  • Thanks for this. I just spent half an hour trying to find out how to strip a changeset I had already pushed to bitbucket. This snippet of information is not well publicised, being buried under all the "no you don't want to do that, the safe way is ..." answers. – Chris F Carroll Sep 27 '13 at 15:51
9

This is not possible. You have to strip the public repo as well.

hg strip just takes away changesets. It does not perform an "adding" operation which could be pushed.

In the exact example you provide, you could just hg rollback on the public repo.

glglgl
  • 89,107
  • 13
  • 149
  • 217
  • Thank you! I know about `rollback`. So, a solution would be to run the strip on the public repo, and on every clone? – Geo Aug 09 '11 at 17:22
  • Yes, this would be the way to go. Or better, *a* way to go. What Idan K. says is correct as well - if it is a "normal mistake", better backout; if it was a "no go" such as including confidential data, strip/rollback is the only way. – glglgl Aug 09 '11 at 18:37
8

Let me pretend you're asking a slightly different question: I've stripped part of my repository history, how do I propagate this change to other dev's repositories?

Mercurial offers no way of propagating stripping in the same way it propagates adding changesets. So you have to come up with your own way.

Bitbucket, for example, has an updates list (on the repo summary page, if my memory serves me well). If you do a strip, Bitbucket displays there something like this:

Changeset 12345abcdef was stripped from the repository, please run hg strip 12345abcdef locally.

When we had to propagate stripping of part of an old branch in our shop, here's what we did:

  1. Stripped the changesets on the server.
  2. Created a batch file named strip.bat on the default branch of the repo containing the command we'd run on the server, i.e. hg strip 1234567890.
  3. Told everybody that whenever they cannot push because “push creates new remote heads” for no apparent reason, this means they should run strip.bat.

In case we ever need to strip something again, we just add another hg strip in the batch file.

P.S. Yes it's better not to strip, e.g. use backout to commit inverse changesets. Sometimes that's not an option: if you mistakenly merged branch a into branch b when you wanted the merge b into a, you're trapped. Even if you backout the merge changeset on feature, the merged changesets from a are already marked as merged, and you'll have a hard time doing another merge of these branches.

Community
  • 1
  • 1
Helgi
  • 5,428
  • 1
  • 31
  • 48
2

The correct and safe way to remove unwanted changes that made it to the wild is to hg backout them.

Idan K
  • 20,443
  • 10
  • 63
  • 83
0

Sometimes it is not possible to strip or backout a change, for example if it was a merge revision and you don't have admin access to the server. One method that does work is to branch the last good revision and then close the bad head.

  1. hg up badrev^ (Go to the revision before the bad one)
  2. touch dummy && hg add dummy && hg ci -m 'dummy' && hg rm dummy && hg ci --amend -m 'Fix accidental merge' (Create a second head with no changes from the good revision)
  3. hg up badrev (Go to the bad revision)
  4. hg ci --close-branch -m 'Close bad head' (Close the bad head)
  5. hg push
Luke Worth
  • 570
  • 3
  • 18