annotate contrib/convert-repo @ 4168:bbfe5a3fc80c

Add a features list to branches.cache to detect caches of old hg versions. The leading space in the written file makes sure that the feature list never can match an existing version, even if the first feature can be read as hex. Additionally old hg versions display the id with --debug, too.
author Thomas Arendsen Hein <thomas@intevation.de>
date Fri, 09 Mar 2007 19:12:03 +0100
parents 645e1dd4b8ae
children 0fab73b3f453
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
1 #!/usr/bin/env python
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
2 #
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
3 # This is a generalized framework for converting between SCM
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
4 # repository formats.
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
5 #
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
6 # In its current form, it's hardcoded to convert incrementally between
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
7 # git and Mercurial.
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
8 #
3916
645e1dd4b8ae convert-repo: update usage information
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3911
diff changeset
9 # To use, run:
645e1dd4b8ae convert-repo: update usage information
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3911
diff changeset
10 #
645e1dd4b8ae convert-repo: update usage information
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3911
diff changeset
11 # convert-repo <git-dir> <hg-dir> <mapfile>
645e1dd4b8ae convert-repo: update usage information
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3911
diff changeset
12 #
645e1dd4b8ae convert-repo: update usage information
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3911
diff changeset
13 # (don't forget to create the <hg-dir> repository beforehand)
645e1dd4b8ae convert-repo: update usage information
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3911
diff changeset
14 #
645e1dd4b8ae convert-repo: update usage information
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3911
diff changeset
15 # The <mapfile> is a simple text file that maps a git commit hash to
645e1dd4b8ae convert-repo: update usage information
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3911
diff changeset
16 # the hash in Mercurial for that version, like so:
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
17 #
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
18 # <git hash> <mercurial hash>
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
19 #
3916
645e1dd4b8ae convert-repo: update usage information
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3911
diff changeset
20 # If the file doesn't exist, it's automatically created. It's updated
645e1dd4b8ae convert-repo: update usage information
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3911
diff changeset
21 # on each commit copied, so convert-repo can be interrupted and can
645e1dd4b8ae convert-repo: update usage information
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3911
diff changeset
22 # be run repeatedly to copy new commits.
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
23
694
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
24 import sys, os, zlib, sha, time
3825
158fce02dc40 Teach convert-repo to deal with mixed charsets in git
Matt Mackall <mpm@selenic.com>
parents: 2649
diff changeset
25
158fce02dc40 Teach convert-repo to deal with mixed charsets in git
Matt Mackall <mpm@selenic.com>
parents: 2649
diff changeset
26 os.environ["HGENCODING"] = "utf-8"
158fce02dc40 Teach convert-repo to deal with mixed charsets in git
Matt Mackall <mpm@selenic.com>
parents: 2649
diff changeset
27
1715
40346aa66b0f Revert convert-repo changes
Matt Mackall <mpm@selenic.com>
parents: 1656
diff changeset
28 from mercurial import hg, ui, util
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
29
3825
158fce02dc40 Teach convert-repo to deal with mixed charsets in git
Matt Mackall <mpm@selenic.com>
parents: 2649
diff changeset
30 def recode(s):
158fce02dc40 Teach convert-repo to deal with mixed charsets in git
Matt Mackall <mpm@selenic.com>
parents: 2649
diff changeset
31 try:
158fce02dc40 Teach convert-repo to deal with mixed charsets in git
Matt Mackall <mpm@selenic.com>
parents: 2649
diff changeset
32 return s.decode("utf-8").encode("utf-8")
158fce02dc40 Teach convert-repo to deal with mixed charsets in git
Matt Mackall <mpm@selenic.com>
parents: 2649
diff changeset
33 except:
158fce02dc40 Teach convert-repo to deal with mixed charsets in git
Matt Mackall <mpm@selenic.com>
parents: 2649
diff changeset
34 try:
158fce02dc40 Teach convert-repo to deal with mixed charsets in git
Matt Mackall <mpm@selenic.com>
parents: 2649
diff changeset
35 return s.decode("latin-1").encode("utf-8")
158fce02dc40 Teach convert-repo to deal with mixed charsets in git
Matt Mackall <mpm@selenic.com>
parents: 2649
diff changeset
36 except:
158fce02dc40 Teach convert-repo to deal with mixed charsets in git
Matt Mackall <mpm@selenic.com>
parents: 2649
diff changeset
37 return s.decode("utf-8", "replace").encode("utf-8")
158fce02dc40 Teach convert-repo to deal with mixed charsets in git
Matt Mackall <mpm@selenic.com>
parents: 2649
diff changeset
38
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
39 class convert_git:
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
40 def __init__(self, path):
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
41 self.path = path
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
42
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
43 def getheads(self):
2649
e6a7a6a33a62 make convert-repo deal with git symbolic refs.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2093
diff changeset
44 fh = os.popen("GIT_DIR=%s git-rev-parse --verify HEAD" % self.path)
e6a7a6a33a62 make convert-repo deal with git symbolic refs.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2093
diff changeset
45 return [fh.read()[:-1]]
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
46
692
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
47 def catfile(self, rev, type):
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
48 if rev == "0" * 40: raise IOError()
1335
bea6356b8bca git -> hg conversion script
Florian La Roche <laroche@redhat.com>
parents: 1237
diff changeset
49 fh = os.popen("GIT_DIR=%s git-cat-file %s %s 2>/dev/null" % (self.path, type, rev))
692
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
50 return fh.read()
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
51
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
52 def getfile(self, name, rev):
692
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
53 return self.catfile(rev, "blob")
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
54
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
55 def getchanges(self, version):
1335
bea6356b8bca git -> hg conversion script
Florian La Roche <laroche@redhat.com>
parents: 1237
diff changeset
56 fh = os.popen("GIT_DIR=%s git-diff-tree --root -m -r %s" % (self.path, version))
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
57 changes = []
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
58 for l in fh:
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
59 if "\t" not in l: continue
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
60 m, f = l[:-1].split("\t")
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
61 m = m.split()
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
62 h = m[3]
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
63 p = (m[1] == "100755")
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
64 changes.append((f, h, p))
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
65 return changes
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
66
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
67 def getcommit(self, version):
692
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
68 c = self.catfile(version, "commit") # read the commit hash
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
69 end = c.find("\n\n")
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
70 message = c[end+2:]
3825
158fce02dc40 Teach convert-repo to deal with mixed charsets in git
Matt Mackall <mpm@selenic.com>
parents: 2649
diff changeset
71 message = recode(message)
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
72 l = c[:end].splitlines()
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
73 manifest = l[0].split()[1]
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
74 parents = []
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
75 for e in l[1:]:
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
76 n,v = e.split(" ", 1)
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
77 if n == "author":
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
78 p = v.split()
1385
adb3de56635b convert-repo: Fix timezone handling
Matt Mackall <mpm@selenic.com>
parents: 1335
diff changeset
79 tm, tz = p[-2:]
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
80 author = " ".join(p[:-2])
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
81 if author[0] == "<": author = author[1:-1]
3825
158fce02dc40 Teach convert-repo to deal with mixed charsets in git
Matt Mackall <mpm@selenic.com>
parents: 2649
diff changeset
82 author = recode(author)
692
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
83 if n == "committer":
431
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
84 p = v.split()
1385
adb3de56635b convert-repo: Fix timezone handling
Matt Mackall <mpm@selenic.com>
parents: 1335
diff changeset
85 tm, tz = p[-2:]
431
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
86 committer = " ".join(p[:-2])
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
87 if committer[0] == "<": committer = committer[1:-1]
3825
158fce02dc40 Teach convert-repo to deal with mixed charsets in git
Matt Mackall <mpm@selenic.com>
parents: 2649
diff changeset
88 committer = recode(committer)
3910
4bc5a2405b12 convert-repo: fix recoding of committer
Matt Mackall <mpm@selenic.com>
parents: 3825
diff changeset
89 message += "\ncommitter: %s\n" % committer
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
90 if n == "parent": parents.append(v)
1385
adb3de56635b convert-repo: Fix timezone handling
Matt Mackall <mpm@selenic.com>
parents: 1335
diff changeset
91
adb3de56635b convert-repo: Fix timezone handling
Matt Mackall <mpm@selenic.com>
parents: 1335
diff changeset
92 tzs, tzh, tzm = tz[-5:-4] + "1", tz[-4:-2], tz[-2:]
2093
5cc414722587 convert-repo: fix reversed time zone offset
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1715
diff changeset
93 tz = -int(tzs) * (int(tzh) * 3600 + int(tzm))
1385
adb3de56635b convert-repo: Fix timezone handling
Matt Mackall <mpm@selenic.com>
parents: 1335
diff changeset
94 date = tm + " " + str(tz)
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
95 return (parents, author, date, message)
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
96
694
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
97 def gettags(self):
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
98 tags = {}
1335
bea6356b8bca git -> hg conversion script
Florian La Roche <laroche@redhat.com>
parents: 1237
diff changeset
99 for f in os.listdir(self.path + "/refs/tags"):
694
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
100 try:
1335
bea6356b8bca git -> hg conversion script
Florian La Roche <laroche@redhat.com>
parents: 1237
diff changeset
101 h = file(self.path + "/refs/tags/" + f).read().strip()
1386
a1040345fdda convert-repo: retrieve the commit hash from the tag object for tag import
Matt Mackall <mpm@selenic.com>
parents: 1385
diff changeset
102 c = self.catfile(h, "tag") # read the commit hash
a1040345fdda convert-repo: retrieve the commit hash from the tag object for tag import
Matt Mackall <mpm@selenic.com>
parents: 1385
diff changeset
103 h = c.splitlines()[0].split()[1]
1237
227cfbe34109 Fix off by one in convert-repo tags
mason@suse.com
parents: 705
diff changeset
104 tags[f] = h
694
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
105 except:
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
106 pass
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
107 return tags
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
108
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
109 class convert_mercurial:
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
110 def __init__(self, path):
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
111 self.path = path
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
112 u = ui.ui()
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
113 self.repo = hg.repository(u, path)
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
114
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
115 def getheads(self):
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
116 h = self.repo.changelog.heads()
1335
bea6356b8bca git -> hg conversion script
Florian La Roche <laroche@redhat.com>
parents: 1237
diff changeset
117 return [ hg.hex(x) for x in h ]
692
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
118
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
119 def putfile(self, f, e, data):
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
120 self.repo.wfile(f, "w").write(data)
692
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
121 if self.repo.dirstate.state(f) == '?':
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
122 self.repo.dirstate.update([f], "a")
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
123
450
9d785fd7deec Get set_exec from util in convert_repo
mpm@selenic.com
parents: 431
diff changeset
124 util.set_exec(self.repo.wjoin(f), e)
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
125
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
126 def delfile(self, f):
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
127 try:
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
128 os.unlink(self.repo.wjoin(f))
692
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
129 #self.repo.remove([f])
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
130 except:
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
131 pass
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
132
1715
40346aa66b0f Revert convert-repo changes
Matt Mackall <mpm@selenic.com>
parents: 1656
diff changeset
133 def putcommit(self, files, parents, author, dest, text):
431
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
134 seen = {}
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
135 pl = []
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
136 for p in parents:
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
137 if p not in seen:
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
138 pl.append(p)
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
139 seen[p] = 1
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
140 parents = pl
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
141
692
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
142 if len(parents) < 2: parents.append("0" * 40)
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
143 if len(parents) < 2: parents.append("0" * 40)
431
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
144 p2 = parents.pop(0)
692
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
145
431
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
146 while parents:
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
147 p1 = p2
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
148 p2 = parents.pop(0)
1715
40346aa66b0f Revert convert-repo changes
Matt Mackall <mpm@selenic.com>
parents: 1656
diff changeset
149 self.repo.rawcommit(files, text, author, dest,
40346aa66b0f Revert convert-repo changes
Matt Mackall <mpm@selenic.com>
parents: 1656
diff changeset
150 hg.bin(p1), hg.bin(p2))
431
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
151 text = "(octopus merge fixup)\n"
1389
9b3ef6f3cef5 convert-repo: fix up octopus merge conversion
Matt Mackall <mpm@selenic.com>
parents: 1388
diff changeset
152 p2 = hg.hex(self.repo.changelog.tip())
431
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
153
1389
9b3ef6f3cef5 convert-repo: fix up octopus merge conversion
Matt Mackall <mpm@selenic.com>
parents: 1388
diff changeset
154 return p2
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
155
694
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
156 def puttags(self, tags):
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
157 try:
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
158 old = self.repo.wfile(".hgtags").read()
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
159 oldlines = old.splitlines(1)
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
160 oldlines.sort()
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
161 except:
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
162 oldlines = []
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
163
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
164 k = tags.keys()
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
165 k.sort()
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
166 newlines = []
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
167 for tag in k:
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
168 newlines.append("%s %s\n" % (tags[tag], tag))
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
169
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
170 newlines.sort()
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
171
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
172 if newlines != oldlines:
1335
bea6356b8bca git -> hg conversion script
Florian La Roche <laroche@redhat.com>
parents: 1237
diff changeset
173 #print "updating tags"
694
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
174 f = self.repo.wfile(".hgtags", "w")
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
175 f.write("".join(newlines))
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
176 f.close()
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
177 if not oldlines: self.repo.add([".hgtags"])
1335
bea6356b8bca git -> hg conversion script
Florian La Roche <laroche@redhat.com>
parents: 1237
diff changeset
178 date = "%s 0" % int(time.mktime(time.gmtime()))
694
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
179 self.repo.rawcommit([".hgtags"], "update tags", "convert-repo",
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
180 date, self.repo.changelog.tip(), hg.nullid)
1387
0c7e8d345564 convert-repo: linearize the tag commit
Matt Mackall <mpm@selenic.com>
parents: 1386
diff changeset
181 return hg.hex(self.repo.changelog.tip())
694
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
182
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
183 class convert:
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
184 def __init__(self, source, dest, mapfile):
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
185 self.source = source
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
186 self.dest = dest
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
187 self.mapfile = mapfile
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
188 self.commitcache = {}
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
189
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
190 self.map = {}
1655
7bfd4724932a convert-repo: automatically create empty map file
Matt Mackall <mpm@selenic.com>
parents: 1389
diff changeset
191 try:
7bfd4724932a convert-repo: automatically create empty map file
Matt Mackall <mpm@selenic.com>
parents: 1389
diff changeset
192 for l in file(self.mapfile):
7bfd4724932a convert-repo: automatically create empty map file
Matt Mackall <mpm@selenic.com>
parents: 1389
diff changeset
193 sv, dv = l[:-1].split()
7bfd4724932a convert-repo: automatically create empty map file
Matt Mackall <mpm@selenic.com>
parents: 1389
diff changeset
194 self.map[sv] = dv
7bfd4724932a convert-repo: automatically create empty map file
Matt Mackall <mpm@selenic.com>
parents: 1389
diff changeset
195 except IOError:
7bfd4724932a convert-repo: automatically create empty map file
Matt Mackall <mpm@selenic.com>
parents: 1389
diff changeset
196 pass
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
197
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
198 def walktree(self, heads):
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
199 visit = heads
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
200 known = {}
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
201 parents = {}
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
202 while visit:
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
203 n = visit.pop(0)
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
204 if n in known or n in self.map: continue
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
205 known[n] = 1
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
206 self.commitcache[n] = self.source.getcommit(n)
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
207 cp = self.commitcache[n][0]
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
208 for p in cp:
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
209 parents.setdefault(n, []).append(p)
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
210 visit.append(p)
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
211
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
212 return parents
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
213
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
214 def toposort(self, parents):
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
215 visit = parents.keys()
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
216 seen = {}
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
217 children = {}
692
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
218
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
219 while visit:
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
220 n = visit.pop(0)
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
221 if n in seen: continue
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
222 seen[n] = 1
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
223 pc = 0
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
224 if n in parents:
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
225 for p in parents[n]:
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
226 if p not in self.map: pc += 1
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
227 visit.append(p)
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
228 children.setdefault(p, []).append(n)
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
229 if not pc: root = n
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
230
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
231 s = []
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
232 removed = {}
692
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
233 visit = children.keys()
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
234 while visit:
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
235 n = visit.pop(0)
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
236 if n in removed: continue
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
237 dep = 0
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
238 if n in parents:
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
239 for p in parents[n]:
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
240 if p in self.map: continue
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
241 if p not in removed:
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
242 # we're still dependent
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
243 visit.append(n)
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
244 dep = 1
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
245 break
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
246
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
247 if not dep:
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
248 # all n's parents are in the list
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
249 removed[n] = 1
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
250 s.append(n)
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
251 if n in children:
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
252 for c in children[n]:
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
253 visit.insert(0, c)
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
254
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
255 return s
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
256
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
257 def copy(self, rev):
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
258 p, a, d, t = self.commitcache[rev]
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
259 files = self.source.getchanges(rev)
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
260
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
261 for f,v,e in files:
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
262 try:
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
263 data = self.source.getfile(f, v)
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
264 except IOError, inst:
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
265 self.dest.delfile(f)
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
266 else:
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
267 self.dest.putfile(f, e, data)
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
268
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
269 r = [self.map[v] for v in p]
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
270 f = [f for f,v,e in files]
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
271 self.map[rev] = self.dest.putcommit(f, r, a, d, t)
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
272 file(self.mapfile, "a").write("%s %s\n" % (rev, self.map[rev]))
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
273
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
274 def convert(self):
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
275 heads = self.source.getheads()
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
276 parents = self.walktree(heads)
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
277 t = self.toposort(parents)
1388
5eb2d3c54165 convert-repo: change duplicate elimination
Matt Mackall <mpm@selenic.com>
parents: 1387
diff changeset
278 t = [n for n in t if n not in self.map]
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
279 num = len(t)
1715
40346aa66b0f Revert convert-repo changes
Matt Mackall <mpm@selenic.com>
parents: 1656
diff changeset
280 c = None
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
281
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
282 for c in t:
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
283 num -= 1
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
284 desc = self.commitcache[c][3].splitlines()[0]
1335
bea6356b8bca git -> hg conversion script
Florian La Roche <laroche@redhat.com>
parents: 1237
diff changeset
285 #print num, desc
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
286 self.copy(c)
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
287
694
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
288 tags = self.source.gettags()
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
289 ctags = {}
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
290 for k in tags:
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
291 v = tags[k]
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
292 if v in self.map:
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
293 ctags[k] = self.map[v]
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
294
1715
40346aa66b0f Revert convert-repo changes
Matt Mackall <mpm@selenic.com>
parents: 1656
diff changeset
295 if c and ctags:
1387
0c7e8d345564 convert-repo: linearize the tag commit
Matt Mackall <mpm@selenic.com>
parents: 1386
diff changeset
296 nrev = self.dest.puttags(ctags)
0c7e8d345564 convert-repo: linearize the tag commit
Matt Mackall <mpm@selenic.com>
parents: 1386
diff changeset
297 # write another hash correspondence to override the previous
0c7e8d345564 convert-repo: linearize the tag commit
Matt Mackall <mpm@selenic.com>
parents: 1386
diff changeset
298 # one so we don't end up with extra tag heads
3911
fe075ddf3272 convert-repo: avoid adding bogus value to shamap on tag update
Matt Mackall <mpm@selenic.com>
parents: 3910
diff changeset
299 if nrev:
fe075ddf3272 convert-repo: avoid adding bogus value to shamap on tag update
Matt Mackall <mpm@selenic.com>
parents: 3910
diff changeset
300 file(self.mapfile, "a").write("%s %s\n" % (c, nrev))
694
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
301
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
302 gitpath, hgpath, mapfile = sys.argv[1:]
1335
bea6356b8bca git -> hg conversion script
Florian La Roche <laroche@redhat.com>
parents: 1237
diff changeset
303 if os.path.isdir(gitpath + "/.git"):
bea6356b8bca git -> hg conversion script
Florian La Roche <laroche@redhat.com>
parents: 1237
diff changeset
304 gitpath += "/.git"
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
305
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
306 c = convert(convert_git(gitpath), convert_mercurial(hgpath), mapfile)
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
307 c.convert()