comparison hgext3rd/topic/__init__.py @ 2898:3dfc88c06378

topic: support --rev argument and properly process then as user input Revisions inputed by the users should be processed using `scmutil.revrange`. This will take alias into account and allow extensions to monitor the user inputs. As a side effect, the '_changetopics' function takes revisions as argument. make the API clearer.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Fri, 01 Sep 2017 17:53:14 +0200
parents bd04a614b866
children 32306ee32806
comparison
equal deleted inserted replaced
2897:bd04a614b866 2898:3dfc88c06378
308 'topics', 'topic', namemap=_namemap, nodemap=_nodemap, 308 'topics', 'topic', namemap=_namemap, nodemap=_nodemap,
309 listnames=lambda repo: repo.topics)) 309 listnames=lambda repo: repo.topics))
310 310
311 @command('topics', [ 311 @command('topics', [
312 ('', 'clear', False, 'clear active topic if any'), 312 ('', 'clear', False, 'clear active topic if any'),
313 ('r', 'rev', '', 'revset of existing revisions', _('REV')), 313 ('r', 'rev', [], 'revset of existing revisions', _('REV')),
314 ('l', 'list', False, 'show the stack of changeset in the topic'), 314 ('l', 'list', False, 'show the stack of changeset in the topic'),
315 ('', 'age', False, 'show when you last touched the topics'), 315 ('', 'age', False, 'show when you last touched the topics'),
316 ('', 'current', None, 'display the current topic only'), 316 ('', 'current', None, 'display the current topic only'),
317 ] + commands.formatteropts, 317 ] + commands.formatteropts,
318 _('hg topics [TOPIC]')) 318 _('hg topics [TOPIC]'))
351 raise error.Abort(_("cannot use --current when setting a topic")) 351 raise error.Abort(_("cannot use --current when setting a topic"))
352 if current and clear: 352 if current and clear:
353 raise error.Abort(_("cannot use --current and --clear")) 353 raise error.Abort(_("cannot use --current and --clear"))
354 if clear and topic: 354 if clear and topic:
355 raise error.Abort(_("cannot use --clear when setting a topic")) 355 raise error.Abort(_("cannot use --clear when setting a topic"))
356
357 touchedrevs = set()
358 if rev:
359 touchedrevs = scmutil.revrange(repo, rev)
356 360
357 if topic: 361 if topic:
358 topic = topic.strip() 362 topic = topic.strip()
359 if not topic: 363 if not topic:
360 raise error.Abort(_("topic name cannot consist entirely of whitespaces")) 364 raise error.Abort(_("topic name cannot consist entirely of whitespaces"))
368 topic = repo.currenttopic 372 topic = repo.currenttopic
369 if not topic: 373 if not topic:
370 raise error.Abort(_('no active topic to list')) 374 raise error.Abort(_('no active topic to list'))
371 return stack.showstack(ui, repo, topic=topic, opts=opts) 375 return stack.showstack(ui, repo, topic=topic, opts=opts)
372 376
373 if rev: 377 if touchedrevs:
374 if not obsolete.isenabled(repo, obsolete.createmarkersopt): 378 if not obsolete.isenabled(repo, obsolete.createmarkersopt):
375 raise error.Abort(_('must have obsolete enabled to change topics')) 379 raise error.Abort(_('must have obsolete enabled to change topics'))
376 if clear: 380 if clear:
377 topic = None 381 topic = None
378 elif opts.get('current'): 382 elif opts.get('current'):
379 topic = repo.currenttopic 383 topic = repo.currenttopic
380 elif not topic: 384 elif not topic:
381 raise error.Abort('changing topic requires a topic name or --clear') 385 raise error.Abort('changing topic requires a topic name or --clear')
382 if any(not c.mutable() for c in repo.set('%r and public()', rev)): 386 if repo.revs('%ld and public()', touchedrevs):
383 raise error.Abort("can't change topic of a public change") 387 raise error.Abort("can't change topic of a public change")
384 wl = l = txn = None 388 wl = l = txn = None
385 try: 389 try:
386 wl = repo.wlock() 390 wl = repo.wlock()
387 l = repo.lock() 391 l = repo.lock()
388 txn = repo.transaction('rewrite-topics') 392 txn = repo.transaction('rewrite-topics')
389 rewrote = _changetopics(ui, repo, rev, topic) 393 rewrote = _changetopics(ui, repo, touchedrevs, topic)
390 txn.close() 394 txn.close()
391 ui.status('changed topic on %d changes\n' % rewrote) 395 ui.status('changed topic on %d changes\n' % rewrote)
392 finally: 396 finally:
393 lockmod.release(txn, l, wl) 397 lockmod.release(txn, l, wl)
394 repo.invalidate() 398 repo.invalidate()
444 f.write(newtopic) 448 f.write(newtopic)
445 else: 449 else:
446 if repo.vfs.exists('topic'): 450 if repo.vfs.exists('topic'):
447 repo.vfs.unlink('topic') 451 repo.vfs.unlink('topic')
448 452
449 def _changetopics(ui, repo, revset, newtopic): 453 def _changetopics(ui, repo, revs, newtopic):
450 """ Changes topic to newtopic of all the revisions in the revset and return 454 """ Changes topic to newtopic of all the revisions in the revset and return
451 the count of revisions whose topic has been changed. 455 the count of revisions whose topic has been changed.
452 """ 456 """
453 rewrote = 0 457 rewrote = 0
454 p1 = None 458 p1 = None
455 p2 = None 459 p2 = None
456 successors = {} 460 successors = {}
457 for c in repo.set('%r', revset): 461 for r in revs:
462 c = repo[r]
463
458 def filectxfn(repo, ctx, path): 464 def filectxfn(repo, ctx, path):
459 try: 465 try:
460 return c[path] 466 return c[path]
461 except error.ManifestLookupError: 467 except error.ManifestLookupError:
462 return None 468 return None