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
精彩评论