convert: hg.clonebranches must pull missing parents (
issue941)
--- a/hgext/convert/common.py Tue Jan 22 00:16:50 2008 +0100
+++ b/hgext/convert/common.py Sat Jan 26 19:55:04 2008 +0100
@@ -167,12 +167,11 @@
tags: {tagname: sink_rev_id, ...}"""
raise NotImplementedError()
- def setbranch(self, branch, pbranch, parents):
+ def setbranch(self, branch, pbranches):
"""Set the current branch name. Called before the first putfile
on the branch.
branch: branch name for subsequent commits
- pbranch: branch name of parent commit
- parents: destination revisions of parent"""
+ pbranches: (converted parent revision, parent branch) tuples"""
pass
def setfilemapmode(self, active):
--- a/hgext/convert/convcmd.py Tue Jan 22 00:16:50 2008 +0100
+++ b/hgext/convert/convcmd.py Sat Jan 26 19:55:04 2008 +0100
@@ -222,15 +222,14 @@
self.mapentry(rev, dest)
return
files, copies = changes
- parents = [self.map[r] for r in commit.parents]
+ pbranches = []
if commit.parents:
- prev = commit.parents[0]
- if prev not in self.commitcache:
- self.cachecommit(prev)
- pbranch = self.commitcache[prev].branch
- else:
- pbranch = None
- self.dest.setbranch(commit.branch, pbranch, parents)
+ for prev in commit.parents:
+ if prev not in self.commitcache:
+ self.cachecommit(prev)
+ pbranches.append((self.map[prev],
+ self.commitcache[prev].branch))
+ self.dest.setbranch(commit.branch, pbranches)
for f, v in files:
filenames.append(f)
try:
@@ -246,6 +245,7 @@
# Merely marks that a copy happened.
self.dest.copyfile(copyf, f)
+ parents = [b[0] for b in pbranches]
newnode = self.dest.putcommit(filenames, parents, commit)
self.mapentry(rev, newnode)
--- a/hgext/convert/hg.py Tue Jan 22 00:16:50 2008 +0100
+++ b/hgext/convert/hg.py Sat Jan 26 19:55:04 2008 +0100
@@ -80,30 +80,43 @@
except OSError:
pass
- def setbranch(self, branch, pbranch, parents):
- if (not self.clonebranches) or (branch == self.lastbranch):
+ def setbranch(self, branch, pbranches):
+ if not self.clonebranches:
return
+ setbranch = (branch != self.lastbranch)
self.lastbranch = branch
- self.after()
if not branch:
branch = 'default'
- if not pbranch:
- pbranch = 'default'
+ pbranches = [(b[0], b[1] and b[1] or 'default') for b in pbranches]
+ pbranch = pbranches and pbranches[0][1] or 'default'
branchpath = os.path.join(self.path, branch)
- try:
- self.repo = hg.repository(self.ui, branchpath)
- except:
- if not parents:
+ if setbranch:
+ self.after()
+ try:
+ self.repo = hg.repository(self.ui, branchpath)
+ except:
self.repo = hg.repository(self.ui, branchpath, create=True)
- else:
- self.ui.note(_('cloning branch %s to %s\n') % (pbranch, branch))
- hg.clone(self.ui, os.path.join(self.path, pbranch),
- branchpath, rev=parents, update=False,
- stream=True)
- self.repo = hg.repository(self.ui, branchpath)
- self.before()
+ self.before()
+
+ # pbranches may bring revisions from other branches (merge parents)
+ # Make sure we have them, or pull them.
+ missings = {}
+ for b in pbranches:
+ try:
+ self.repo.lookup(b[0])
+ except:
+ missings.setdefault(b[1], []).append(b[0])
+
+ if missings:
+ self.after()
+ for pbranch, heads in missings.iteritems():
+ pbranchpath = os.path.join(self.path, pbranch)
+ prepo = hg.repository(self.ui, pbranchpath)
+ self.ui.note(_('pulling from %s into %s\n') % (pbranch, branch))
+ self.repo.pull(prepo, [prepo.lookup(h) for h in heads])
+ self.before()
def putcommit(self, files, parents, commit):
seen = {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-convert-clonebranches Sat Jan 26 19:55:04 2008 +0100
@@ -0,0 +1,54 @@
+#!/bin/sh
+
+echo "[extensions]" >> $HGRCPATH
+echo "hgext.convert = " >> $HGRCPATH
+echo "[convert]" >> $HGRCPATH
+echo "hg.tagsbranch=0" >> $HGRCPATH
+
+hg init source
+cd source
+echo a > a
+hg ci -qAm adda
+# Add a merge with one parent in the same branch
+echo a >> a
+hg ci -qAm changea
+hg up -qC 0
+hg branch branch0
+echo b > b
+hg ci -qAm addb
+hg up -qC
+hg merge
+hg ci -qm mergeab
+hg tag -ql mergeab
+cd ..
+
+# Miss perl... sometimes
+cat > filter.py <<EOF
+import sys, re
+
+r = re.compile(r'^(?:\d+|pulling from)')
+sys.stdout.writelines([l for l in sys.stdin if r.search(l)])
+EOF
+
+echo % convert
+hg convert -v --config convert.hg.clonebranches=1 source dest |
+ python filter.py
+
+# Add a merge with both parents and child in different branches
+cd source
+hg branch branch1
+echo a > file1
+hg ci -qAm c1
+hg up -qC mergeab
+hg branch branch2
+echo a > file2
+hg ci -qAm c2
+hg merge branch1
+hg branch branch3
+hg ci -qAm c3
+cd ..
+
+echo % incremental conversion
+hg convert -v --config convert.hg.clonebranches=1 source dest |
+ python filter.py
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-convert-clonebranches.out Sat Jan 26 19:55:04 2008 +0100
@@ -0,0 +1,29 @@
+marked working directory as branch branch0
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+(branch merge, don't forget to commit)
+% convert
+3 adda
+2 addb
+pulling from default into branch0
+1 changesets found
+1 changea
+0 mergeab
+pulling from default into branch0
+1 changesets found
+marked working directory as branch branch1
+marked working directory as branch branch2
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+(branch merge, don't forget to commit)
+marked working directory as branch branch3
+% incremental conversion
+2 c1
+pulling from branch0 into branch1
+2 changesets found
+1 c2
+pulling from branch0 into branch2
+2 changesets found
+0 c3
+pulling from branch2 into branch3
+3 changesets found
+pulling from branch1 into branch3
+1 changesets found