Merge lp:~jelmer/brz/git-no-file-id into lp:brz
- git-no-file-id
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~jelmer/brz/git-no-file-id |
Merge into: | lp:brz |
Diff against target: |
498 lines (+70/-105) 5 files modified
breezy/git/commit.py (+3/-4) breezy/git/tree.py (+51/-88) breezy/git/workingtree.py (+8/-11) breezy/transport/http/__init__.py (+1/-0) byov.conf (+7/-2) |
To merge this branch: | bzr merge lp:~jelmer/brz/git-no-file-id |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Martin Packman | Approve | ||
Review via email: mp+373055@code.launchpad.net |
This proposal has been superseded by a proposal from 2022-10-27.
Commit message
Drop file_id and parent_id from Git Tree objects.
Description of the change
Drop file_id and parent_id from Git Tree objects.
The Breezy Bot (the-breezy-bot) wrote : | # |
Running landing tests failed
https:/
The Breezy Bot (the-breezy-bot) wrote : | # |
Running landing tests failed
https:/
The Breezy Bot (the-breezy-bot) wrote : | # |
Merging failed
https:/
The Breezy Bot (the-breezy-bot) wrote : | # |
Merging failed
https:/
The Breezy Bot (the-breezy-bot) wrote : | # |
Running landing tests failed
https:/
The Breezy Bot (the-breezy-bot) wrote : | # |
Merging failed
https:/
The Breezy Bot (the-breezy-bot) wrote : | # |
Merging failed
https:/
- 7396. By Jelmer Vernooij
-
Merge lp:brz/3.3
- 7397. By Jelmer Vernooij
-
Merge lp:brz/3.3
- 7398. By Jelmer Vernooij
-
Merge lp:brz/3.3
Unmerged revisions
- 7398. By Jelmer Vernooij
-
Merge lp:brz/3.3
- 7397. By Jelmer Vernooij
-
Merge lp:brz/3.3
- 7396. By Jelmer Vernooij
-
Merge lp:brz/3.3
- 7395. By Jelmer Vernooij
-
merge trunk
- 7394. By Jelmer Vernooij
-
Merge trunk
- 7393. By Jelmer Vernooij
-
Merge lp:brz.
- 7392. By Jelmer Vernooij
-
merge trunk.
- 7391. By Jelmer Vernooij
-
drop file_id and parent_id from Git Tree objects.
Preview Diff
1 | === modified file 'breezy/git/commit.py' |
2 | --- breezy/git/commit.py 2020-08-22 22:46:24 +0000 |
3 | +++ breezy/git/commit.py 2022-08-31 13:01:38 +0000 |
4 | @@ -91,8 +91,7 @@ |
5 | if change.kind[1] in ("directory",): |
6 | self._inv_delta.append( |
7 | (change.path[0], change.path[1], file_id, |
8 | - entry_factory[change.kind[1]]( |
9 | - file_id, change.name[1], parent_id_new))) |
10 | + entry_factory[change.kind[1]](change.name[1]))) |
11 | if change.kind[0] in ("file", "symlink"): |
12 | self._blobs[encode_git_path(change.path[0])] = None |
13 | self._any_changes = True |
14 | @@ -108,7 +107,7 @@ |
15 | entry_kls = entry_factory[change.kind[1]] |
16 | except KeyError: |
17 | raise KeyError("unknown kind %s" % change.kind[1]) |
18 | - entry = entry_kls(file_id, change.name[1], parent_id_new) |
19 | + entry = entry_kls(change.name[1]) |
20 | if change.kind[1] == "file": |
21 | entry.executable = change.executable[1] |
22 | blob = Blob() |
23 | @@ -171,7 +170,7 @@ |
24 | |
25 | def finish_inventory(self): |
26 | # eliminate blobs that were removed |
27 | - self._blobs = {k: v for (k, v) in self._blobs.items()} |
28 | + self._blobs = {k: v for (k, v) in self._blobs.items() if v is not None} |
29 | |
30 | def _iterblobs(self): |
31 | return ((path, sha, mode) for (path, (mode, sha)) |
32 | |
33 | === modified file 'breezy/git/tree.py' |
34 | --- breezy/git/tree.py 2022-08-22 18:19:46 +0000 |
35 | +++ breezy/git/tree.py 2022-08-31 13:01:38 +0000 |
36 | @@ -78,12 +78,12 @@ |
37 | |
38 | class GitTreeDirectory(_mod_tree.TreeDirectory): |
39 | |
40 | - __slots__ = ['file_id', 'name', 'parent_id'] |
41 | + __slots__ = ['name', 'children'] |
42 | |
43 | - def __init__(self, file_id, name, parent_id): |
44 | - self.file_id = file_id |
45 | + def __init__(self, name): |
46 | self.name = name |
47 | - self.parent_id = parent_id |
48 | + # TODO(jelmer) |
49 | + self.children = {} |
50 | |
51 | @property |
52 | def kind(self): |
53 | @@ -94,31 +94,24 @@ |
54 | return False |
55 | |
56 | def copy(self): |
57 | - return self.__class__( |
58 | - self.file_id, self.name, self.parent_id) |
59 | + return self.__class__(self.name) |
60 | |
61 | def __repr__(self): |
62 | - return "%s(file_id=%r, name=%r, parent_id=%r)" % ( |
63 | - self.__class__.__name__, self.file_id, self.name, |
64 | - self.parent_id) |
65 | + return "%s(name=%r)" % (self.__class__.__name__, self.name) |
66 | |
67 | def __eq__(self, other): |
68 | return (self.kind == other.kind and |
69 | - self.file_id == other.file_id and |
70 | - self.name == other.name and |
71 | - self.parent_id == other.parent_id) |
72 | + self.name == other.name) |
73 | |
74 | |
75 | class GitTreeFile(_mod_tree.TreeFile): |
76 | |
77 | - __slots__ = ['file_id', 'name', 'parent_id', 'text_size', |
78 | + __slots__ = ['name', 'text_size', |
79 | 'executable', 'git_sha1'] |
80 | |
81 | - def __init__(self, file_id, name, parent_id, text_size=None, |
82 | + def __init__(self, name, text_size=None, |
83 | git_sha1=None, executable=None): |
84 | - self.file_id = file_id |
85 | self.name = name |
86 | - self.parent_id = parent_id |
87 | self.text_size = text_size |
88 | self.git_sha1 = git_sha1 |
89 | self.executable = executable |
90 | @@ -129,22 +122,19 @@ |
91 | |
92 | def __eq__(self, other): |
93 | return (self.kind == other.kind and |
94 | - self.file_id == other.file_id and |
95 | self.name == other.name and |
96 | - self.parent_id == other.parent_id and |
97 | self.git_sha1 == other.git_sha1 and |
98 | self.text_size == other.text_size and |
99 | self.executable == other.executable) |
100 | |
101 | def __repr__(self): |
102 | - return ("%s(file_id=%r, name=%r, parent_id=%r, text_size=%r, " |
103 | + return ("%s(name=%r, text_size=%r, " |
104 | "git_sha1=%r, executable=%r)") % ( |
105 | - type(self).__name__, self.file_id, self.name, self.parent_id, |
106 | + type(self).__name__, self.name, |
107 | self.text_size, self.git_sha1, self.executable) |
108 | |
109 | def copy(self): |
110 | - ret = self.__class__( |
111 | - self.file_id, self.name, self.parent_id) |
112 | + ret = self.__class__(self.name) |
113 | ret.git_sha1 = self.git_sha1 |
114 | ret.text_size = self.text_size |
115 | ret.executable = self.executable |
116 | @@ -153,13 +143,10 @@ |
117 | |
118 | class GitTreeSymlink(_mod_tree.TreeLink): |
119 | |
120 | - __slots__ = ['file_id', 'name', 'parent_id', 'symlink_target'] |
121 | + __slots__ = ['name', 'symlink_target'] |
122 | |
123 | - def __init__(self, file_id, name, parent_id, |
124 | - symlink_target=None): |
125 | - self.file_id = file_id |
126 | + def __init__(self, name, symlink_target=None): |
127 | self.name = name |
128 | - self.parent_id = parent_id |
129 | self.symlink_target = symlink_target |
130 | |
131 | @property |
132 | @@ -175,31 +162,25 @@ |
133 | return None |
134 | |
135 | def __repr__(self): |
136 | - return "%s(file_id=%r, name=%r, parent_id=%r, symlink_target=%r)" % ( |
137 | - type(self).__name__, self.file_id, self.name, self.parent_id, |
138 | - self.symlink_target) |
139 | + return "%s(name=%r, symlink_target=%r)" % ( |
140 | + type(self).__name__, self.name, self.symlink_target) |
141 | |
142 | def __eq__(self, other): |
143 | return (self.kind == other.kind and |
144 | - self.file_id == other.file_id and |
145 | self.name == other.name and |
146 | - self.parent_id == other.parent_id and |
147 | self.symlink_target == other.symlink_target) |
148 | |
149 | def copy(self): |
150 | return self.__class__( |
151 | - self.file_id, self.name, self.parent_id, |
152 | - self.symlink_target) |
153 | + self.name, self.symlink_target) |
154 | |
155 | |
156 | class GitTreeSubmodule(_mod_tree.TreeReference): |
157 | |
158 | - __slots__ = ['file_id', 'name', 'parent_id', 'reference_revision'] |
159 | + __slots__ = ['name', 'reference_revision'] |
160 | |
161 | - def __init__(self, file_id, name, parent_id, reference_revision=None): |
162 | - self.file_id = file_id |
163 | + def __init__(self, name, reference_revision=None): |
164 | self.name = name |
165 | - self.parent_id = parent_id |
166 | self.reference_revision = reference_revision |
167 | |
168 | @property |
169 | @@ -211,22 +192,16 @@ |
170 | return 'tree-reference' |
171 | |
172 | def __repr__(self): |
173 | - return ("%s(file_id=%r, name=%r, parent_id=%r, " |
174 | - "reference_revision=%r)") % ( |
175 | - type(self).__name__, self.file_id, self.name, self.parent_id, |
176 | - self.reference_revision) |
177 | + return ("%s(name=%r, reference_revision=%r)") % ( |
178 | + type(self).__name__, self.name, self.reference_revision) |
179 | |
180 | def __eq__(self, other): |
181 | return (self.kind == other.kind and |
182 | - self.file_id == other.file_id and |
183 | self.name == other.name and |
184 | - self.parent_id == other.parent_id and |
185 | self.reference_revision == other.reference_revision) |
186 | |
187 | def copy(self): |
188 | - return self.__class__( |
189 | - self.file_id, self.name, self.parent_id, |
190 | - self.reference_revision) |
191 | + return self.__class__(self.name, self.reference_revision) |
192 | |
193 | |
194 | entry_factory = { |
195 | @@ -469,12 +444,11 @@ |
196 | from_dir = u"" |
197 | (store, mode, hexsha) = self._lookup_path(from_dir) |
198 | if mode is None: # Root |
199 | - root_ie = self._get_dir_ie(b"", None) |
200 | + root_ie = self._get_dir_ie(b"") |
201 | else: |
202 | parent_path = posixpath.dirname(from_dir) |
203 | - parent_id = self.mapping.generate_file_id(parent_path) |
204 | if mode_kind(mode) == 'directory': |
205 | - root_ie = self._get_dir_ie(encode_git_path(from_dir), parent_id) |
206 | + root_ie = self._get_dir_ie(encode_git_path(from_dir)) |
207 | else: |
208 | root_ie = self._get_file_ie( |
209 | store, encode_git_path(from_dir), |
210 | @@ -484,9 +458,9 @@ |
211 | todo = [] |
212 | if root_ie.kind == 'directory': |
213 | todo.append((store, encode_git_path(from_dir), |
214 | - b"", hexsha, root_ie.file_id)) |
215 | + b"", hexsha)) |
216 | while todo: |
217 | - (store, path, relpath, hexsha, parent_id) = todo.pop() |
218 | + (store, path, relpath, hexsha) = todo.pop() |
219 | tree = store[hexsha] |
220 | for name, mode, hexsha in tree.iteritems(): |
221 | if self.mapping.is_special_file(name): |
222 | @@ -498,17 +472,17 @@ |
223 | store = self._get_submodule_store(child_relpath) |
224 | hexsha = store[hexsha].tree |
225 | if stat.S_ISDIR(mode): |
226 | - ie = self._get_dir_ie(child_path, parent_id) |
227 | + ie = self._get_dir_ie(child_path) |
228 | if recursive: |
229 | todo.append( |
230 | (store, child_path, child_relpath, hexsha, |
231 | ie.file_id)) |
232 | else: |
233 | ie = self._get_file_ie( |
234 | - store, child_path, name, mode, hexsha, parent_id) |
235 | + store, child_path, name, mode, hexsha) |
236 | yield (decode_git_path(child_relpath), "V", ie.kind, ie) |
237 | |
238 | - def _get_file_ie(self, store, path, name, mode, hexsha, parent_id): |
239 | + def _get_file_ie(self, store, path, name, mode, hexsha): |
240 | if not isinstance(path, bytes): |
241 | raise TypeError(path) |
242 | if not isinstance(name, bytes): |
243 | @@ -516,8 +490,7 @@ |
244 | kind = mode_kind(mode) |
245 | path = decode_git_path(path) |
246 | name = decode_git_path(name) |
247 | - file_id = self.mapping.generate_file_id(path) |
248 | - ie = entry_factory[kind](file_id, name, parent_id) |
249 | + ie = entry_factory[kind](name) |
250 | if kind == 'symlink': |
251 | ie.symlink_target = decode_git_path(store[hexsha].data) |
252 | elif kind == 'tree-reference': |
253 | @@ -529,10 +502,9 @@ |
254 | ie.executable = mode_is_executable(mode) |
255 | return ie |
256 | |
257 | - def _get_dir_ie(self, path, parent_id): |
258 | + def _get_dir_ie(self, path): |
259 | path = decode_git_path(path) |
260 | - file_id = self.mapping.generate_file_id(path) |
261 | - return GitTreeDirectory(file_id, posixpath.basename(path), parent_id) |
262 | + return GitTreeDirectory(posixpath.basename(path)) |
263 | |
264 | def iter_child_entries(self, path): |
265 | (store, mode, tree_sha) = self._lookup_path(path) |
266 | @@ -541,17 +513,15 @@ |
267 | return |
268 | |
269 | encoded_path = encode_git_path(path) |
270 | - file_id = self.path2id(path) |
271 | tree = store[tree_sha] |
272 | for name, mode, hexsha in tree.iteritems(): |
273 | if self.mapping.is_special_file(name): |
274 | continue |
275 | child_path = posixpath.join(encoded_path, name) |
276 | if stat.S_ISDIR(mode): |
277 | - yield self._get_dir_ie(child_path, file_id) |
278 | + yield self._get_dir_ie(child_path) |
279 | else: |
280 | - yield self._get_file_ie(store, child_path, name, mode, hexsha, |
281 | - file_id) |
282 | + yield self._get_file_ie(store, child_path, name, mode, hexsha) |
283 | |
284 | def iter_entries_by_dir(self, specific_files=None, |
285 | recurse_nested=False): |
286 | @@ -563,11 +533,11 @@ |
287 | else: |
288 | specific_files = set([encode_git_path(p) |
289 | for p in specific_files]) |
290 | - todo = deque([(self.store, b"", self.tree, self.path2id(''))]) |
291 | + todo = deque([(self.store, b"", self.tree)]) |
292 | if specific_files is None or u"" in specific_files: |
293 | - yield u"", self._get_dir_ie(b"", None) |
294 | + yield u"", self._get_dir_ie(b"") |
295 | while todo: |
296 | - store, path, tree_sha, parent_id = todo.popleft() |
297 | + store, path, tree_sha = todo.popleft() |
298 | tree = store[tree_sha] |
299 | extradirs = [] |
300 | for name, mode, hexsha in tree.iteritems(): |
301 | @@ -585,17 +555,15 @@ |
302 | if (specific_files is None or |
303 | any([p for p in specific_files if p.startswith( |
304 | child_path)])): |
305 | - extradirs.append( |
306 | - (substore, child_path, hexsha, |
307 | - self.path2id(child_path_decoded))) |
308 | + extradirs.append((substore, child_path, hexsha)) |
309 | if specific_files is None or child_path in specific_files: |
310 | if stat.S_ISDIR(mode): |
311 | yield (child_path_decoded, |
312 | - self._get_dir_ie(child_path, parent_id)) |
313 | + self._get_dir_ie(child_path)) |
314 | else: |
315 | yield (child_path_decoded, |
316 | self._get_file_ie(substore, child_path, name, mode, |
317 | - hexsha, parent_id)) |
318 | + hexsha)) |
319 | todo.extendleft(reversed(extradirs)) |
320 | |
321 | def iter_references(self): |
322 | @@ -1364,11 +1332,12 @@ |
323 | specific_files = set(specific_files) |
324 | else: |
325 | specific_files = None |
326 | - root_ie = self._get_dir_ie(u"", None) |
327 | + root_ie = self._get_dir_ie(u"") |
328 | ret = {} |
329 | if specific_files is None or u"" in specific_files: |
330 | ret[(u"", u"")] = root_ie |
331 | - dir_ids = {u"": root_ie.file_id} |
332 | + dir_ids = set([u""]) |
333 | + for path, value in self._recurse_index_entries(): |
334 | for path, value in self._recurse_index_entries( |
335 | recurse_nested=recurse_nested): |
336 | if self.mapping.is_special_file(path): |
337 | @@ -1378,14 +1347,13 @@ |
338 | continue |
339 | (parent, name) = posixpath.split(path) |
340 | try: |
341 | - file_ie = self._get_file_ie(name, path, value, None) |
342 | + file_ie = self._get_file_ie(name, path, value) |
343 | except _mod_transport.NoSuchFile: |
344 | continue |
345 | if specific_files is None: |
346 | for (dir_path, dir_ie) in self._add_missing_parent_ids( |
347 | parent, dir_ids): |
348 | ret[(posixpath.dirname(dir_path), dir_path)] = dir_ie |
349 | - file_ie.parent_id = self.path2id(parent) |
350 | ret[(posixpath.dirname(path), path)] = file_ie |
351 | # Special casing for directories |
352 | if specific_files: |
353 | @@ -1402,23 +1370,19 @@ |
354 | if entry.kind == 'tree-reference': |
355 | yield path |
356 | |
357 | - def _get_dir_ie(self, path, parent_id): |
358 | - file_id = self.path2id(path) |
359 | - return GitTreeDirectory(file_id, |
360 | - posixpath.basename(path).strip("/"), parent_id) |
361 | + def _get_dir_ie(self, path): |
362 | + return GitTreeDirectory(posixpath.basename(path).strip("/")) |
363 | |
364 | - def _get_file_ie(self, name, path, value, parent_id): |
365 | + def _get_file_ie(self, name, path, value): |
366 | if not isinstance(name, str): |
367 | raise TypeError(name) |
368 | if not isinstance(path, str): |
369 | raise TypeError(path) |
370 | if not isinstance(value, tuple) and not isinstance(value, IndexEntry): |
371 | raise TypeError(value) |
372 | - file_id = self.path2id(path) |
373 | - if not isinstance(file_id, bytes): |
374 | - raise TypeError(file_id) |
375 | + |
376 | kind = mode_kind(value.mode) |
377 | - ie = entry_factory[kind](file_id, name, parent_id) |
378 | + ie = entry_factory[kind](name) |
379 | if kind == 'symlink': |
380 | ie.symlink_target = self.get_symlink_target(path) |
381 | elif kind == 'tree-reference': |
382 | @@ -1434,9 +1398,8 @@ |
383 | return [] |
384 | parent = posixpath.dirname(path).strip("/") |
385 | ret = self._add_missing_parent_ids(parent, dir_ids) |
386 | - parent_id = dir_ids[parent] |
387 | - ie = self._get_dir_ie(path, parent_id) |
388 | - dir_ids[path] = ie.file_id |
389 | + ie = self._get_dir_ie(path) |
390 | + dir_ids.add(path) |
391 | ret.append((path, ie)) |
392 | return ret |
393 | |
394 | |
395 | === modified file 'breezy/git/workingtree.py' |
396 | --- breezy/git/workingtree.py 2022-08-22 18:19:46 +0000 |
397 | +++ breezy/git/workingtree.py 2022-08-31 13:01:38 +0000 |
398 | @@ -538,8 +538,7 @@ |
399 | return |
400 | if action is not None: |
401 | parent_path = posixpath.dirname(filepath) |
402 | - parent_id = self.path2id(parent_path) |
403 | - parent_ie = self._get_dir_ie(parent_path, parent_id) |
404 | + parent_ie = self._get_dir_ie(parent_path) |
405 | file_id = action(self, parent_ie, filepath, kind) |
406 | if file_id is not None: |
407 | raise workingtree.SettingFileIdUnsupported() |
408 | @@ -835,16 +834,16 @@ |
409 | recurse_nested=False): |
410 | if from_dir is None or from_dir == '.': |
411 | from_dir = u"" |
412 | - dir_ids = {} |
413 | + dir_ids = set() |
414 | fk_entries = {'directory': tree.TreeDirectory, |
415 | 'file': tree.TreeFile, |
416 | 'symlink': tree.TreeLink, |
417 | 'tree-reference': tree.TreeReference} |
418 | with self.lock_read(): |
419 | - root_ie = self._get_dir_ie(u"", None) |
420 | + root_ie = self._get_dir_ie(u"") |
421 | if include_root and not from_dir: |
422 | yield "", "V", root_ie.kind, root_ie |
423 | - dir_ids[u""] = root_ie.file_id |
424 | + dir_ids.add(u"") |
425 | if recursive: |
426 | path_iterator = sorted( |
427 | self._iter_files_recursive( |
428 | @@ -879,7 +878,7 @@ |
429 | if kind == 'directory': |
430 | if path != from_dir: |
431 | if self._has_dir(encoded_path): |
432 | - ie = self._get_dir_ie(path, self.path2id(path)) |
433 | + ie = self._get_dir_ie(path) |
434 | status = "V" |
435 | elif self.is_ignored(path): |
436 | status = "I" |
437 | @@ -891,7 +890,7 @@ |
438 | ie) |
439 | continue |
440 | if value is not None: |
441 | - ie = self._get_file_ie(name, path, value, dir_ids[parent]) |
442 | + ie = self._get_file_ie(name, path, value) |
443 | yield (posixpath.relpath(path, from_dir), "V", ie.kind, ie) |
444 | else: |
445 | try: |
446 | @@ -920,7 +919,6 @@ |
447 | def iter_child_entries(self, path): |
448 | encoded_path = encode_git_path(path) |
449 | with self.lock_read(): |
450 | - parent_id = self.path2id(path) |
451 | found_any = False |
452 | for item_path, value in self.index.iteritems(): |
453 | decoded_item_path = decode_git_path(item_path) |
454 | @@ -933,11 +931,10 @@ |
455 | if '/' in subpath: |
456 | dirname = subpath.split('/', 1)[0] |
457 | file_ie = self._get_dir_ie( |
458 | - posixpath.join(path, dirname), parent_id) |
459 | + posixpath.join(path, dirname)) |
460 | else: |
461 | (unused_parent, name) = posixpath.split(decoded_item_path) |
462 | - file_ie = self._get_file_ie( |
463 | - name, decoded_item_path, value, parent_id) |
464 | + file_ie = self._get_file_ie(name, decoded_item_path, value) |
465 | yield file_ie |
466 | if not found_any and path != u'': |
467 | raise _mod_transport.NoSuchFile(path) |
468 | |
469 | === modified file 'breezy/transport/http/__init__.py' |
470 | --- breezy/transport/http/__init__.py 2021-01-10 00:25:52 +0000 |
471 | +++ breezy/transport/http/__init__.py 2022-08-31 13:01:38 +0000 |
472 | @@ -116,3 +116,4 @@ |
473 | * none: Certificates ignored |
474 | * required: Certificates required and validated |
475 | """) |
476 | + |
477 | |
478 | === modified file 'byov.conf' |
479 | --- byov.conf 2022-07-09 14:29:29 +0000 |
480 | +++ byov.conf 2022-08-31 13:01:38 +0000 |
481 | @@ -2,10 +2,15 @@ |
482 | # Start with an up to date system by default |
483 | vm.update = True |
484 | # External sources dependencies, packages are not recent enough |
485 | +dulwich.clone = (git clone git://jelmer.uk/dulwich ../dulwich.git) |
486 | +dulwich.install = (cd ../dulwich.git && python3 ./setup.py install --user) |
487 | subunit.clone = (git clone https://github.com/testing-cabal/subunit.git ../subunit) |
488 | +fastimport.clone = (git clone git://jelmer.uk/python-fastimport.git ../fastimport.git) |
489 | +fastimport.install = (cd ../fastimport.git && python3 ./setup.py install --user) |
490 | sphinx_epytext.install = (pip3 install sphinx_epytext) |
491 | -flake8.install3 = (pip3 install flake8) |
492 | -brz.extras = fastimport,launchpad,workspace,git,cext,doc |
493 | +flake8.install = (pip3 install flake8) |
494 | +patiencediff.install = (pip3 install patiencediff) |
495 | +cython.install = (pip3 install cython) |
496 | |
497 | [brz] |
498 | # because paramiko 2.0.0 is broken: |
Looks good, thanks!