annotate contrib/convert-repo @ 3861:db36a4f490f6

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