14

I understand how to remove an entire changeset from history but it's not clear how to remove a subset instead.

For example, how do I remove all DLL files from an existing changeset while leaving the source-code alone?

Community
  • 1
  • 1
Gili
  • 86,244
  • 97
  • 390
  • 689

2 Answers2

18

Because the revision ids (e.g. a8d7641f...) are based on a hash of the changeset, it's not really possible to remove a subset of a changeset from history.

However, it is possible to create a new repo with a parallel history, except for a certain set of files, by using the Convert extension. You'll be converting a Mercurial repo to a Mercurial repo, using the filemap to exclude the files you don't want by adding excludes. This will create a new, unrelated repository, which means that any clones people have won't be able to pull from it any more, and will have to re-clone from this new repo.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
tghw
  • 25,208
  • 13
  • 70
  • 96
  • Is there no other way? Let's say your on a 100 person team. Someone accidentally checks in copyrighted material. Or maybe they check in some userdata by mistake as part of a test. Asking all the devs to re-clone seems like a non-starter but you need to get rid of the data. Is there no other option? – gman May 05 '11 at 05:31
  • 1
    No. With a team that large, one would hope that there is some kind of review process involved. – Ringding Oct 19 '11 at 06:29
13
  1. Make sure all your teammates have pushed their local changes to the central repo (if any)
  2. Backup your repository
  3. Create a "map.txt" file with the following content:
    # this filemap is used to exclude specific files
    exclude "subdir/filename1.ext"
    exclude "subdir/filename2.ext"
    exclude "subdir2"
  4. Run this command:
    hg convert --filemap map.txt c:/oldrepo c:/newrepo
    NOTE: You have to use "forward-slash" in paths, even on windows.
  5. Wait and be patient
  6. Now you have a new repo at c:\newrepo but without the files

PS. In the "upper" repo you have to remove all changesets and re-push your new repo.

PPS. I actually wrote a blog post about this that has more details (including stripping the changesest in Bitbucket etc.

Alex from Jitbit
  • 53,710
  • 19
  • 160
  • 149
  • 2
    As new team members are added, I suspect we'll probably do this once a year to keep the repo lean from all the noob commits. – Jeremy Smith Aug 28 '14 at 13:12
  • My cofounder has accidentally committed the entire PhoneGap library into the repo (18 megabytes), so I had to learn this the hard way, hehe – Alex from Jitbit Oct 11 '14 at 22:04
  • What about excluding all files of certain type? I tried `"exclude *.bak"` to exclude all backup files from all commits (I forgot to include them in .hgignore), didn't work. – sunny moon Mar 23 '16 at 18:56