2587 for f in changes: |
2587 for f in changes: |
2588 ui.write(format % repo.pathto(f, cwd)) |
2588 ui.write(format % repo.pathto(f, cwd)) |
2589 if f in copy and (f in added or f in showcopy): |
2589 if f in copy and (f in added or f in showcopy): |
2590 ui.write(' %s%s' % (repo.pathto(copy[f], cwd), end)) |
2590 ui.write(' %s%s' % (repo.pathto(copy[f], cwd), end)) |
2591 |
2591 |
2592 def tag(ui, repo, name, rev_=None, **opts): |
2592 def tag(ui, repo, name1, *names, **opts): |
2593 """add a tag for the current or given revision |
2593 """add one or more tags for the current or given revision |
2594 |
2594 |
2595 Name a particular revision using <name>. |
2595 Name a particular revision using <name>. |
2596 |
2596 |
2597 Tags are used to name particular revisions of the repository and are |
2597 Tags are used to name particular revisions of the repository and are |
2598 very useful to compare different revisions, to go back to significant |
2598 very useful to compare different revisions, to go back to significant |
2607 necessary. The file '.hg/localtags' is used for local tags (not |
2607 necessary. The file '.hg/localtags' is used for local tags (not |
2608 shared among repositories). |
2608 shared among repositories). |
2609 |
2609 |
2610 See 'hg help dates' for a list of formats valid for -d/--date. |
2610 See 'hg help dates' for a list of formats valid for -d/--date. |
2611 """ |
2611 """ |
2612 if name in ['tip', '.', 'null']: |
2612 |
2613 raise util.Abort(_("the name '%s' is reserved") % name) |
2613 rev_ = None |
2614 if rev_ is not None: |
2614 names = (name1,) + names |
2615 ui.warn(_("use of 'hg tag NAME [REV]' is deprecated, " |
2615 if len(names) != len(dict.fromkeys(names)): |
2616 "please use 'hg tag [-r REV] NAME' instead\n")) |
2616 raise util.Abort(_('tag names must be unique')) |
2617 if opts['rev']: |
2617 for n in names: |
2618 raise util.Abort(_("use only one form to specify the revision")) |
2618 if n in ['tip', '.', 'null']: |
|
2619 raise util.Abort(_('the name \'%s\' is reserved') % n) |
2619 if opts['rev'] and opts['remove']: |
2620 if opts['rev'] and opts['remove']: |
2620 raise util.Abort(_("--rev and --remove are incompatible")) |
2621 raise util.Abort(_("--rev and --remove are incompatible")) |
2621 if opts['rev']: |
2622 if opts['rev']: |
2622 rev_ = opts['rev'] |
2623 rev_ = opts['rev'] |
2623 message = opts['message'] |
2624 message = opts['message'] |
2624 if opts['remove']: |
2625 if opts['remove']: |
2625 tagtype = repo.tagtype(name) |
2626 expectedtype = opts['local'] and 'local' or 'global' |
2626 |
2627 for n in names: |
2627 if not tagtype: |
2628 if not repo.tagtype(n): |
2628 raise util.Abort(_('tag %s does not exist') % name) |
2629 raise util.Abort(_('tag \'%s\' does not exist') % n) |
2629 if opts['local'] and tagtype == 'global': |
2630 if repo.tagtype(n) != expectedtype: |
2630 raise util.Abort(_('%s tag is global') % name) |
2631 raise util.Abort(_('tag \'%s\' is not a %s tag') % |
2631 if not opts['local'] and tagtype == 'local': |
2632 (n, expectedtype)) |
2632 raise util.Abort(_('%s tag is local') % name) |
|
2633 |
|
2634 rev_ = nullid |
2633 rev_ = nullid |
2635 if not message: |
2634 if not message: |
2636 message = _('Removed tag %s') % name |
2635 message = _('Removed tag %s') % ', '.join(names) |
2637 elif name in repo.tags() and not opts['force']: |
2636 elif not opts['force']: |
2638 raise util.Abort(_('a tag named %s already exists (use -f to force)') |
2637 for n in names: |
2639 % name) |
2638 if n in repo.tags(): |
|
2639 raise util.Abort(_('tag \'%s\' already exists ' |
|
2640 '(use -f to force)') % n) |
2640 if not rev_ and repo.dirstate.parents()[1] != nullid: |
2641 if not rev_ and repo.dirstate.parents()[1] != nullid: |
2641 raise util.Abort(_('uncommitted merge - please provide a ' |
2642 raise util.Abort(_('uncommitted merge - please provide a ' |
2642 'specific revision')) |
2643 'specific revision')) |
2643 r = repo.changectx(rev_).node() |
2644 r = repo.changectx(rev_).node() |
2644 |
2645 |
2645 if not message: |
2646 if not message: |
2646 message = _('Added tag %s for changeset %s') % (name, short(r)) |
2647 message = (_('Added tag %s for changeset %s') % |
|
2648 (', '.join(names), short(r))) |
2647 |
2649 |
2648 date = opts.get('date') |
2650 date = opts.get('date') |
2649 if date: |
2651 if date: |
2650 date = util.parsedate(date) |
2652 date = util.parsedate(date) |
2651 |
2653 |
2652 repo.tag(name, r, message, opts['local'], opts['user'], date) |
2654 repo.tag(names, r, message, opts['local'], opts['user'], date) |
2653 |
2655 |
2654 def tags(ui, repo): |
2656 def tags(ui, repo): |
2655 """list repository tags |
2657 """list repository tags |
2656 |
2658 |
2657 List the repository tags. |
2659 List the repository tags. |
3188 ('r', 'rev', '', _('revision to tag')), |
3190 ('r', 'rev', '', _('revision to tag')), |
3189 ('', 'remove', None, _('remove a tag')), |
3191 ('', 'remove', None, _('remove a tag')), |
3190 # -l/--local is already there, commitopts cannot be used |
3192 # -l/--local is already there, commitopts cannot be used |
3191 ('m', 'message', '', _('use <text> as commit message')), |
3193 ('m', 'message', '', _('use <text> as commit message')), |
3192 ] + commitopts2, |
3194 ] + commitopts2, |
3193 _('hg tag [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME')), |
3195 _('hg tag [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...')), |
3194 "tags": (tags, [], _('hg tags')), |
3196 "tags": (tags, [], _('hg tags')), |
3195 "tip": |
3197 "tip": |
3196 (tip, |
3198 (tip, |
3197 [('p', 'patch', None, _('show patch')), |
3199 [('p', 'patch', None, _('show patch')), |
3198 ] + templateopts, |
3200 ] + templateopts, |