Delete all local changesets and revert to tree

39,916

Solution 1

When the simplest way (a new hg clone) isn't practical, I use hg strip:

% hg outgoing -l 1
% hg strip $rev # replace $rev with the revision number from outgoing

Repeat until hg outgoing stays quiet. Note that hg strip $rev obliterates $rev and all its descendants.

Note that you may have to first enable strip in your Mercurial settings.

PS: an even smarter approach is to use the revset language, and do:

% hg strip 'roots(outgoing())'

Solution 2

You'll want to make a local clone where you preserve only the changesets that are also present in the remote repository. Use TortoiseHg, hg log or similar to figure out which of your revisions is that lastest revision you didn't make (the one before the mess started). Using hg outgoing can help here -- it will list all the changesets you made -- pick a revision number earlier than any of those.

If the target revision is called good and your clone is called foo, then do:

hg clone -r good foo foo-clean

This will be a fast, local operation -- there is no reason to download everything again. The foo-clean clone will only contain changesets up to revision good. You can now replace foo-clean/.hg/hgrc with foo/.hg/hgrc in order to preserve your repository-local settings such as the default push/pull path.

When you are satisfied that foo-clean has everything you need from foo, then simply delete foo and rename foo-clean to foo. Do a hg pull to get any new changesets from the remote repository into your clone and continue like normal.


If nobody has pushed new changesets to the remote repository, then it is very simple to determine which revision you want to use as good above: hg id default will tell you the ID of the tip in the remote repository.

Solution 3

Ok. So just delete all the local stuff, hg init the new local repository and hg pull the latest tip you have. Don't forget to hg update after this.

Solution 4

You may use

hg strip revision

to kill any revision and its subtree in your local repository.

https://www.mercurial-scm.org/wiki/Strip

But don't try to use it for anything that has been already pushed.

Solution 5

Just delete everything you have on your local system and re-clone the remote repo.

Share:
39,916
Richard
Author by

Richard

Updated on December 18, 2020

Comments

  • Richard
    Richard over 3 years

    I'm using Mercurial and I've got into a terrible mess locally, with three heads. I can't push, and I just want to delete all my local changes and commits and start again with totally clean code and a clean history.

    In other words, I want to end up with (a) exactly the same code locally as exists in the tip of the remote branch and (b) no history of any local commits.

    I know hg update -C overwrites any local changes. But how do I delete any local commits?

    To be clear, I have no interest in preserving any of the work I've done locally. I just want the simplest way to revert back to a totally clean local checkout.

  • Richard
    Richard over 14 years
    Thanks. When you say 'delete all the local stuff', do you mean delete the entire repository, or just my changes? What does hg init do (have Googled but can't see a simple explanation) and do I need to use any flags with it? Will it delete things like my Mercurial .hgrc preferences?
  • Richard
    Richard over 14 years
    Update: if I delete everything in the project root directory, then type 'hg init', I get 'abort: repository . already exists!'. Do I need to set up and work from a new directory? I'd rather not if possible... surely there must a simple way to kill everything I've done locally?!
  • alemjerus
    alemjerus over 14 years
    Yes, delete everything including all the repository stuff. Start from a new clean folder. Your preferences you can save in backup file, and then restore them into the new repository you create with hg init reponame. Details on init and stuff: hgbook.red-bean.com/read/mercurial-in-daily-use.html
  • Martin Geisler
    Martin Geisler over 14 years
    alemjerus: hg init + hg pull = hg clone The difference is that hg clone makes a nice .hg/hgrc file for you and that hg clone will use hardlinks to save space when cloning on the same filesystem.
  • Martin Geisler
    Martin Geisler over 14 years
    Richard: The output of hg help init is here: selenic.com/mercurial/hg.1.html#init But maybe that is too terse? Please send a mail to our mailinglist if you need more help! See: mercurial.selenic.com/wiki/MailingLists
  • eswald
    eswald over 13 years
    Thank you! I ended up in a situation that this solved perfectly, with no fuss whatsoever.
  • Peteter
    Peteter over 13 years
    I'm having the same situation, but also have a lot of file in the repo directory but are in the hgignore. Can't install hg strip and would like to drop the local commits without replacing the whole clone. Any ideas? -- Ah! If I haven't added any files, I should be able to just copy the other clone into my old directory!?
  • David C
    David C almost 13 years
    This saved me from the large fixes above, very simple, thank you!
  • Yitz
    Yitz over 11 years
    Be careful with this method if you have multiple branches, though. Cloning up to a specified revision only gets the changesets on the branch of the specified revision. You may then have to hg pull -r for the last "good" revision of each additional branch.
  • jsea
    jsea about 9 years
    If anyone has problems getting hg strip 'roots(outgoing())' to work due to it not recognizing 'roots(outgoing())'. I was able to get it to work with hg strip "roots(outgoing())".
  • just somebody
    just somebody about 9 years
    @SombreErmine in cmd.exe, yes.
  • StayOnTarget
    StayOnTarget over 5 years
    This is a totally valid approach but for larger repositories won't be the fastest way to do it.
  • Mike Rosoft
    Mike Rosoft over 5 years
    You can use it on a public revision, but if you pull again, it will re-appear. (hg strip only works with the local repository.)