2

I have a project with 24 months of source control history in a Mercurial repository.

I've recently found some old tarballs of the project that predate source control, and i think they would be useful to import into the repository as "pre-historic" changesets.

Can i somehow add a parent to my initial commit?

Alternatively, is it possible to re-play my entire repository history on top of the tarballs, preserving all metadata (timestamps etc)?

Is it possible to have the new parent commits use the timestamps of these old tarballs?

mappu
  • 329
  • 2
  • 16
  • Possible duplicate of [Join two Mercurial repositories into one line of revisions](https://stackoverflow.com/questions/5859263/join-two-mercurial-repositories-into-one-line-of-revisions) – StayOnTarget Mar 01 '19 at 12:25

2 Answers2

8

You can use the convert extension to build a new repository where the tarballs are imported as revisions before your current root revision.

First, you import the tarballs based on the null revision:

$ hg update null
$ tar -xvzf backup-2010.tar.gz
$ hg addremove
$ hg commit -m 'Version from 2010'
$ rm -r *
$ tar -xvzf backup-2011.tar.gz
$ hg addremove
$ hg commit -m 'Version from 2011'

I'm using addremove above to give Mercurial a chance to detect renames between each tarball (look at the --similarity flag to fine-tune this and use hg rename --after by hand to help Mercurial further). Also, I remove all the files in the working copy before importing a new tarball: that way the next commit will contain exactly the snapshot present in the tarball you unpack.

After you've imported all the tarballs like above, you have a parallel history in your repository:

[c1] --- [c2] --- [c3] ... [cN]

[t1] --- [t2] --- [tM]

Your old commits are c1 to cN and the commits from the tarballs are t1 to tM. At the moment they share no history — it's as if you used hg pull -f to pull an unrelated repository into the current one.

The convert extension can now be used to do a Mercurial to Mercurial conversion where you rewrite the parent revision of c1 to be tM. Use the --splicemap flag for this. It needs a file with

<full changeset hash for c1> <full changeset hash for tM>

Use hg log --template '{node} ' -r c1 -r tM > splicemap to generate such a file. Then run

$ hg convert --splicemap splicemap . spliced

to generate a new repository spliced with the combined history. The repository is new, so you need to get everybody to re-clone it.

This technique is similar to using hg rebase as suggested by Kindread. The difference is that convert wont try to merge anything: it simply rewrites the parent pointer in c1 to be tM. Since there is no merging involved, this cannot fails with weird merge conflicts.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Martin Geisler
  • 72,968
  • 25
  • 171
  • 229
  • If you use TortoiseHG, an easy way to generate the splicemap file is to pick the hashes out of the Workbench GUI tool. You can right-click on any revision in the history and there is an option to select the exact hash value that is needed, called `## Copy Hash` – StayOnTarget Jun 15 '16 at 14:10
1

You should look at using rebase. This can allow you to make the changes the 2nd changeset on your repo ( you have to rebase from the 1st ).

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

However, note that if there are other clones of this repo existing ( such as for fellow developers, or on a repo server ), you will have issues with them pulling the revised repo. You will probably have to co-ordinate with the owners of those clone's to get all work into a single clone, rebase that clone, and then have everyone re-clone from the revised clone. You will also have to change the phase the of the changesets.

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

Honestly though, I would just add them to your 'modern-day' repo, I don't think making them pre-historic would give you any notable advantage over adding them to the top.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Kindread
  • 926
  • 4
  • 12
  • Makes sense, thanks. I hadn't considered just adding them to the top - wrong ordering aside, that at least gets file history into the toolchain, even if making diffs becomes a bit weird. Still neither solution is quite ideal. – mappu Oct 07 '13 at 06:32
  • @mappu. Well, hg also has a debug mode, which can give you some power over history. I don't actually use it though, so I can't say what to do, or even if its possible to accomplish exactly what you want. Its also very easy to accidentally do what you don't want to... – Kindread Oct 07 '13 at 06:40