53 except: |
53 except: |
54 try: |
54 try: |
55 return s.decode("latin-1").encode("utf-8") |
55 return s.decode("latin-1").encode("utf-8") |
56 except: |
56 except: |
57 return s.decode("utf-8", "replace").encode("utf-8") |
57 return s.decode("utf-8", "replace").encode("utf-8") |
|
58 |
|
59 class converter_source: |
|
60 """Conversion source interface""" |
|
61 |
|
62 def __init__(self, path): |
|
63 """Initialize conversion source (or raise NoRepo("message") |
|
64 exception if path is not a valid repository)""" |
|
65 raise NotImplementedError() |
|
66 |
|
67 def getheads(self): |
|
68 """Return a list of this repository's heads""" |
|
69 raise NotImplementedError() |
|
70 |
|
71 def getfile(self, name, rev): |
|
72 """Return file contents as a string""" |
|
73 raise NotImplementedError() |
|
74 |
|
75 def getmode(self, name, rev): |
|
76 """Return file mode, eg. '', 'x', or 'l'""" |
|
77 raise NotImplementedError() |
|
78 |
|
79 def getchanges(self, version): |
|
80 """Return sorted list of (filename, id) tuples for all files changed in rev. |
|
81 |
|
82 id just tells us which revision to return in getfile(), e.g. in |
|
83 git it's an object hash.""" |
|
84 raise NotImplementedError() |
|
85 |
|
86 def getcommit(self, version): |
|
87 """Return the commit object for version""" |
|
88 raise NotImplementedError() |
|
89 |
|
90 def gettags(self): |
|
91 """Return the tags as a dictionary of name: revision""" |
|
92 raise NotImplementedError() |
|
93 |
|
94 class converter_sink: |
|
95 """Conversion sink (target) interface""" |
|
96 |
|
97 def __init__(self, path): |
|
98 """Initialize conversion sink (or raise NoRepo("message") |
|
99 exception if path is not a valid repository)""" |
|
100 raise NotImplementedError() |
|
101 |
|
102 def getheads(self): |
|
103 """Return a list of this repository's heads""" |
|
104 raise NotImplementedError() |
|
105 |
|
106 def mapfile(self): |
|
107 """Path to a file that will contain lines |
|
108 source_rev_id sink_rev_id |
|
109 mapping equivalent revision identifiers for each system.""" |
|
110 raise NotImplementedError() |
|
111 |
|
112 def putfile(self, f, e, data): |
|
113 """Put file for next putcommit(). |
|
114 f: path to file |
|
115 e: '', 'x', or 'l' (regular file, executable, or symlink) |
|
116 data: file contents""" |
|
117 raise NotImplementedError() |
|
118 |
|
119 def delfile(self, f): |
|
120 """Delete file for next putcommit(). |
|
121 f: path to file""" |
|
122 raise NotImplementedError() |
|
123 |
|
124 def putcommit(self, files, parents, commit): |
|
125 """Create a revision with all changed files listed in 'files' |
|
126 and having listed parents. 'commit' is a commit object containing |
|
127 at a minimum the author, date, and message for this changeset. |
|
128 Called after putfile() and delfile() calls. Note that the sink |
|
129 repository is not told to update itself to a particular revision |
|
130 (or even what that revision would be) before it receives the |
|
131 file data.""" |
|
132 raise NotImplementedError() |
|
133 |
|
134 def puttags(self, tags): |
|
135 """Put tags into sink. |
|
136 tags: {tagname: sink_rev_id, ...}""" |
|
137 raise NotImplementedError() |
|
138 |
58 |
139 |
59 # CVS conversion code inspired by hg-cvs-import and git-cvsimport |
140 # CVS conversion code inspired by hg-cvs-import and git-cvsimport |
60 class convert_cvs: |
141 class convert_cvs: |
61 def __init__(self, path): |
142 def __init__(self, path): |
62 self.path = path |
143 self.path = path |