English 中文(简体)
How are git branches imported into mercurial with hg convert?
原标题:

I have a number of branches in a git repository:

david@Panama ~/app: git branch -r  
origin/HEAD -> origin/master
origin/master
origin/newButtons
origin/newFonts
origin/serverView

If I try and import this git repo into mercurial:

david@Panama ~/: hg convert app
...
david@Panama ~/app-hg: hg update
388 files updated, 0 files merged, 0 files removed, 0 files unresolved
david@Panama ~/app-hg: hg branches
default                     1148:6d04af619607

It seems that the branches have been "lost" (in terms of them no longer being separated) and indeed merged into the tip:

david@Panama ~/app-hg: hg log
changeset:   1148:6d04af619607
tag:         tip
user:        convert-repo
date:        Mon Nov 16 17:57:06 2009 +0000
summary:     update tags

changeset:   1147:742e7a01a6c9
parent:      1144:bff259181b22
user:        user1
date:        Sat Nov 14 17:47:09 2009 +0000
summary:     Playing around with fonts to get a cleaner look

changeset:   1146:162c1b0dd648
parent:      1144:bff259181b22
user:        user1
date:        Fri Nov 13 21:12:21 2009 +0000
summary:     Playing with new server view

changeset:   1145:aa06857832ab
user:        user1
date:        Sat Nov 14 13:54:12 2009 +0000
summary:     Updated buttons to something more fitting

changeset:   1144:bff259181b22
user:        David Mytton <>
date:        Fri Nov 13 10:35:51 2009 +0000
summary:     Example

Given that being the case:

a) Am I doing something wrong to import the branches here?

b) Can the branches actually be imported?

最佳回答

This is by design. Imported Git branches are only labeled in Mercurial, and hg heads should give you the correct number of imported "branches".

As mentioned in this thread:

Consider a tree that looks like this:

        o-o-o-o-o-o-b <- branch foo
       /
 -o-o-a
       
        o-o-c <- branch bar

What branch are "a" and its ancestors on?
We haven t the slightest clue. In fact, the only changesets we have any certainty about are b nd c because branch names aren t part of history.

So:

Turns out it s actually impossible to do this right, because git doesn t store enough information.
Consider a repo with two branches in git, each with a number of commits.
Because git doesn t record which branch each commit originated on, there isn t enough information in the tree to label each changeset.
A git user can swap the names of the two branches and nothing is recorded to say it was ever different. If two branches have a common ancestor (and they almost certainly will), what branch is that ancestor on? We don t know.

The best we can do in the general case is to label each branch head as being on that branch. Then if you do an incremental conversion, we ll probably do the right thing. But git s concept of branches aren t a perfect match to hg s so this conversion won t be perfect either.


You can test it with a small Git repo (Git 1.6.5.1, Hg1.3.1):

PS C:ProgGit	ests> cd .hgimport
PS C:ProgGit	estshgimport> git init gitRepoToImport
PS C:ProgGit	estshgimport> cd .gitRepoToImport
PS [...]gitRepoToImport> echo firstContentToBr1 > br1.txt
PS [...]gitRepoToImport> echo firstContentToBr2 > br2.txt
PS [...]gitRepoToImport> echo firstContentToBr3 > br3.txt
PS [...]gitRepoToImport> git add -A
PS [...]gitRepoToImport> git commit -a -m "first content, to be evolved in three different branches"

Make a bunch of modifications in three separate branches:

PS [...]gitRepoToImport> git checkout -b br1
PS [...]gitRepoToImport> echo firstEvolutionInBr1 >> .r1.txt
PS [...]gitRepoToImport> git commit -a -m "first evolution in branch 1"
PS [...]gitRepoToImport> echo secondEvolutionInBr1 >> .r1.txt
PS [...]gitRepoToImport> git commit -a -m "second evolution in branch 1"
PS [...]gitRepoToImport> git checkout master
PS [...]gitRepoToImport> git checkout -b br2
PS [...]gitRepoToImport> echo firstEvolutionInBr1 >> .r2.txt
PS [...]gitRepoToImport> git commit -a -m "first evolution in branch 2"
PS [...]gitRepoToImport> git checkout master
PS [...]gitRepoToImport> git checkout -b br3
PS [...]gitRepoToImport> echo firstEvolutionInBr3 >> .r3.txt
PS [...]gitRepoToImport> git commit -a -m "first evolution in branch 3"
PS [...]gitRepoToImport> echo secondEvolutionInBr3 >> .r3.txt
PS [...]gitRepoToImport> git commit -a -m "second evolution in branch 3"
PS [...]gitRepoToImport> echo thirdEvolutionInBr3 >> .r3.txt
PS [...]gitRepoToImport> git commit -a -m "third evolution in branch 3"
PS [...]gitRepoToImport> git checkout br2
PS [...]gitRepoToImport> echo secondEvolutionInBr2 >> .r2.txt
PS [...]gitRepoToImport> git commit -a -m "second evolution in branch 2"
PS [...]gitRepoToImport> git checkout br1
PS [...]gitRepoToImport> echo thirdEvolutionInBr3 >> .r1.txt
PS [...]gitRepoToImport> git commit -a -m "third evolution in branch 1"
PS [...]gitRepoToImport> git checkout br2
PS [...]gitRepoToImport> echo thirdEvolutionInBr3 >> .r2.txt
PS [...]gitRepoToImport> git commit -a -m "third evolution in branch 2"

Then clone that Git repo (just in case, to male other tests)

PS [...]gitRepoToImport> cd ..
PS C:ProgGit	estshgimport> git clone .gitRepoToImport gitRepoToImport1

Configure your ~/.hgrc with a format UTF-8 without BOM (took me a while to get it right!)

[extensions]
hgext.convert = 

Then make the conversion

PS C:ProgGit	estshgimport> hg convert .gitRepoToImport1 hgRepo
PS C:ProgGit	estshgimport> cd .hgRepo
PS C:ProgGit	estshgimporthgRepo> hg heads

You will get the three expected "branches"

changeset:   9:ad0884395ada
tag:         tip
user:        VonC
date:        Mon Nov 16 21:45:35 2009 +0100
summary:     third evolution in branch 2

changeset:   6:854bc6537c7c
user:        VonC
date:        Mon Nov 16 21:45:19 2009 +0100
summary:     third evolution in branch 1

changeset:   3:9194cf25d3ca
user:        VonC
date:        Mon Nov 16 21:44:09 2009 +0100
summary:     third evolution in branch 3
问题回答

暂无回答




相关问题
git confusion - cloning a repo is returning a past version

Im having some confusion with my git usage. I cloned a repo from one comp to the other, and the new clone is the state of the original that was active some time ago. So its cloning a past version. ...

Appropriate strategy for tagging and hotfixing with git

I was wondering if the strategy I m using for tagging and hotfixing tags (which then I use for deploying rails applications) with git is appropriate. For tagging I just tag a commit of the master ...

Tips on upgrading CVS to git/hg?

We still use CVS, I use git and hg for my personal use though I m still a novice at both, but I realize they re much more modern and better, faster, distributed, etc. It s just everyone is so ...

Using Git in a TFS shop

Using Git at home has spoiled me - I now find using TFS at work to be a bit of a drag and want to explore the possibility of using Git locally and syncing somehow with TFS. I figure there are a few ...

热门标签