395 else: |
406 else: |
396 if repo.vfs.exists('topic'): |
407 if repo.vfs.exists('topic'): |
397 repo.vfs.unlink('topic') |
408 repo.vfs.unlink('topic') |
398 |
409 |
399 def _changetopics(ui, repo, revset, newtopic): |
410 def _changetopics(ui, repo, revset, newtopic): |
|
411 """ Changes topic to newtopic of all the revisions in the revset and return |
|
412 the count of revisions whose topic has been changed. |
|
413 """ |
400 rewrote = 0 |
414 rewrote = 0 |
401 wl = l = txn = None |
415 p1 = None |
402 try: |
416 p2 = None |
403 wl = repo.wlock() |
417 successors = {} |
404 l = repo.lock() |
418 for c in repo.set('%r', revset): |
405 txn = repo.transaction('rewrite-topics') |
419 def filectxfn(repo, ctx, path): |
406 p1 = None |
420 try: |
407 p2 = None |
421 return c[path] |
408 successors = {} |
422 except error.ManifestLookupError: |
409 for c in repo.set('%r', revset): |
423 return None |
410 def filectxfn(repo, ctx, path): |
424 fixedextra = dict(c.extra()) |
411 try: |
425 ui.debug('old node id is %s\n' % node.hex(c.node())) |
412 return c[path] |
426 ui.debug('origextra: %r\n' % fixedextra) |
413 except error.ManifestLookupError: |
427 oldtopic = fixedextra.get(constants.extrakey, None) |
414 return None |
428 if oldtopic == newtopic: |
415 fixedextra = dict(c.extra()) |
429 continue |
416 ui.debug('old node id is %s\n' % node.hex(c.node())) |
430 if newtopic is None: |
417 ui.debug('origextra: %r\n' % fixedextra) |
431 del fixedextra[constants.extrakey] |
418 oldtopic = fixedextra.get(constants.extrakey, None) |
432 else: |
419 if oldtopic == newtopic: |
433 fixedextra[constants.extrakey] = newtopic |
420 continue |
434 fixedextra[constants.changekey] = c.hex() |
421 if newtopic is None: |
435 if 'amend_source' in fixedextra: |
422 del fixedextra[constants.extrakey] |
436 # TODO: right now the commitctx wrapper in |
423 else: |
437 # topicrepo overwrites the topic in extra if |
424 fixedextra[constants.extrakey] = newtopic |
438 # amend_source is set to support 'hg commit |
425 fixedextra[constants.changekey] = c.hex() |
439 # --amend'. Support for amend should be adjusted |
426 if 'amend_source' in fixedextra: |
440 # to not be so invasive. |
427 # TODO: right now the commitctx wrapper in |
441 del fixedextra['amend_source'] |
428 # topicrepo overwrites the topic in extra if |
442 ui.debug('changing topic of %s from %s to %s\n' % ( |
429 # amend_source is set to support 'hg commit |
443 c, oldtopic, newtopic)) |
430 # --amend'. Support for amend should be adjusted |
444 ui.debug('fixedextra: %r\n' % fixedextra) |
431 # to not be so invasive. |
445 # While changing topic of set of linear commits, make sure that |
432 del fixedextra['amend_source'] |
446 # we base our commits on new parent rather than old parent which |
433 ui.debug('changing topic of %s from %s to %s\n' % ( |
447 # was obsoleted while changing the topic |
434 c, oldtopic, newtopic)) |
448 p1 = c.p1().node() |
435 ui.debug('fixedextra: %r\n' % fixedextra) |
449 p2 = c.p2().node() |
436 # While changing topic of set of linear commits, make sure that |
450 if p1 in successors: |
437 # we base our commits on new parent rather than old parent which |
451 p1 = successors[p1] |
438 # was obsoleted while changing the topic |
452 if p2 in successors: |
439 p1 = c.p1().node() |
453 p2 = successors[p2] |
440 p2 = c.p2().node() |
454 mc = context.memctx( |
441 if p1 in successors: |
455 repo, (p1, p2), c.description(), |
442 p1 = successors[p1] |
456 c.files(), filectxfn, |
443 if p2 in successors: |
457 user=c.user(), date=c.date(), extra=fixedextra) |
444 p2 = successors[p2] |
458 newnode = repo.commitctx(mc) |
445 mc = context.memctx( |
459 successors[c.node()] = newnode |
446 repo, (p1, p2), c.description(), |
460 ui.debug('new node id is %s\n' % node.hex(newnode)) |
447 c.files(), filectxfn, |
461 obsolete.createmarkers(repo, [(c, (repo[newnode],))]) |
448 user=c.user(), date=c.date(), extra=fixedextra) |
462 rewrote += 1 |
449 newnode = repo.commitctx(mc) |
463 # move the working copy too |
450 successors[c.node()] = newnode |
464 wctx = repo[None] |
451 ui.debug('new node id is %s\n' % node.hex(newnode)) |
465 # in-progress merge is a bit too complex for now. |
452 obsolete.createmarkers(repo, [(c, (repo[newnode],))]) |
466 if len(wctx.parents()) == 1: |
453 rewrote += 1 |
467 newid = successors.get(wctx.p1().node()) |
454 # move the working copy too |
468 if newid is not None: |
455 wctx = repo[None] |
469 hg.update(repo, newid, quietempty=True) |
456 # in-progress merge is a bit too complex for now. |
470 return rewrote |
457 if len(wctx.parents()) == 1: |
|
458 newid = successors.get(wctx.p1().node()) |
|
459 if newid is not None: |
|
460 hg.update(repo, newid, quietempty=True) |
|
461 txn.close() |
|
462 finally: |
|
463 lock.release(txn, l, wl) |
|
464 repo.invalidate() |
|
465 ui.status('changed topic on %d changes\n' % rewrote) |
|
466 |
471 |
467 def _listtopics(ui, repo, opts): |
472 def _listtopics(ui, repo, opts): |
468 fm = ui.formatter('topics', opts) |
473 fm = ui.formatter('topics', opts) |
469 showlast = opts.get('age') |
474 showlast = opts.get('age') |
470 if showlast: |
475 if showlast: |