Mercurial > hg > mercurial-crew-with-dirclash
comparison hgext/convert/subversion.py @ 4786:62e1b6412b62
convert: svn: add an early return to move most changeset parsing out an indent level
author | Brendan Cully <brendan@kublai.com> |
---|---|
date | Tue, 03 Jul 2007 11:36:06 -0700 |
parents | a67f185d0474 |
children | c5dd8e184279 |
comparison
equal
deleted
inserted
replaced
4785:a67f185d0474 | 4786:62e1b6412b62 |
---|---|
216 | 216 |
217 copyfrom = {} # Map of entrypath, revision for finding source of deleted revisions. | 217 copyfrom = {} # Map of entrypath, revision for finding source of deleted revisions. |
218 copies = {} | 218 copies = {} |
219 entries = [] | 219 entries = [] |
220 self.ui.debug("Parsing revision %d\n" % revnum) | 220 self.ui.debug("Parsing revision %d\n" % revnum) |
221 if orig_paths is not None: | 221 if orig_paths is None: |
222 rev = self.rev(revnum) | 222 return |
223 try: | 223 |
224 branch = self.module.split("/")[-1] | 224 rev = self.rev(revnum) |
225 if branch == 'trunk': | 225 try: |
226 branch = '' | 226 branch = self.module.split("/")[-1] |
227 except IndexError: | 227 if branch == 'trunk': |
228 branch = None | 228 branch = '' |
229 except IndexError: | |
230 branch = None | |
229 | 231 |
230 for path in orig_paths: | 232 for path in orig_paths: |
231 # self.ui.write("path %s\n" % path) | 233 # self.ui.write("path %s\n" % path) |
232 if path == self.module: # Follow branching back in history | 234 if path == self.module: # Follow branching back in history |
233 ent = orig_paths[path] | |
234 if ent: | |
235 if ent.copyfrom_path: | |
236 self.modulemap[ent.copyfrom_rev] = ent.copyfrom_path | |
237 else: | |
238 self.ui.debug("No copyfrom path, don't know what to do.\n") | |
239 # Maybe it was added and there is no more history. | |
240 entrypath = get_entry_from_path(path, module=self.module) | |
241 # self.ui.write("entrypath %s\n" % entrypath) | |
242 if entrypath is None: | |
243 # Outside our area of interest | |
244 self.ui.debug("boring@%s: %s\n" % (revnum, path)) | |
245 continue | |
246 entry = entrypath.decode(self.encoding) | |
247 ent = orig_paths[path] | 235 ent = orig_paths[path] |
248 if not entrypath: | 236 if ent: |
249 # TODO: branch creation event | |
250 pass | |
251 | |
252 kind = svn.ra.check_path(self.ra, entrypath, revnum) | |
253 if kind == svn.core.svn_node_file: | |
254 if ent.copyfrom_path: | 237 if ent.copyfrom_path: |
255 copyfrom_path = get_entry_from_path(ent.copyfrom_path) | 238 self.modulemap[ent.copyfrom_rev] = ent.copyfrom_path |
256 if copyfrom_path: | 239 else: |
257 self.ui.debug("Copied to %s from %s@%s\n" % (entry, copyfrom_path, ent.copyfrom_rev)) | 240 self.ui.debug("No copyfrom path, don't know what to do.\n") |
258 # It's probably important for hg that the source | 241 # Maybe it was added and there is no more history. |
259 # exists in the revision's parent, not just the | 242 entrypath = get_entry_from_path(path, module=self.module) |
260 # ent.copyfrom_rev | 243 # self.ui.write("entrypath %s\n" % entrypath) |
261 fromkind = svn.ra.check_path(self.ra, copyfrom_path, ent.copyfrom_rev) | 244 if entrypath is None: |
262 if fromkind != 0: | 245 # Outside our area of interest |
263 copies[self.recode(entry)] = self.recode(copyfrom_path) | 246 self.ui.debug("boring@%s: %s\n" % (revnum, path)) |
247 continue | |
248 entry = entrypath.decode(self.encoding) | |
249 ent = orig_paths[path] | |
250 if not entrypath: | |
251 # TODO: branch creation event | |
252 pass | |
253 | |
254 kind = svn.ra.check_path(self.ra, entrypath, revnum) | |
255 if kind == svn.core.svn_node_file: | |
256 if ent.copyfrom_path: | |
257 copyfrom_path = get_entry_from_path(ent.copyfrom_path) | |
258 if copyfrom_path: | |
259 self.ui.debug("Copied to %s from %s@%s\n" % (entry, copyfrom_path, ent.copyfrom_rev)) | |
260 # It's probably important for hg that the source | |
261 # exists in the revision's parent, not just the | |
262 # ent.copyfrom_rev | |
263 fromkind = svn.ra.check_path(self.ra, copyfrom_path, ent.copyfrom_rev) | |
264 if fromkind != 0: | |
265 copies[self.recode(entry)] = self.recode(copyfrom_path) | |
266 entries.append(self.recode(entry)) | |
267 elif kind == 0: # gone, but had better be a deleted *file* | |
268 self.ui.debug("gone from %s\n" % ent.copyfrom_rev) | |
269 | |
270 fromrev = revnum - 1 | |
271 # might always need to be revnum - 1 in these 3 lines? | |
272 old_module = self.modulemap.get(fromrev, self.module) | |
273 basepath = old_module + "/" + get_entry_from_path(path, module=self.module) | |
274 entrypath = old_module + "/" + get_entry_from_path(path, module=self.module) | |
275 | |
276 def lookup_parts(p): | |
277 rc = None | |
278 parts = p.split("/") | |
279 for i in range(len(parts)): | |
280 part = "/".join(parts[:i]) | |
281 info = part, copyfrom.get(part, None) | |
282 if info[1] is not None: | |
283 self.ui.debug("Found parent directory %s\n" % info) | |
284 rc = info | |
285 return rc | |
286 | |
287 self.ui.debug("base, entry %s %s\n" % (basepath, entrypath)) | |
288 | |
289 frompath, froment = lookup_parts(entrypath) or (None, revnum - 1) | |
290 | |
291 # need to remove fragment from lookup_parts and replace with copyfrom_path | |
292 if frompath is not None: | |
293 self.ui.debug("munge-o-matic\n") | |
294 self.ui.debug(entrypath + '\n') | |
295 self.ui.debug(entrypath[len(frompath):] + '\n') | |
296 entrypath = froment.copyfrom_path + entrypath[len(frompath):] | |
297 fromrev = froment.copyfrom_rev | |
298 self.ui.debug("Info: %s %s %s %s\n" % (frompath, froment, ent, entrypath)) | |
299 | |
300 fromkind = svn.ra.check_path(self.ra, entrypath, fromrev) | |
301 if fromkind == svn.core.svn_node_file: # a deleted file | |
264 entries.append(self.recode(entry)) | 302 entries.append(self.recode(entry)) |
265 elif kind == 0: # gone, but had better be a deleted *file* | 303 else: |
266 self.ui.debug("gone from %s\n" % ent.copyfrom_rev) | 304 # print "Deleted/moved non-file:", revnum, path, ent |
267 | 305 # children = self._find_children(path, revnum - 1) |
268 fromrev = revnum - 1 | 306 # print "find children %s@%d from %d action %s" % (path, revnum, ent.copyfrom_rev, ent.action) |
269 # might always need to be revnum - 1 in these 3 lines? | 307 # Sometimes this is tricky. For example: in |
270 old_module = self.modulemap.get(fromrev, self.module) | 308 # The Subversion Repository revision 6940 a dir |
271 basepath = old_module + "/" + get_entry_from_path(path, module=self.module) | 309 # was copied and one of its files was deleted |
272 entrypath = old_module + "/" + get_entry_from_path(path, module=self.module) | 310 # from the new location in the same commit. This |
273 | 311 # code can't deal with that yet. |
274 def lookup_parts(p): | 312 if ent.action == 'C': |
275 rc = None | 313 children = self._find_children(path, fromrev) |
276 parts = p.split("/") | |
277 for i in range(len(parts)): | |
278 part = "/".join(parts[:i]) | |
279 info = part, copyfrom.get(part, None) | |
280 if info[1] is not None: | |
281 self.ui.debug("Found parent directory %s\n" % info) | |
282 rc = info | |
283 return rc | |
284 | |
285 self.ui.debug("base, entry %s %s\n" % (basepath, entrypath)) | |
286 | |
287 frompath, froment = lookup_parts(entrypath) or (None, revnum - 1) | |
288 | |
289 # need to remove fragment from lookup_parts and replace with copyfrom_path | |
290 if frompath is not None: | |
291 self.ui.debug("munge-o-matic\n") | |
292 self.ui.debug(entrypath + '\n') | |
293 self.ui.debug(entrypath[len(frompath):] + '\n') | |
294 entrypath = froment.copyfrom_path + entrypath[len(frompath):] | |
295 fromrev = froment.copyfrom_rev | |
296 self.ui.debug("Info: %s %s %s %s\n" % (frompath, froment, ent, entrypath)) | |
297 | |
298 fromkind = svn.ra.check_path(self.ra, entrypath, fromrev) | |
299 if fromkind == svn.core.svn_node_file: # a deleted file | |
300 entries.append(self.recode(entry)) | |
301 else: | 314 else: |
302 # print "Deleted/moved non-file:", revnum, path, ent | 315 oroot = entrypath.strip('/') |
303 # children = self._find_children(path, revnum - 1) | 316 nroot = path.strip('/') |
304 # print "find children %s@%d from %d action %s" % (path, revnum, ent.copyfrom_rev, ent.action) | 317 children = self._find_children(oroot, fromrev) |
305 # Sometimes this is tricky. For example: in | 318 children = [s.replace(oroot,nroot) for s in children] |
306 # The Subversion Repository revision 6940 a dir | 319 # Mark all [files, not directories] as deleted. |
307 # was copied and one of its files was deleted | |
308 # from the new location in the same commit. This | |
309 # code can't deal with that yet. | |
310 if ent.action == 'C': | |
311 children = self._find_children(path, fromrev) | |
312 else: | |
313 oroot = entrypath.strip('/') | |
314 nroot = path.strip('/') | |
315 children = self._find_children(oroot, fromrev) | |
316 children = [s.replace(oroot,nroot) for s in children] | |
317 # Mark all [files, not directories] as deleted. | |
318 for child in children: | |
319 # Can we move a child directory and its | |
320 # parent in the same commit? (probably can). Could | |
321 # cause problems if instead of revnum -1, | |
322 # we have to look in (copyfrom_path, revnum - 1) | |
323 entrypath = get_entry_from_path("/" + child, module=old_module) | |
324 if entrypath: | |
325 entry = self.recode(entrypath.decode(self.encoding)) | |
326 if entry in copies: | |
327 # deleted file within a copy | |
328 del copies[entry] | |
329 else: | |
330 entries.append(entry) | |
331 elif kind == svn.core.svn_node_dir: | |
332 # Should probably synthesize normal file entries | |
333 # and handle as above to clean up copy/rename handling. | |
334 | |
335 # If the directory just had a prop change, | |
336 # then we shouldn't need to look for its children. | |
337 # Also this could create duplicate entries. Not sure | |
338 # whether this will matter. Maybe should make entries a set. | |
339 # print "Changed directory", revnum, path, ent.action, ent.copyfrom_path, ent.copyfrom_rev | |
340 # This will fail if a directory was copied | |
341 # from another branch and then some of its files | |
342 # were deleted in the same transaction. | |
343 children = self._find_children(path, revnum) | |
344 children.sort() | |
345 for child in children: | 320 for child in children: |
346 # Can we move a child directory and its | 321 # Can we move a child directory and its |
347 # parent in the same commit? (probably can). Could | 322 # parent in the same commit? (probably can). Could |
348 # cause problems if instead of revnum -1, | 323 # cause problems if instead of revnum -1, |
349 # we have to look in (copyfrom_path, revnum - 1) | 324 # we have to look in (copyfrom_path, revnum - 1) |
350 entrypath = get_entry_from_path("/" + child, module=self.module) | 325 entrypath = get_entry_from_path("/" + child, module=old_module) |
351 # print child, self.module, entrypath | |
352 if entrypath: | 326 if entrypath: |
353 # Need to filter out directories here... | 327 entry = self.recode(entrypath.decode(self.encoding)) |
354 kind = svn.ra.check_path(self.ra, entrypath, revnum) | 328 if entry in copies: |
355 if kind != svn.core.svn_node_dir: | 329 # deleted file within a copy |
356 entries.append(self.recode(entrypath)) | 330 del copies[entry] |
357 | 331 else: |
358 # Copies here (must copy all from source) | 332 entries.append(entry) |
359 # Probably not a real problem for us if | 333 elif kind == svn.core.svn_node_dir: |
360 # source does not exist | 334 # Should probably synthesize normal file entries |
361 | 335 # and handle as above to clean up copy/rename handling. |
362 # Can do this with the copy command "hg copy" | 336 |
363 # if ent.copyfrom_path: | 337 # If the directory just had a prop change, |
364 # copyfrom_entry = get_entry_from_path(ent.copyfrom_path.decode(self.encoding), | 338 # then we shouldn't need to look for its children. |
365 # module=self.module) | 339 # Also this could create duplicate entries. Not sure |
366 # copyto_entry = entrypath | 340 # whether this will matter. Maybe should make entries a set. |
367 # | 341 # print "Changed directory", revnum, path, ent.action, ent.copyfrom_path, ent.copyfrom_rev |
368 # print "copy directory", copyfrom_entry, 'to', copyto_entry | 342 # This will fail if a directory was copied |
369 # | 343 # from another branch and then some of its files |
370 # copies.append((copyfrom_entry, copyto_entry)) | 344 # were deleted in the same transaction. |
371 | 345 children = self._find_children(path, revnum) |
372 if ent.copyfrom_path: | 346 children.sort() |
373 copyfrom_path = ent.copyfrom_path.decode(self.encoding) | 347 for child in children: |
374 copyfrom_entry = get_entry_from_path(copyfrom_path, module=self.module) | 348 # Can we move a child directory and its |
375 if copyfrom_entry: | 349 # parent in the same commit? (probably can). Could |
376 copyfrom[path] = ent | 350 # cause problems if instead of revnum -1, |
377 self.ui.debug("mark %s came from %s\n" % (path, copyfrom[path])) | 351 # we have to look in (copyfrom_path, revnum - 1) |
378 | 352 entrypath = get_entry_from_path("/" + child, module=self.module) |
379 # Good, /probably/ a regular copy. Really should check | 353 # print child, self.module, entrypath |
380 # to see whether the parent revision actually contains | 354 if entrypath: |
381 # the directory in question. | 355 # Need to filter out directories here... |
382 children = self._find_children(self.recode(copyfrom_path), ent.copyfrom_rev) | 356 kind = svn.ra.check_path(self.ra, entrypath, revnum) |
383 children.sort() | 357 if kind != svn.core.svn_node_dir: |
384 for child in children: | 358 entries.append(self.recode(entrypath)) |
385 entrypath = get_entry_from_path("/" + child, module=self.module) | 359 |
386 if entrypath: | 360 # Copies here (must copy all from source) |
387 entry = entrypath.decode(self.encoding) | 361 # Probably not a real problem for us if |
388 # print "COPY COPY From", copyfrom_entry, entry | 362 # source does not exist |
389 copyto_path = path + entry[len(copyfrom_entry):] | 363 |
390 copyto_entry = get_entry_from_path(copyto_path, module=self.module) | 364 # Can do this with the copy command "hg copy" |
391 # print "COPY", entry, "COPY To", copyto_entry | 365 # if ent.copyfrom_path: |
392 copies[self.recode(copyto_entry)] = self.recode(entry) | 366 # copyfrom_entry = get_entry_from_path(ent.copyfrom_path.decode(self.encoding), |
393 # copy from quux splort/quuxfile | 367 # module=self.module) |
394 | 368 # copyto_entry = entrypath |
395 self.modulemap[revnum] = self.module # track backwards in time | 369 # |
396 # a list of (filename, id) where id lets us retrieve the file. | 370 # print "copy directory", copyfrom_entry, 'to', copyto_entry |
397 # eg in git, id is the object hash. for svn it'll be the | 371 # |
398 self.files[rev] = zip(entries, [rev] * len(entries)) | 372 # copies.append((copyfrom_entry, copyto_entry)) |
399 if not entries: | 373 |
400 return | 374 if ent.copyfrom_path: |
401 | 375 copyfrom_path = ent.copyfrom_path.decode(self.encoding) |
402 # Example SVN datetime. Includes microseconds. | 376 copyfrom_entry = get_entry_from_path(copyfrom_path, module=self.module) |
403 # ISO-8601 conformant | 377 if copyfrom_entry: |
404 # '2007-01-04T17:35:00.902377Z' | 378 copyfrom[path] = ent |
405 date = util.parsedate(date[:18] + " UTC", ["%Y-%m-%dT%H:%M:%S"]) | 379 self.ui.debug("mark %s came from %s\n" % (path, copyfrom[path])) |
406 | 380 |
407 log = message and self.recode(message) | 381 # Good, /probably/ a regular copy. Really should check |
408 author = author and self.recode(author) or '' | 382 # to see whether the parent revision actually contains |
409 | 383 # the directory in question. |
410 cset = commit(author=author, | 384 children = self._find_children(self.recode(copyfrom_path), ent.copyfrom_rev) |
411 date=util.datestr(date), | 385 children.sort() |
412 desc=log, | 386 for child in children: |
413 parents=[], | 387 entrypath = get_entry_from_path("/" + child, module=self.module) |
414 copies=copies, | 388 if entrypath: |
415 branch=branch) | 389 entry = entrypath.decode(self.encoding) |
416 | 390 # print "COPY COPY From", copyfrom_entry, entry |
417 if self.child_cset and self.child_rev != rev: | 391 copyto_path = path + entry[len(copyfrom_entry):] |
418 self.child_cset.parents = [rev] | 392 copyto_entry = get_entry_from_path(copyto_path, module=self.module) |
419 self.commits[self.child_rev] = self.child_cset | 393 # print "COPY", entry, "COPY To", copyto_entry |
420 self.child_cset = cset | 394 copies[self.recode(copyto_entry)] = self.recode(entry) |
421 self.child_rev = rev | 395 # copy from quux splort/quuxfile |
396 | |
397 self.modulemap[revnum] = self.module # track backwards in time | |
398 # a list of (filename, id) where id lets us retrieve the file. | |
399 # eg in git, id is the object hash. for svn it'll be the | |
400 self.files[rev] = zip(entries, [rev] * len(entries)) | |
401 if not entries: | |
402 return | |
403 | |
404 # Example SVN datetime. Includes microseconds. | |
405 # ISO-8601 conformant | |
406 # '2007-01-04T17:35:00.902377Z' | |
407 date = util.parsedate(date[:18] + " UTC", ["%Y-%m-%dT%H:%M:%S"]) | |
408 | |
409 log = message and self.recode(message) | |
410 author = author and self.recode(author) or '' | |
411 | |
412 cset = commit(author=author, | |
413 date=util.datestr(date), | |
414 desc=log, | |
415 parents=[], | |
416 copies=copies, | |
417 branch=branch) | |
418 | |
419 if self.child_cset and self.child_rev != rev: | |
420 self.child_cset.parents = [rev] | |
421 self.commits[self.child_rev] = self.child_cset | |
422 self.child_cset = cset | |
423 self.child_rev = rev | |
422 | 424 |
423 try: | 425 try: |
424 discover_changed_paths = True | 426 discover_changed_paths = True |
425 strict_node_history = False | 427 strict_node_history = False |
426 svn.ra.get_log(self.ra, [self.module], from_revnum, to_revnum, | 428 svn.ra.get_log(self.ra, [self.module], from_revnum, to_revnum, |