开发者

Merging disparate projects with repositories into a single solution with hg?

I started two disparate projects in Visual Studio 2010, each with their own hg repository.

Later I decided that the two projects belonged under one solution, and thus one hg repository.

The new solution the following file structure:

SolutionFolder
   |---.hg
   +---Lib
   |    ∟ dlls
   +---Source
   |    ∟ Project_A
   |      ∟--.hg  
   |    ∟ Project_B
   |      ∟--.hg
   +---OverarchingSolution.sln

Is there a way that I can merge Project_A's and Project_B's changesets into the solution folder's repository?

Thus resulting in:

SolutionFolder
   |---.hg
   +---Lib
   |    ∟ dlls
   +---Source
   |    ∟ Project_A
   |    ∟ Project_B
   +---OverarchingSolution.sln
开发者_JS百科

With all of the changesets from Project_A's and Project_B's landing in the SolutionFolder's repository?


If you think there's a chance you'll ever want to use those two repositories separately again (i.e: use one in a different solution but not the other) then you can just make them subrepositories of a new top level repository.

To do that you'd just cd into SolutionFolder and create a file named .hgsub containing these lines:

Source/Project_A = Source/Project_A
Source/Project_B = Source/Project_B

then you run these commands (still in SolutionFolder):

hg init
hg add .hgsub
hg commit -m 'new repo with two sub repos'

After that you can do most all the normal Mercurial commands up in Solution Folder (status, commit, etc) with an additional --subrepos argument and they'll cascade down into the sub-repos.


If you're okay with altering history (ie: invalidating everyone else's clones of this project) you can use the 'convert' extension.

Create text file, we'll call it rename-map-a.txt this line in it:

rename . Source/Project_A

Then go into Source and run:

hg convert --filemap rename-map-a.txt Project_A new-Project_A

Repeat the same process for B so that now you have:

SolutionFolder
   |---.hg
   +---Lib
   |    ∟ dlls
   +---Source
   |    ∟ Project_A
   |      ∟--.hg  
   |    ∟ Project_B
   |      ∟--.hg
   |    ∟ new-Project_A
   |      ∟--.hg  
   |    ∟ new-Project_B
   |      ∟--.hg
   +---OverarchingSolution.sln

Then go into SolutionFolder and run these commands:

hg init   # creates a new, empty repo
hg pull Source/new-Project_A   # pulls in changesets from A
hg pull --force Source/new-Project_B   # pulls in changesets from A

If that worked you can remove (or better move somewhere for backup these directories:

SolutionFolder/Source/Project_A/.hg
SolutionFolder/Source/Project_B/.hg
SolutionFolder/Source/new-Project_A
SolutionFilder/Source/new-Project_B

leaving you with exactly what you have as the goal in your question, and with all history and everything tracked. That said, see my other answer for what I think is a better idea.


One way you can do this is to pull from an unrelated repo, using hg pull -f. This will result in a repository that has multiple roots. You will still have the history from both repos, which will be represented by two lines of development in the repository.

The only trick here is to get the directory structure right. You want to root of your merged-in repos to match the root of your combined repo.

So for your case, I would imagine something like this:

    C:\> move SolutionFolder\Source\Project_A Temp_Project_A
    C:\> cd Temp_Project_A
    C:\Temp_Project_A> mkdir Source\Project_A
    C:\Temp_Project_A> hg rename * Source\Project_A
    C:\Temp_Project_A> hg ci -m "moved all Project_A files down in preparation for combining repos"
    C:\Temp_Project_A> cd ..\SolutionFolder
    C:\SolutionFolder> hg pull -f ..\Temp_Project_A
    C:\SolutionFolder> hg merge
    C:\SolutionFolder> hg ci -m "merged Project_A repo into main one"

    (and similar for Project B)

Check out the section beginning "It is possible to pull from completely unrelated repository..." in the Mercurial Wiki

Here is a generic example with real output:

    C:\>hg ini repoA

    C:\>hg ini repoB

    C:\>cd repoA

    C:\repoA>echo FOO > foo.txt

    C:\repoA>hg add
    adding foo.txt

    C:\repoA>hg ci -m "added foo in repo A"

    C:\repoA>cd ..\repoB

    C:\repoB>echo BAR > bar.txt

    C:\repoB>hg add
    adding bar.txt

    C:\repoB>hg ci -m "added bar in repo B"

    C:\repoB>cd ..

    C:\>hg clone repoA combinedRepo
    updating to branch default
    1 files updated, 0 files merged, 0 files removed, 0 files unresolved

    C:\>cd combinedRepo

    C:\combinedRepo>hg pull -f ..\repoB
    pulling from ..\repoB
    searching for changes
    warning: repository is unrelated
    adding changesets
    adding manifests
    adding file changes
    added 1 changesets with 1 changes to 1 files (+1 heads)
    (run 'hg heads' to see heads, 'hg merge' to merge)

    C:\combinedRepo>hg merge
    1 files updated, 0 files merged, 0 files removed, 0 files unresolved
    (branch merge, don't forget to commit)

    C:\combinedRepo>hg ci -m "merged repoB into repoA"

    C:\combinedRepo>hg gl
    @    changeset:   2:3d08641554c5
    |\   tag:         tip
    | |  parent:      0:bc6a6ad6a3e5
    | |  parent:      1:54dc5af30c7a
    | |  user:        j.w.
    | |  date:        Fri Mar 25 10:12:32 2011 -0700
    | |  summary:     merged repoB into repoA
    | |
    | o  changeset:   1:54dc5af30c7a
    |    parent:      -1:000000000000
    |    user:        j.w.
    |    date:        Fri Mar 25 10:11:43 2011 -0700
    |    summary:     added bar in repo B
    |
    o  changeset:   0:bc6a6ad6a3e5
       user:        j.w
       date:        Fri Mar 25 10:11:15 2011 -0700
       summary:     added foo in repo A
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜