Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mercurial Remove History

Tags:

mercurial

Is there a way in mercurial to remove old changesets from a database? I have a repository that is 60GB and that makes it pretty painful to do a clone. I would like to trim off everything before a certain date and put the huge database away to collect dust.

like image 730
Jake Pearson Avatar asked Apr 21 '10 16:04

Jake Pearson


People also ask

How do I delete a file in Mercurial?

Once you decide that a file no longer belongs in your repository, use the hg remove command. This deletes the file, and tells Mercurial to stop tracking it (which will occur at the next commit). A removed file is represented in the output of hg status with a “ R ”.

What does hg amend do?

The --amend flag can be used to amend the parent of the working directory with a new commit that contains the changes in the parent in addition to those currently reported by hg status, if there are any. The old commit is stored in a backup bundle in .

How can I delete last commit in Mercurial?

If you are still in the draft phase (not pushed elsewhere yet), use the built-in extension hg strip <rev> command. Otherwise, you should do a hg backout , which will reverse the changeset. In case you still need the commit you made, I suggest you export it to import it again in the correct branch, before stripping.

How do I delete a branch in Mercurial?

You cannot. You can close the branch to hide it from the list of active branches, but you cannot completely delete it. This happens because in mercurial and in git the "branch" term means different things. In mercurial - it is a set of changesets.


2 Answers

There is no simple / recommended way of doing this directly to an existing repository.

You can however "convert" your mercurial repo to a new mercurial repo and choose a revision from where to include the history onwards via the convert.hg.startrev option

hg convert --config convert.hg.startrev=1234 <source-repository> <new-repository-name> 

The new repo will contain everything from the original repo minus the history previous to the starting revision.

Caveat: The new repo will have completely new changeset IDs, i.e. it is in no way related to the original repo. After creating the new repo every developer has to clone the new repo and delete their clones from the original repo.

I used this to cleanup old repos used internally within our company - combined with the --filemap option to remove unwanted files too.

like image 143
Gerd Klima Avatar answered Sep 25 '22 23:09

Gerd Klima


You can do it, but in doing so you invalidate all the clones out there, so it's generally not wise to do unless you're working entirely alone.

Every changeset in mercurial is uniquely identified by a hashcode, which is a combination of (among other things) the source code changes, metadata, and the hashes of its one or two parents. Those parents need to exist in the repo all the way back to the start of the project. (Not having that restriction would be having shallow-clones, which aren't available (yet)).

If you're okay with changing the hashes of the newer changesets (which again breaks all the clones out there in the wild) you can do so with the commands;

hg export -o 'changeset-%r.patch' 400:tip   # changesets 400 through the end for example cd /elsewhere hg init newrepo cd newrepo hg import /path/to/the/patches/*.patch 

You'll probably have to do a little work to handle merge changesets, but that's the general idea.

One could also do it using hg convert with type hg as both the source and the destination types, and using a splicemap, but that's probably more involved yet.

The larger question is, how do you type up 60GB of source code, or were you adding generated files against all advice. :)

like image 45
Ry4an Brase Avatar answered Sep 22 '22 23:09

Ry4an Brase