tryurbest
tryurbest

Reputation: 1429

Move files across sub-repos in mercurial

Does anyone know how to move files across suprepos while preserving the history on the file

I am using hg mv /Product/common/modules/sub-repo1/scripts/filename /Product/common/modules/sub-repo2/scripts/filename

Product is the shell level repo and sub-repo1 and sub-repo2 are sub-repos

It throws an error abort /Product/common/modules/sub-repo2/scripts/filename not under root..

Upvotes: 4

Views: 735

Answers (2)

Laurens Holst
Laurens Holst

Reputation: 21086

It is possible by splicing two repositories together:

  1. Convert to a new repository with a filemap which filters out everything except the file you‘re interested in. There is a nice description on hgtip.com.

    echo include my-file > filemap
    hg convert --filemap sourcerepo temprepo
    
  2. Pull the new repository into your existing repository. This will create an entire new head which does not originate from any previous changeset. This is also described in more detail on hgtip.com.

    cd destrepo
    hg pull --force temprepo
    
  3. Finally, merge the new head.

    hg merge
    

Here’s an example on the command line. First we create an original source repository:

$ mkdir sourcerepo
$ cd sourcerepo
$ hg init
$ echo aaa > a
$ echo bbb > b
$ hg add a b
$ hg commit -m first
$ echo xxx > a
$ echo yyy > b
$ hg commit -m second

Then we create a filemap and convert it to a temporary repository containing just the file we want:

$ cd ..
$ echo include a > filemap
$ hg convert --filemap filemap sourcerepo temprepo
initializing destination temprepo repository
scanning source...
sorting...
converting...
1 first
0 second
$ hg glog temprepo/a
@  changeset:   1:a2c44f396733
|  tag:         tip
|  user:        Laurens Holst <...>
|  date:        Fri Oct 21 13:02:53 2011 +0200
|  summary:     second
|
o  changeset:   0:68090379058b
   user:        Laurens Holst <...>
   date:        Fri Oct 21 13:02:41 2011 +0200
   summary:     first

Now we create a destination repository:

$ mkdir destrepo
$ cd destrepo
$ echo zzz > z
$ hg add z
$ hg commit -m another
$ hg glog
o  changeset:   0:890b51ba85c6
   tag:         tip
   user:        Laurens Holst <...>
   date:        Fri Oct 21 13:15:51 2011 +0200
   summary:     another

Finally we pull in the changes from the temporary repo, and merge it:

$ hg pull --force ../temprepo
pulling from ../temprepo
searching for changes
warning: repository is unrelated
requesting all changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 2 changes to 1 files (+1 heads)
(run 'hg heads' to see heads, 'hg merge' to merge)
$ hg merge
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg commit -m "merge file a from sourcerepo"
$ ls
a z
$ hg glog
@    changeset:   3:7becd66c019a
|\   tag:         tip
| |  parent:      0:890b51ba85c6
| |  parent:      2:dc9ac503efba
| |  user:        Laurens Holst <...>
| |  date:        Fri Oct 21 13:39:51 2011 +0200
| |  summary:     merge file a from sourcerepo
| |
| o  changeset:   2:dc9ac503efba
| |  user:        Laurens Holst <...>
| |  date:        Fri Oct 21 13:02:53 2011 +0200
| |  summary:     second
| |
| o  changeset:   1:2a5fa6bd9021
|    parent:      -1:000000000000
|    user:        Laurens Holst <...>
|    date:        Fri Oct 21 13:02:41 2011 +0200
|    summary:     first
|
o  changeset:   0:890b51ba85c6
   user:        Laurens Holst <...>
   date:        Fri Oct 21 13:15:51 2011 +0200
   summary:     another

Now your file from the source repository is merged into the destination repository while preserving all change history!

Upvotes: 7

Lasse V. Karlsen
Lasse V. Karlsen

Reputation: 391664

You can't do that.

You need to do it in these steps:

  1. Copy the file from one repository to the other using normal file system tools
  2. Add it in the new repository through hg add
  3. Remove the file from the old repository through hg remove

Note that in the process, you'll lose the history, as that will be left behind in the old repository, and not transferred to the new one. If you need that, there's other ways involving making a new repository containing only that file and its history, through conversion, but that's a different topic.

You will not be able to persuade Mercurial to work with more than one repository at a time, so there's no single command that will transfer it from one repository to the other.

Upvotes: 3

Related Questions