hgext3rd/topic/__init__.py
branchmercurial-4.8
changeset 4356 a71f2271ed76
parent 4320 b4bc185bcefb
child 4365 8c4289d0e91e
equal deleted inserted replaced
4355:75db6a9d0b54 4356:a71f2271ed76
   175               # (first pick I could think off, update as needed
   175               # (first pick I could think off, update as needed
   176               'log.topic': 'green_background',
   176               'log.topic': 'green_background',
   177               'topic.active': 'green',
   177               'topic.active': 'green',
   178              }
   178              }
   179 
   179 
   180 __version__ = '0.12.4.dev'
   180 __version__ = '0.13.0.dev'
   181 
   181 
   182 testedwith = '4.3.3 4.4.2 4.5.2 4.6.2 4.7 4.8'
   182 testedwith = '4.4.2 4.5.2 4.6.2 4.7 4.8'
   183 minimumhgversion = '4.3'
   183 minimumhgversion = '4.4'
   184 buglink = 'https://bz.mercurial-scm.org/'
   184 buglink = 'https://bz.mercurial-scm.org/'
   185 
   185 
   186 if util.safehasattr(registrar, 'configitem'):
   186 if util.safehasattr(registrar, 'configitem'):
   187 
   187 
   188     from mercurial import configitems
   188     from mercurial import configitems
   678             wl = repo.wlock()
   678             wl = repo.wlock()
   679             lock = repo.lock()
   679             lock = repo.lock()
   680             txn = repo.transaction('rewrite-topics')
   680             txn = repo.transaction('rewrite-topics')
   681             rewrote = _changetopics(ui, repo, touchedrevs, topic)
   681             rewrote = _changetopics(ui, repo, touchedrevs, topic)
   682             txn.close()
   682             txn.close()
   683             ui.status('changed topic on %d changes\n' % rewrote)
   683             if topic is None:
       
   684                 ui.status('cleared topic on %d changesets\n' % rewrote)
       
   685             else:
       
   686                 ui.status('changed topic on %d changesets to "%s"\n' % (rewrote,
       
   687                                                                         topic))
   684         finally:
   688         finally:
   685             lockmod.release(txn, lock, wl)
   689             lockmod.release(txn, lock, wl)
   686             repo.invalidate()
   690             repo.invalidate()
   687         return
   691         return
   688 
   692 
   715     else:
   719     else:
   716         _listtopics(ui, repo, opts)
   720         _listtopics(ui, repo, opts)
   717     return ret
   721     return ret
   718 
   722 
   719 @command('stack', [
   723 @command('stack', [
       
   724         ('c', 'children', None,
       
   725             _('display data about children outside of the stack'))
   720     ] + commands.formatteropts,
   726     ] + commands.formatteropts,
   721     _('hg stack [TOPIC]'))
   727     _('hg stack [TOPIC]'))
   722 def cmdstack(ui, repo, topic='', **opts):
   728 def cmdstack(ui, repo, topic='', **opts):
   723     """list all changesets in a topic and other information
   729     """list all changesets in a topic and other information
   724 
   730 
   948             hg.update(repo, newid[0], quietempty=True)
   954             hg.update(repo, newid[0], quietempty=True)
   949     return rewrote
   955     return rewrote
   950 
   956 
   951 def _listtopics(ui, repo, opts):
   957 def _listtopics(ui, repo, opts):
   952     fm = ui.formatter('topics', opts)
   958     fm = ui.formatter('topics', opts)
   953     showlast = opts.get('age')
       
   954     if showlast:
       
   955         # we have a new function as plugging logic into existing function is
       
   956         # pretty much difficult
       
   957         return _showlasttouched(repo, fm, opts)
       
   958     activetopic = repo.currenttopic
   959     activetopic = repo.currenttopic
   959     namemask = '%s'
   960     namemask = '%s'
   960     if repo.topics:
   961     if repo.topics:
   961         maxwidth = max(len(t) for t in repo.topics)
   962         maxwidth = max(len(t) for t in repo.topics)
   962         namemask = '%%-%is' % maxwidth
   963         namemask = '%%-%is' % maxwidth
   963     for topic in sorted(repo.topics):
   964     if opts.get('age'):
       
   965         # here we sort by age and topic name
       
   966         topicsdata = sorted(_getlasttouched(repo, repo.topics))
       
   967     else:
       
   968         # here we sort by topic name only
       
   969         topicsdata = (
       
   970             (None, topic, None, None)
       
   971             for topic in sorted(repo.topics)
       
   972         )
       
   973     for age, topic, date, user in topicsdata:
   964         fm.startitem()
   974         fm.startitem()
   965         marker = ' '
   975         marker = ' '
   966         label = 'topic'
   976         label = 'topic'
   967         active = (topic == activetopic)
   977         active = (topic == activetopic)
   968         if active:
   978         if active:
   975         fm.data(active=active)
   985         fm.data(active=active)
   976 
   986 
   977         if ui.quiet:
   987         if ui.quiet:
   978             fm.plain('\n')
   988             fm.plain('\n')
   979             continue
   989             continue
       
   990         fm.plain(' (')
       
   991         if date:
       
   992             if age == -1:
       
   993                 timestr = 'empty and active'
       
   994             else:
       
   995                 timestr = templatefilters.age(date)
       
   996             fm.write('lasttouched', '%s', timestr, label='topic.list.time')
       
   997         if user:
       
   998             fm.write('usertouched', ' by %s', user, label='topic.list.user')
       
   999         if date:
       
  1000             fm.plain(', ')
   980         data = stack.stack(repo, topic=topic)
  1001         data = stack.stack(repo, topic=topic)
   981         fm.plain(' (')
       
   982         if ui.verbose:
  1002         if ui.verbose:
   983             fm.write('branches+', 'on branch: %s',
  1003             fm.write('branches+', 'on branch: %s',
   984                      '+'.join(data.branches), # XXX use list directly after 4.0 is released
  1004                      '+'.join(data.branches), # XXX use list directly after 4.0 is released
   985                      label='topic.list.branches')
  1005                      label='topic.list.branches')
   986 
  1006 
  1016                          _('ambiguous destination: %s') % data.behinderror,
  1036                          _('ambiguous destination: %s') % data.behinderror,
  1017                          label='topic.list.behinderror')
  1037                          label='topic.list.behinderror')
  1018         fm.plain(')\n')
  1038         fm.plain(')\n')
  1019     fm.end()
  1039     fm.end()
  1020 
  1040 
  1021 def _showlasttouched(repo, fm, opts):
       
  1022     topics = repo.topics
       
  1023     timedict = _getlasttouched(repo, topics)
       
  1024     times = timedict.keys()
       
  1025     times.sort()
       
  1026     if topics:
       
  1027         maxwidth = max(len(t) for t in topics)
       
  1028         namemask = '%%-%is' % maxwidth
       
  1029     activetopic = repo.currenttopic
       
  1030     for timevalue in times:
       
  1031         curtopics = sorted(timedict[timevalue][1])
       
  1032         for topic, user in curtopics:
       
  1033             fm.startitem()
       
  1034             marker = ' '
       
  1035             label = 'topic'
       
  1036             active = (topic == activetopic)
       
  1037             if active:
       
  1038                 marker = '*'
       
  1039                 label = 'topic.active'
       
  1040             fm.plain(' %s ' % marker, label=label)
       
  1041             fm.write('topic', namemask, topic, label=label)
       
  1042             fm.data(active=active)
       
  1043             fm.plain(' (')
       
  1044             if timevalue == -1:
       
  1045                 timestr = 'empty and active'
       
  1046             else:
       
  1047                 timestr = templatefilters.age(timedict[timevalue][0])
       
  1048             fm.write('lasttouched', '%s', timestr, label='topic.list.time')
       
  1049             if user:
       
  1050                 fm.write('usertouched', ' by %s', user, label='topic.list.user')
       
  1051             fm.plain(')')
       
  1052             fm.plain('\n')
       
  1053     fm.end()
       
  1054 
       
  1055 def _getlasttouched(repo, topics):
  1041 def _getlasttouched(repo, topics):
  1056     """
  1042     """
  1057     Calculates the last time a topic was used. Returns a dictionary of seconds
  1043     Calculates the last time a topic was used. Returns a generator of 4-tuples:
  1058     passed from current time for a topic as keys and topic name as values.
  1044     (age in seconds, topic name, date, and user who last touched the topic).
  1059     """
  1045     """
  1060     topicstime = {}
       
  1061     curtime = time.time()
  1046     curtime = time.time()
  1062     for t in topics:
  1047     for topic in topics:
  1063         secspassed = -1
  1048         age = -1
  1064         user = None
  1049         user = None
  1065         maxtime = (0, 0)
  1050         maxtime = (0, 0)
  1066         trevs = repo.revs("topic(%s)", t)
  1051         trevs = repo.revs("topic(%s)", topic)
  1067         # Need to check for the time of all changesets in the topic, whether
  1052         # Need to check for the time of all changesets in the topic, whether
  1068         # they are obsolete of non-heads
  1053         # they are obsolete of non-heads
  1069         # XXX: can we just rely on the max rev number for this
  1054         # XXX: can we just rely on the max rev number for this
  1070         for revs in trevs:
  1055         for revs in trevs:
  1071             rt = repo[revs].date()
  1056             rt = repo[revs].date()
  1082                 if rt[0] > maxtime[0]:
  1067                 if rt[0] > maxtime[0]:
  1083                     user = marker.metadata().get('user', user)
  1068                     user = marker.metadata().get('user', user)
  1084                     maxtime = rt
  1069                     maxtime = rt
  1085 
  1070 
  1086         username = stack.parseusername(user)
  1071         username = stack.parseusername(user)
  1087         topicuser = (t, username)
       
  1088 
       
  1089         if trevs:
  1072         if trevs:
  1090             secspassed = (curtime - maxtime[0])
  1073             age = curtime - maxtime[0]
  1091         try:
  1074 
  1092             topicstime[secspassed][1].append(topicuser)
  1075         yield (age, topic, maxtime, username)
  1093         except KeyError:
       
  1094             topicstime[secspassed] = (maxtime, [topicuser])
       
  1095 
       
  1096     return topicstime
       
  1097 
  1076 
  1098 def summaryhook(ui, repo):
  1077 def summaryhook(ui, repo):
  1099     t = getattr(repo, 'currenttopic', '')
  1078     t = getattr(repo, 'currenttopic', '')
  1100     if not t:
  1079     if not t:
  1101         return
  1080         return