Mercurial > hg > mercurial-crew-with-dirclash
annotate contrib/convert-repo @ 4508:0026ccc2bf23
Remove atomicfile class.
The interface provided by opener(atomic=True) is inherently unsafe:
if an exception is raised in the code using the atomic file, the
possibly incomplete file will be renamed to its final destination,
defeating the whole purpose of atomic files.
To get around this, we would either need some bad hacks involving
sys.exc_info (to make sure things work in except: blocks), or an
interface to say "file is complete; rename it".
This is the exact interface provided by atomictempfile. Since there
are no remaining users of the atomicfile class, just remove it.
author | Alexis S. L. Carvalho <alexis@cecm.usp.br> |
---|---|
date | Tue, 05 Jun 2007 19:55:27 -0300 |
parents | af013ae3ca10 |
children |
rev | line source |
---|---|
316 | 1 #!/usr/bin/env python |
2 # | |
3 # This is a generalized framework for converting between SCM | |
4 # repository formats. | |
5 # | |
3916
645e1dd4b8ae
convert-repo: update usage information
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3911
diff
changeset
|
6 # To use, run: |
645e1dd4b8ae
convert-repo: update usage information
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3911
diff
changeset
|
7 # |
3948
b58c1681d23b
Update convert-repo usage comments
Matt Mackall <mpm@selenic.com>
parents:
3947
diff
changeset
|
8 # convert-repo <source> [<dest> [<mapfile>]] |
3916
645e1dd4b8ae
convert-repo: update usage information
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3911
diff
changeset
|
9 # |
3954
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
10 # Currently accepted source formats: git, cvs |
3948
b58c1681d23b
Update convert-repo usage comments
Matt Mackall <mpm@selenic.com>
parents:
3947
diff
changeset
|
11 # Currently accepted destination formats: hg |
3916
645e1dd4b8ae
convert-repo: update usage information
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3911
diff
changeset
|
12 # |
3948
b58c1681d23b
Update convert-repo usage comments
Matt Mackall <mpm@selenic.com>
parents:
3947
diff
changeset
|
13 # If destination isn't given, a new Mercurial repo named <src>-hg will |
b58c1681d23b
Update convert-repo usage comments
Matt Mackall <mpm@selenic.com>
parents:
3947
diff
changeset
|
14 # be created. If <mapfile> isn't given, it will be put in a default |
b58c1681d23b
Update convert-repo usage comments
Matt Mackall <mpm@selenic.com>
parents:
3947
diff
changeset
|
15 # location (<dest>/.hg/shamap by default) |
316 | 16 # |
3948
b58c1681d23b
Update convert-repo usage comments
Matt Mackall <mpm@selenic.com>
parents:
3947
diff
changeset
|
17 # The <mapfile> is a simple text file that maps each source commit ID to |
b58c1681d23b
Update convert-repo usage comments
Matt Mackall <mpm@selenic.com>
parents:
3947
diff
changeset
|
18 # the destination ID for that revision, like so: |
b58c1681d23b
Update convert-repo usage comments
Matt Mackall <mpm@selenic.com>
parents:
3947
diff
changeset
|
19 # |
b58c1681d23b
Update convert-repo usage comments
Matt Mackall <mpm@selenic.com>
parents:
3947
diff
changeset
|
20 # <source ID> <destination ID> |
316 | 21 # |
3916
645e1dd4b8ae
convert-repo: update usage information
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3911
diff
changeset
|
22 # 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
|
23 # 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
|
24 # be run repeatedly to copy new commits. |
316 | 25 |
4047 | 26 import sys, os, zlib, sha, time, re, locale, socket |
3947
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
27 os.environ["HGENCODING"] = "utf-8" |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
28 from mercurial import hg, ui, util, fancyopts |
3825
158fce02dc40
Teach convert-repo to deal with mixed charsets in git
Matt Mackall <mpm@selenic.com>
parents:
2649
diff
changeset
|
29 |
3947
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
30 class Abort(Exception): pass |
3954
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
31 class NoRepo(Exception): pass |
3947
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
32 |
4447
af013ae3ca10
use documented convert-repo interface
Daniel Holth <dholth@fastmail.fm>
parents:
4446
diff
changeset
|
33 class commit(object): |
3955
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
34 def __init__(self, **parts): |
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
35 for x in "author date desc parents".split(): |
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
36 if not x in parts: |
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
37 abort("commit missing field %s\n" % x) |
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
38 self.__dict__.update(parts) |
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
39 |
3947
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
40 quiet = 0 |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
41 def status(msg): |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
42 if not quiet: sys.stdout.write(str(msg)) |
3825
158fce02dc40
Teach convert-repo to deal with mixed charsets in git
Matt Mackall <mpm@selenic.com>
parents:
2649
diff
changeset
|
43 |
3947
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
44 def warn(msg): |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
45 sys.stderr.write(str(msg)) |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
46 |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
47 def abort(msg): |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
48 raise Abort(msg) |
316 | 49 |
3825
158fce02dc40
Teach convert-repo to deal with mixed charsets in git
Matt Mackall <mpm@selenic.com>
parents:
2649
diff
changeset
|
50 def recode(s): |
158fce02dc40
Teach convert-repo to deal with mixed charsets in git
Matt Mackall <mpm@selenic.com>
parents:
2649
diff
changeset
|
51 try: |
158fce02dc40
Teach convert-repo to deal with mixed charsets in git
Matt Mackall <mpm@selenic.com>
parents:
2649
diff
changeset
|
52 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
|
53 except: |
158fce02dc40
Teach convert-repo to deal with mixed charsets in git
Matt Mackall <mpm@selenic.com>
parents:
2649
diff
changeset
|
54 try: |
158fce02dc40
Teach convert-repo to deal with mixed charsets in git
Matt Mackall <mpm@selenic.com>
parents:
2649
diff
changeset
|
55 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
|
56 except: |
158fce02dc40
Teach convert-repo to deal with mixed charsets in git
Matt Mackall <mpm@selenic.com>
parents:
2649
diff
changeset
|
57 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
|
58 |
4447
af013ae3ca10
use documented convert-repo interface
Daniel Holth <dholth@fastmail.fm>
parents:
4446
diff
changeset
|
59 class converter_source(object): |
4446
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
60 """Conversion source interface""" |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
61 |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
62 def __init__(self, path): |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
63 """Initialize conversion source (or raise NoRepo("message") |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
64 exception if path is not a valid repository)""" |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
65 raise NotImplementedError() |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
66 |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
67 def getheads(self): |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
68 """Return a list of this repository's heads""" |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
69 raise NotImplementedError() |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
70 |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
71 def getfile(self, name, rev): |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
72 """Return file contents as a string""" |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
73 raise NotImplementedError() |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
74 |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
75 def getmode(self, name, rev): |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
76 """Return file mode, eg. '', 'x', or 'l'""" |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
77 raise NotImplementedError() |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
78 |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
79 def getchanges(self, version): |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
80 """Return sorted list of (filename, id) tuples for all files changed in rev. |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
81 |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
82 id just tells us which revision to return in getfile(), e.g. in |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
83 git it's an object hash.""" |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
84 raise NotImplementedError() |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
85 |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
86 def getcommit(self, version): |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
87 """Return the commit object for version""" |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
88 raise NotImplementedError() |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
89 |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
90 def gettags(self): |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
91 """Return the tags as a dictionary of name: revision""" |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
92 raise NotImplementedError() |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
93 |
4447
af013ae3ca10
use documented convert-repo interface
Daniel Holth <dholth@fastmail.fm>
parents:
4446
diff
changeset
|
94 class converter_sink(object): |
4446
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
95 """Conversion sink (target) interface""" |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
96 |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
97 def __init__(self, path): |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
98 """Initialize conversion sink (or raise NoRepo("message") |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
99 exception if path is not a valid repository)""" |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
100 raise NotImplementedError() |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
101 |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
102 def getheads(self): |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
103 """Return a list of this repository's heads""" |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
104 raise NotImplementedError() |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
105 |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
106 def mapfile(self): |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
107 """Path to a file that will contain lines |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
108 source_rev_id sink_rev_id |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
109 mapping equivalent revision identifiers for each system.""" |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
110 raise NotImplementedError() |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
111 |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
112 def putfile(self, f, e, data): |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
113 """Put file for next putcommit(). |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
114 f: path to file |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
115 e: '', 'x', or 'l' (regular file, executable, or symlink) |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
116 data: file contents""" |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
117 raise NotImplementedError() |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
118 |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
119 def delfile(self, f): |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
120 """Delete file for next putcommit(). |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
121 f: path to file""" |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
122 raise NotImplementedError() |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
123 |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
124 def putcommit(self, files, parents, commit): |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
125 """Create a revision with all changed files listed in 'files' |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
126 and having listed parents. 'commit' is a commit object containing |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
127 at a minimum the author, date, and message for this changeset. |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
128 Called after putfile() and delfile() calls. Note that the sink |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
129 repository is not told to update itself to a particular revision |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
130 (or even what that revision would be) before it receives the |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
131 file data.""" |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
132 raise NotImplementedError() |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
133 |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
134 def puttags(self, tags): |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
135 """Put tags into sink. |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
136 tags: {tagname: sink_rev_id, ...}""" |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
137 raise NotImplementedError() |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
138 |
1b75e0eff532
document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents:
4114
diff
changeset
|
139 |
3954
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
140 # CVS conversion code inspired by hg-cvs-import and git-cvsimport |
4447
af013ae3ca10
use documented convert-repo interface
Daniel Holth <dholth@fastmail.fm>
parents:
4446
diff
changeset
|
141 class convert_cvs(converter_source): |
3954
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
142 def __init__(self, path): |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
143 self.path = path |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
144 cvs = os.path.join(path, "CVS") |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
145 if not os.path.exists(cvs): |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
146 raise NoRepo("couldn't open CVS repo %s" % path) |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
147 |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
148 self.changeset = {} |
3955
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
149 self.files = {} |
3954
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
150 self.tags = {} |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
151 self.lastbranch = {} |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
152 self.parent = {} |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
153 self.socket = None |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
154 self.cvsroot = file(os.path.join(cvs, "Root")).read()[:-1] |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
155 self.cvsrepo = file(os.path.join(cvs, "Repository")).read()[:-1] |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
156 self.encoding = locale.getpreferredencoding() |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
157 self._parse() |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
158 self._connect() |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
159 |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
160 def _parse(self): |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
161 if self.changeset: |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
162 return |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
163 |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
164 d = os.getcwd() |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
165 try: |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
166 os.chdir(self.path) |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
167 id = None |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
168 state = 0 |
4109
59de487f43d7
Change a bit cvsps arguments
Edouard Gomez <ed.gomez@free.fr>
parents:
4082
diff
changeset
|
169 for l in os.popen("cvsps -A -u --cvs-direct -q"): |
3954
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
170 if state == 0: # header |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
171 if l.startswith("PatchSet"): |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
172 id = l[9:-2] |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
173 elif l.startswith("Date"): |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
174 date = util.parsedate(l[6:-1], ["%Y/%m/%d %H:%M:%S"]) |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
175 date = util.datestr(date) |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
176 elif l.startswith("Branch"): |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
177 branch = l[8:-1] |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
178 self.parent[id] = self.lastbranch.get(branch,'bad') |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
179 self.lastbranch[branch] = id |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
180 elif l.startswith("Ancestor branch"): |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
181 ancestor = l[17:-1] |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
182 self.parent[id] = self.lastbranch[ancestor] |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
183 elif l.startswith("Author"): |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
184 author = self.recode(l[8:-1]) |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
185 elif l.startswith("Tag: "): |
4110
b53c6f7dbb1f
Don't keep trailing white space in cvs tags
Edouard Gomez <ed.gomez@free.fr>
parents:
4109
diff
changeset
|
186 t = l[5:-1].rstrip() |
b53c6f7dbb1f
Don't keep trailing white space in cvs tags
Edouard Gomez <ed.gomez@free.fr>
parents:
4109
diff
changeset
|
187 if t != "(none)": |
3954
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
188 self.tags[t] = id |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
189 elif l.startswith("Log:"): |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
190 state = 1 |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
191 log = "" |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
192 elif state == 1: # log |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
193 if l == "Members: \n": |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
194 files = {} |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
195 log = self.recode(log[:-1]) |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
196 if log.isspace(): |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
197 log = "*** empty log message ***\n" |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
198 state = 2 |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
199 else: |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
200 log += l |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
201 elif state == 2: |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
202 if l == "\n": # |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
203 state = 0 |
3955
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
204 p = [self.parent[id]] |
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
205 if id == "1": |
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
206 p = [] |
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
207 c = commit(author=author, date=date, parents=p, |
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
208 desc=log, branch=branch) |
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
209 self.changeset[id] = c |
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
210 self.files[id] = files |
3954
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
211 else: |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
212 file,rev = l[1:-2].rsplit(':',1) |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
213 rev = rev.split("->")[1] |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
214 files[file] = rev |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
215 |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
216 self.heads = self.lastbranch.values() |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
217 finally: |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
218 os.chdir(d) |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
219 |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
220 def _connect(self): |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
221 root = self.cvsroot |
4047 | 222 conntype = None |
3954
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
223 user, host = None, None |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
224 cmd = ['cvs', 'server'] |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
225 |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
226 status("connecting to %s\n" % root) |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
227 |
4047 | 228 if root.startswith(":pserver:"): |
229 root = root[9:] | |
230 m = re.match(r'(?:(.*?)(?::(.*?))?@)?([^:\/]*)(?::(\d*))?(.*)', root) | |
231 if m: | |
232 conntype = "pserver" | |
233 user, passw, serv, port, root = m.groups() | |
234 if not user: | |
235 user = "anonymous" | |
236 rr = ":pserver:" + user + "@" + serv + ":" + root | |
237 if port: | |
238 rr2, port = "-", int(port) | |
239 else: | |
240 rr2, port = rr, 2401 | |
241 rr += str(port) | |
3954
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
242 |
4047 | 243 if not passw: |
244 passw = "A" | |
245 pf = open(os.path.join(os.environ["HOME"], ".cvspass")) | |
246 for l in pf: | |
247 # :pserver:cvs@mea.tmt.tele.fi:/cvsroot/zmailer Ah<Z | |
248 m = re.match(r'(/\d+\s+/)?(.*)', l) | |
249 l = m.group(2) | |
250 w, p = l.split(' ', 1) | |
251 if w in [rr, rr2]: | |
252 passw = p | |
253 break | |
254 pf.close() | |
255 | |
256 sck = socket.socket() | |
257 sck.connect((serv, port)) | |
258 sck.send("\n".join(["BEGIN AUTH REQUEST", root, user, passw, "END AUTH REQUEST", ""])) | |
259 if sck.recv(128) != "I LOVE YOU\n": | |
260 raise NoRepo("CVS pserver authentication failed") | |
261 | |
262 self.writep = self.readp = sck.makefile('r+') | |
263 | |
264 if not conntype and root.startswith(":local:"): | |
265 conntype = "local" | |
3954
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
266 root = root[7:] |
4047 | 267 |
268 if not conntype: | |
3954
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
269 # :ext:user@host/home/user/path/to/cvsroot |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
270 if root.startswith(":ext:"): |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
271 root = root[5:] |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
272 m = re.match(r'(?:([^@:/]+)@)?([^:/]+):?(.*)', root) |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
273 if not m: |
4047 | 274 conntype = "local" |
3954
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
275 else: |
4047 | 276 conntype = "rsh" |
3954
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
277 user, host, root = m.group(1), m.group(2), m.group(3) |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
278 |
4047 | 279 if conntype != "pserver": |
280 if conntype == "rsh": | |
281 rsh = os.environ.get("CVS_RSH" or "rsh") | |
282 if user: | |
283 cmd = [rsh, '-l', user, host] + cmd | |
284 else: | |
285 cmd = [rsh, host] + cmd | |
3954
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
286 |
4047 | 287 self.writep, self.readp = os.popen2(cmd) |
288 | |
3954
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
289 self.realroot = root |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
290 |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
291 self.writep.write("Root %s\n" % root) |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
292 self.writep.write("Valid-responses ok error Valid-requests Mode" |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
293 " M Mbinary E Checked-in Created Updated" |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
294 " Merged Removed\n") |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
295 self.writep.write("valid-requests\n") |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
296 self.writep.flush() |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
297 r = self.readp.readline() |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
298 if not r.startswith("Valid-requests"): |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
299 abort("server sucks\n") |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
300 if "UseUnchanged" in r: |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
301 self.writep.write("UseUnchanged\n") |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
302 self.writep.flush() |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
303 r = self.readp.readline() |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
304 |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
305 def getheads(self): |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
306 return self.heads |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
307 |
3957
558f52943cd2
convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents:
3955
diff
changeset
|
308 def _getfile(self, name, rev): |
3954
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
309 if rev.endswith("(DEAD)"): |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
310 raise IOError |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
311 |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
312 args = ("-N -P -kk -r %s --" % rev).split() |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
313 args.append(os.path.join(self.cvsrepo, name)) |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
314 for x in args: |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
315 self.writep.write("Argument %s\n" % x) |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
316 self.writep.write("Directory .\n%s\nco\n" % self.realroot) |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
317 self.writep.flush() |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
318 |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
319 data = "" |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
320 while 1: |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
321 line = self.readp.readline() |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
322 if line.startswith("Created ") or line.startswith("Updated "): |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
323 self.readp.readline() # path |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
324 self.readp.readline() # entries |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
325 mode = self.readp.readline()[:-1] |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
326 count = int(self.readp.readline()[:-1]) |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
327 data = self.readp.read(count) |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
328 elif line.startswith(" "): |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
329 data += line[1:] |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
330 elif line.startswith("M "): |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
331 pass |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
332 elif line.startswith("Mbinary "): |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
333 count = int(self.readp.readline()[:-1]) |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
334 data = self.readp.read(count) |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
335 else: |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
336 if line == "ok\n": |
4082
6b2909e84203
convert-repo converts symlinks from git
Daniel Holth <dholth@fastmail.fm>
parents:
4062
diff
changeset
|
337 return (data, "x" in mode and "x" or "") |
3954
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
338 elif line.startswith("E "): |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
339 warn("cvs server: %s\n" % line[2:]) |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
340 elif line.startswith("Remove"): |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
341 l = self.readp.readline() |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
342 l = self.readp.readline() |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
343 if l != "ok\n": |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
344 abort("unknown CVS response: %s\n" % l) |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
345 else: |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
346 abort("unknown CVS response: %s\n" % line) |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
347 |
3957
558f52943cd2
convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents:
3955
diff
changeset
|
348 def getfile(self, file, rev): |
558f52943cd2
convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents:
3955
diff
changeset
|
349 data, mode = self._getfile(file, rev) |
558f52943cd2
convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents:
3955
diff
changeset
|
350 self.modecache[(file, rev)] = mode |
558f52943cd2
convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents:
3955
diff
changeset
|
351 return data |
558f52943cd2
convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents:
3955
diff
changeset
|
352 |
558f52943cd2
convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents:
3955
diff
changeset
|
353 def getmode(self, file, rev): |
558f52943cd2
convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents:
3955
diff
changeset
|
354 return self.modecache[(file, rev)] |
558f52943cd2
convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents:
3955
diff
changeset
|
355 |
3954
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
356 def getchanges(self, rev): |
3957
558f52943cd2
convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents:
3955
diff
changeset
|
357 self.modecache = {} |
3955
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
358 files = self.files[rev] |
3957
558f52943cd2
convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents:
3955
diff
changeset
|
359 cl = files.items() |
3954
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
360 cl.sort() |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
361 return cl |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
362 |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
363 def recode(self, text): |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
364 return text.decode(self.encoding, "replace").encode("utf-8") |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
365 |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
366 def getcommit(self, rev): |
3955
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
367 return self.changeset[rev] |
3954
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
368 |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
369 def gettags(self): |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
370 return self.tags |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
371 |
4447
af013ae3ca10
use documented convert-repo interface
Daniel Holth <dholth@fastmail.fm>
parents:
4446
diff
changeset
|
372 class convert_git(converter_source): |
316 | 373 def __init__(self, path): |
3947
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
374 if os.path.isdir(path + "/.git"): |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
375 path += "/.git" |
316 | 376 self.path = path |
4111
06d65498f73b
convert-repo: use .git/objects/ rather than .git/HEAD to detect git repos
Matt Mackall <mpm@selenic.com>
parents:
4082
diff
changeset
|
377 if not os.path.exists(path + "/objects"): |
3954
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
378 raise NoRepo("couldn't open GIT repo %s" % path) |
316 | 379 |
380 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
|
381 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
|
382 return [fh.read()[:-1]] |
316 | 383 |
692
695dd9a491da
convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents:
450
diff
changeset
|
384 def catfile(self, rev, type): |
695dd9a491da
convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents:
450
diff
changeset
|
385 if rev == "0" * 40: raise IOError() |
1335
bea6356b8bca
git -> hg conversion script
Florian La Roche <laroche@redhat.com>
parents:
1237
diff
changeset
|
386 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
|
387 return fh.read() |
695dd9a491da
convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents:
450
diff
changeset
|
388 |
316 | 389 def getfile(self, name, rev): |
692
695dd9a491da
convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents:
450
diff
changeset
|
390 return self.catfile(rev, "blob") |
316 | 391 |
3957
558f52943cd2
convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents:
3955
diff
changeset
|
392 def getmode(self, name, rev): |
558f52943cd2
convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents:
3955
diff
changeset
|
393 return self.modecache[(name, rev)] |
558f52943cd2
convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents:
3955
diff
changeset
|
394 |
316 | 395 def getchanges(self, version): |
3957
558f52943cd2
convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents:
3955
diff
changeset
|
396 self.modecache = {} |
1335
bea6356b8bca
git -> hg conversion script
Florian La Roche <laroche@redhat.com>
parents:
1237
diff
changeset
|
397 fh = os.popen("GIT_DIR=%s git-diff-tree --root -m -r %s" % (self.path, version)) |
316 | 398 changes = [] |
399 for l in fh: | |
400 if "\t" not in l: continue | |
401 m, f = l[:-1].split("\t") | |
402 m = m.split() | |
403 h = m[3] | |
404 p = (m[1] == "100755") | |
4082
6b2909e84203
convert-repo converts symlinks from git
Daniel Holth <dholth@fastmail.fm>
parents:
4062
diff
changeset
|
405 s = (m[1] == "120000") |
6b2909e84203
convert-repo converts symlinks from git
Daniel Holth <dholth@fastmail.fm>
parents:
4062
diff
changeset
|
406 self.modecache[(f, h)] = (p and "x") or (s and "l") or "" |
3957
558f52943cd2
convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents:
3955
diff
changeset
|
407 changes.append((f, h)) |
316 | 408 return changes |
409 | |
410 def getcommit(self, version): | |
692
695dd9a491da
convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents:
450
diff
changeset
|
411 c = self.catfile(version, "commit") # read the commit hash |
316 | 412 end = c.find("\n\n") |
413 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
|
414 message = recode(message) |
316 | 415 l = c[:end].splitlines() |
416 manifest = l[0].split()[1] | |
417 parents = [] | |
418 for e in l[1:]: | |
419 n,v = e.split(" ", 1) | |
420 if n == "author": | |
421 p = v.split() | |
1385
adb3de56635b
convert-repo: Fix timezone handling
Matt Mackall <mpm@selenic.com>
parents:
1335
diff
changeset
|
422 tm, tz = p[-2:] |
316 | 423 author = " ".join(p[:-2]) |
424 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
|
425 author = recode(author) |
692
695dd9a491da
convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents:
450
diff
changeset
|
426 if n == "committer": |
431 | 427 p = v.split() |
1385
adb3de56635b
convert-repo: Fix timezone handling
Matt Mackall <mpm@selenic.com>
parents:
1335
diff
changeset
|
428 tm, tz = p[-2:] |
431 | 429 committer = " ".join(p[:-2]) |
430 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
|
431 committer = recode(committer) |
3910
4bc5a2405b12
convert-repo: fix recoding of committer
Matt Mackall <mpm@selenic.com>
parents:
3825
diff
changeset
|
432 message += "\ncommitter: %s\n" % committer |
316 | 433 if n == "parent": parents.append(v) |
1385
adb3de56635b
convert-repo: Fix timezone handling
Matt Mackall <mpm@selenic.com>
parents:
1335
diff
changeset
|
434 |
adb3de56635b
convert-repo: Fix timezone handling
Matt Mackall <mpm@selenic.com>
parents:
1335
diff
changeset
|
435 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
|
436 tz = -int(tzs) * (int(tzh) * 3600 + int(tzm)) |
1385
adb3de56635b
convert-repo: Fix timezone handling
Matt Mackall <mpm@selenic.com>
parents:
1335
diff
changeset
|
437 date = tm + " " + str(tz) |
3955
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
438 |
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
439 c = commit(parents=parents, date=date, author=author, desc=message) |
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
440 return c |
316 | 441 |
694 | 442 def gettags(self): |
443 tags = {} | |
4062
516f883e3d79
convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4047
diff
changeset
|
444 fh = os.popen('git-ls-remote --tags "%s" 2>/dev/null' % self.path) |
516f883e3d79
convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4047
diff
changeset
|
445 prefix = 'refs/tags/' |
516f883e3d79
convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4047
diff
changeset
|
446 for line in fh: |
516f883e3d79
convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4047
diff
changeset
|
447 line = line.strip() |
516f883e3d79
convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4047
diff
changeset
|
448 if not line.endswith("^{}"): |
516f883e3d79
convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4047
diff
changeset
|
449 continue |
516f883e3d79
convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4047
diff
changeset
|
450 node, tag = line.split(None, 1) |
516f883e3d79
convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4047
diff
changeset
|
451 if not tag.startswith(prefix): |
516f883e3d79
convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4047
diff
changeset
|
452 continue |
516f883e3d79
convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4047
diff
changeset
|
453 tag = tag[len(prefix):-3] |
516f883e3d79
convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4047
diff
changeset
|
454 tags[tag] = node |
516f883e3d79
convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4047
diff
changeset
|
455 |
694 | 456 return tags |
457 | |
4447
af013ae3ca10
use documented convert-repo interface
Daniel Holth <dholth@fastmail.fm>
parents:
4446
diff
changeset
|
458 class convert_mercurial(converter_sink): |
316 | 459 def __init__(self, path): |
460 self.path = path | |
461 u = ui.ui() | |
3947
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
462 try: |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
463 self.repo = hg.repository(u, path) |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
464 except: |
3954
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
465 raise NoRepo("could open hg repo %s" % path) |
3947
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
466 |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
467 def mapfile(self): |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
468 return os.path.join(self.path, ".hg", "shamap") |
316 | 469 |
470 def getheads(self): | |
471 h = self.repo.changelog.heads() | |
1335
bea6356b8bca
git -> hg conversion script
Florian La Roche <laroche@redhat.com>
parents:
1237
diff
changeset
|
472 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
|
473 |
316 | 474 def putfile(self, f, e, data): |
4082
6b2909e84203
convert-repo converts symlinks from git
Daniel Holth <dholth@fastmail.fm>
parents:
4062
diff
changeset
|
475 self.repo.wwrite(f, data, e) |
692
695dd9a491da
convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents:
450
diff
changeset
|
476 if self.repo.dirstate.state(f) == '?': |
695dd9a491da
convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents:
450
diff
changeset
|
477 self.repo.dirstate.update([f], "a") |
695dd9a491da
convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents:
450
diff
changeset
|
478 |
316 | 479 def delfile(self, f): |
480 try: | |
481 os.unlink(self.repo.wjoin(f)) | |
692
695dd9a491da
convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents:
450
diff
changeset
|
482 #self.repo.remove([f]) |
316 | 483 except: |
484 pass | |
485 | |
3955
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
486 def putcommit(self, files, parents, commit): |
431 | 487 seen = {} |
488 pl = [] | |
489 for p in parents: | |
490 if p not in seen: | |
491 pl.append(p) | |
492 seen[p] = 1 | |
493 parents = pl | |
316 | 494 |
692
695dd9a491da
convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents:
450
diff
changeset
|
495 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
|
496 if len(parents) < 2: parents.append("0" * 40) |
431 | 497 p2 = parents.pop(0) |
692
695dd9a491da
convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents:
450
diff
changeset
|
498 |
3955
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
499 text = commit.desc |
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
500 extra = {} |
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
501 try: |
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
502 extra["branch"] = commit.branch |
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
503 except AttributeError: |
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
504 pass |
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
505 |
431 | 506 while parents: |
507 p1 = p2 | |
508 p2 = parents.pop(0) | |
3955
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
509 a = self.repo.rawcommit(files, text, commit.author, commit.date, |
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
510 hg.bin(p1), hg.bin(p2), extra=extra) |
431 | 511 text = "(octopus merge fixup)\n" |
1389
9b3ef6f3cef5
convert-repo: fix up octopus merge conversion
Matt Mackall <mpm@selenic.com>
parents:
1388
diff
changeset
|
512 p2 = hg.hex(self.repo.changelog.tip()) |
431 | 513 |
1389
9b3ef6f3cef5
convert-repo: fix up octopus merge conversion
Matt Mackall <mpm@selenic.com>
parents:
1388
diff
changeset
|
514 return p2 |
316 | 515 |
694 | 516 def puttags(self, tags): |
517 try: | |
518 old = self.repo.wfile(".hgtags").read() | |
519 oldlines = old.splitlines(1) | |
520 oldlines.sort() | |
521 except: | |
522 oldlines = [] | |
523 | |
524 k = tags.keys() | |
525 k.sort() | |
526 newlines = [] | |
527 for tag in k: | |
528 newlines.append("%s %s\n" % (tags[tag], tag)) | |
529 | |
530 newlines.sort() | |
531 | |
532 if newlines != oldlines: | |
3947
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
533 status("updating tags\n") |
694 | 534 f = self.repo.wfile(".hgtags", "w") |
535 f.write("".join(newlines)) | |
536 f.close() | |
537 if not oldlines: self.repo.add([".hgtags"]) | |
1335
bea6356b8bca
git -> hg conversion script
Florian La Roche <laroche@redhat.com>
parents:
1237
diff
changeset
|
538 date = "%s 0" % int(time.mktime(time.gmtime())) |
694 | 539 self.repo.rawcommit([".hgtags"], "update tags", "convert-repo", |
540 date, self.repo.changelog.tip(), hg.nullid) | |
1387
0c7e8d345564
convert-repo: linearize the tag commit
Matt Mackall <mpm@selenic.com>
parents:
1386
diff
changeset
|
541 return hg.hex(self.repo.changelog.tip()) |
694 | 542 |
3954
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
543 converters = [convert_cvs, convert_git, convert_mercurial] |
3947
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
544 |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
545 def converter(path): |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
546 if not os.path.isdir(path): |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
547 abort("%s: not a directory\n" % path) |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
548 for c in converters: |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
549 try: |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
550 return c(path) |
3954
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
551 except NoRepo: |
3947
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
552 pass |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
553 abort("%s: unknown repository type\n" % path) |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
554 |
4447
af013ae3ca10
use documented convert-repo interface
Daniel Holth <dholth@fastmail.fm>
parents:
4446
diff
changeset
|
555 class convert(object): |
3958
2b87d3c5ab8e
convert-repo: add option to attempt to sort by date
Matt Mackall <mpm@selenic.com>
parents:
3957
diff
changeset
|
556 def __init__(self, source, dest, mapfile, opts): |
3947
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
557 |
316 | 558 self.source = source |
559 self.dest = dest | |
560 self.mapfile = mapfile | |
3958
2b87d3c5ab8e
convert-repo: add option to attempt to sort by date
Matt Mackall <mpm@selenic.com>
parents:
3957
diff
changeset
|
561 self.opts = opts |
316 | 562 self.commitcache = {} |
563 | |
564 self.map = {} | |
1655
7bfd4724932a
convert-repo: automatically create empty map file
Matt Mackall <mpm@selenic.com>
parents:
1389
diff
changeset
|
565 try: |
7bfd4724932a
convert-repo: automatically create empty map file
Matt Mackall <mpm@selenic.com>
parents:
1389
diff
changeset
|
566 for l in file(self.mapfile): |
7bfd4724932a
convert-repo: automatically create empty map file
Matt Mackall <mpm@selenic.com>
parents:
1389
diff
changeset
|
567 sv, dv = l[:-1].split() |
7bfd4724932a
convert-repo: automatically create empty map file
Matt Mackall <mpm@selenic.com>
parents:
1389
diff
changeset
|
568 self.map[sv] = dv |
7bfd4724932a
convert-repo: automatically create empty map file
Matt Mackall <mpm@selenic.com>
parents:
1389
diff
changeset
|
569 except IOError: |
7bfd4724932a
convert-repo: automatically create empty map file
Matt Mackall <mpm@selenic.com>
parents:
1389
diff
changeset
|
570 pass |
316 | 571 |
572 def walktree(self, heads): | |
573 visit = heads | |
574 known = {} | |
575 parents = {} | |
576 while visit: | |
577 n = visit.pop(0) | |
578 if n in known or n in self.map: continue | |
579 known[n] = 1 | |
580 self.commitcache[n] = self.source.getcommit(n) | |
3955
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
581 cp = self.commitcache[n].parents |
316 | 582 for p in cp: |
583 parents.setdefault(n, []).append(p) | |
584 visit.append(p) | |
585 | |
586 return parents | |
587 | |
588 def toposort(self, parents): | |
589 visit = parents.keys() | |
590 seen = {} | |
591 children = {} | |
692
695dd9a491da
convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents:
450
diff
changeset
|
592 |
316 | 593 while visit: |
594 n = visit.pop(0) | |
595 if n in seen: continue | |
596 seen[n] = 1 | |
597 pc = 0 | |
598 if n in parents: | |
599 for p in parents[n]: | |
600 if p not in self.map: pc += 1 | |
601 visit.append(p) | |
602 children.setdefault(p, []).append(n) | |
603 if not pc: root = n | |
604 | |
605 s = [] | |
606 removed = {} | |
692
695dd9a491da
convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents:
450
diff
changeset
|
607 visit = children.keys() |
316 | 608 while visit: |
609 n = visit.pop(0) | |
610 if n in removed: continue | |
611 dep = 0 | |
612 if n in parents: | |
613 for p in parents[n]: | |
614 if p in self.map: continue | |
615 if p not in removed: | |
616 # we're still dependent | |
617 visit.append(n) | |
618 dep = 1 | |
619 break | |
620 | |
621 if not dep: | |
622 # all n's parents are in the list | |
623 removed[n] = 1 | |
3958
2b87d3c5ab8e
convert-repo: add option to attempt to sort by date
Matt Mackall <mpm@selenic.com>
parents:
3957
diff
changeset
|
624 if n not in self.map: |
2b87d3c5ab8e
convert-repo: add option to attempt to sort by date
Matt Mackall <mpm@selenic.com>
parents:
3957
diff
changeset
|
625 s.append(n) |
316 | 626 if n in children: |
627 for c in children[n]: | |
628 visit.insert(0, c) | |
629 | |
3958
2b87d3c5ab8e
convert-repo: add option to attempt to sort by date
Matt Mackall <mpm@selenic.com>
parents:
3957
diff
changeset
|
630 if opts.get('datesort'): |
2b87d3c5ab8e
convert-repo: add option to attempt to sort by date
Matt Mackall <mpm@selenic.com>
parents:
3957
diff
changeset
|
631 depth = {} |
2b87d3c5ab8e
convert-repo: add option to attempt to sort by date
Matt Mackall <mpm@selenic.com>
parents:
3957
diff
changeset
|
632 for n in s: |
2b87d3c5ab8e
convert-repo: add option to attempt to sort by date
Matt Mackall <mpm@selenic.com>
parents:
3957
diff
changeset
|
633 depth[n] = 0 |
2b87d3c5ab8e
convert-repo: add option to attempt to sort by date
Matt Mackall <mpm@selenic.com>
parents:
3957
diff
changeset
|
634 pl = [p for p in self.commitcache[n].parents if p not in self.map] |
2b87d3c5ab8e
convert-repo: add option to attempt to sort by date
Matt Mackall <mpm@selenic.com>
parents:
3957
diff
changeset
|
635 if pl: |
2b87d3c5ab8e
convert-repo: add option to attempt to sort by date
Matt Mackall <mpm@selenic.com>
parents:
3957
diff
changeset
|
636 depth[n] = max([depth[p] for p in pl]) + 1 |
2b87d3c5ab8e
convert-repo: add option to attempt to sort by date
Matt Mackall <mpm@selenic.com>
parents:
3957
diff
changeset
|
637 |
2b87d3c5ab8e
convert-repo: add option to attempt to sort by date
Matt Mackall <mpm@selenic.com>
parents:
3957
diff
changeset
|
638 s = [(depth[n], self.commitcache[n].date, n) for n in s] |
2b87d3c5ab8e
convert-repo: add option to attempt to sort by date
Matt Mackall <mpm@selenic.com>
parents:
3957
diff
changeset
|
639 s.sort() |
2b87d3c5ab8e
convert-repo: add option to attempt to sort by date
Matt Mackall <mpm@selenic.com>
parents:
3957
diff
changeset
|
640 s = [e[2] for e in s] |
2b87d3c5ab8e
convert-repo: add option to attempt to sort by date
Matt Mackall <mpm@selenic.com>
parents:
3957
diff
changeset
|
641 |
316 | 642 return s |
643 | |
644 def copy(self, rev): | |
3955
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
645 c = self.commitcache[rev] |
316 | 646 files = self.source.getchanges(rev) |
647 | |
3957
558f52943cd2
convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents:
3955
diff
changeset
|
648 for f,v in files: |
316 | 649 try: |
650 data = self.source.getfile(f, v) | |
651 except IOError, inst: | |
652 self.dest.delfile(f) | |
653 else: | |
3957
558f52943cd2
convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents:
3955
diff
changeset
|
654 e = self.source.getmode(f, v) |
316 | 655 self.dest.putfile(f, e, data) |
656 | |
3955
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
657 r = [self.map[v] for v in c.parents] |
3957
558f52943cd2
convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents:
3955
diff
changeset
|
658 f = [f for f,v in files] |
3955
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
659 self.map[rev] = self.dest.putcommit(f, r, c) |
316 | 660 file(self.mapfile, "a").write("%s %s\n" % (rev, self.map[rev])) |
661 | |
662 def convert(self): | |
3947
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
663 status("scanning source...\n") |
316 | 664 heads = self.source.getheads() |
665 parents = self.walktree(heads) | |
3947
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
666 status("sorting...\n") |
316 | 667 t = self.toposort(parents) |
668 num = len(t) | |
1715
40346aa66b0f
Revert convert-repo changes
Matt Mackall <mpm@selenic.com>
parents:
1656
diff
changeset
|
669 c = None |
316 | 670 |
3947
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
671 status("converting...\n") |
316 | 672 for c in t: |
673 num -= 1 | |
3955
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
674 desc = self.commitcache[c].desc |
3954
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
675 if "\n" in desc: |
fad134931327
convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents:
3948
diff
changeset
|
676 desc = desc.splitlines()[0] |
3947
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
677 status("%d %s\n" % (num, desc)) |
316 | 678 self.copy(c) |
679 | |
694 | 680 tags = self.source.gettags() |
681 ctags = {} | |
682 for k in tags: | |
683 v = tags[k] | |
684 if v in self.map: | |
685 ctags[k] = self.map[v] | |
686 | |
1715
40346aa66b0f
Revert convert-repo changes
Matt Mackall <mpm@selenic.com>
parents:
1656
diff
changeset
|
687 if c and ctags: |
1387
0c7e8d345564
convert-repo: linearize the tag commit
Matt Mackall <mpm@selenic.com>
parents:
1386
diff
changeset
|
688 nrev = self.dest.puttags(ctags) |
0c7e8d345564
convert-repo: linearize the tag commit
Matt Mackall <mpm@selenic.com>
parents:
1386
diff
changeset
|
689 # write another hash correspondence to override the previous |
0c7e8d345564
convert-repo: linearize the tag commit
Matt Mackall <mpm@selenic.com>
parents:
1386
diff
changeset
|
690 # 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
|
691 if nrev: |
fe075ddf3272
convert-repo: avoid adding bogus value to shamap on tag update
Matt Mackall <mpm@selenic.com>
parents:
3910
diff
changeset
|
692 file(self.mapfile, "a").write("%s %s\n" % (c, nrev)) |
694 | 693 |
3947
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
694 def command(src, dest=None, mapfile=None, **opts): |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
695 srcc = converter(src) |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
696 if not hasattr(srcc, "getcommit"): |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
697 abort("%s: can't read from this repo type\n" % src) |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
698 |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
699 if not dest: |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
700 dest = src + "-hg" |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
701 status("assuming destination %s\n" % dest) |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
702 if not os.path.isdir(dest): |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
703 status("creating repository %s\n" % dest) |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
704 os.system("hg init " + dest) |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
705 destc = converter(dest) |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
706 if not hasattr(destc, "putcommit"): |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
707 abort("%s: can't write to this repo type\n" % src) |
316 | 708 |
3947
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
709 if not mapfile: |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
710 try: |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
711 mapfile = destc.mapfile() |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
712 except: |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
713 mapfile = os.path.join(destc, "map") |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
714 |
3958
2b87d3c5ab8e
convert-repo: add option to attempt to sort by date
Matt Mackall <mpm@selenic.com>
parents:
3957
diff
changeset
|
715 c = convert(srcc, destc, mapfile, opts) |
3947
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
716 c.convert() |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
717 |
3958
2b87d3c5ab8e
convert-repo: add option to attempt to sort by date
Matt Mackall <mpm@selenic.com>
parents:
3957
diff
changeset
|
718 options = [('q', 'quiet', None, 'suppress output'), |
2b87d3c5ab8e
convert-repo: add option to attempt to sort by date
Matt Mackall <mpm@selenic.com>
parents:
3957
diff
changeset
|
719 ('', 'datesort', None, 'try to sort changesets by date')] |
3947
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
720 opts = {} |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
721 args = fancyopts.fancyopts(sys.argv[1:], options, opts) |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
722 |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
723 if opts['quiet']: |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
724 quiet = 1 |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
725 |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
726 try: |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
727 command(*args, **opts) |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
728 except Abort, inst: |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
729 warn(inst) |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
730 except KeyboardInterrupt: |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
731 status("interrupted\n") |