comparison hgext/evolve.py @ 1782:a046e78c3290

fold: require --from flag for folding revisions to working copy It's very easy to think that "hg fold 4::6" will fold exactly those revisions. In reality, it will fold those *and* any revisions between them and the working copy. To prevent users from making that mistake, require the use of a new --from flag for folding revisions from the given set to the working copy. With this change, I'm sure some users will be surprised that the command can not be run without either --from or --exact, but at least the consequences will be smaller (the command simply aborts and the user can try again).
author Martin von Zweigbergk <martinvonz@google.com>
date Thu, 12 Jan 2017 13:47:49 -0800
parents 39ef492603c6
children f22120b12715
comparison
equal deleted inserted replaced
1781:39ef492603c6 1782:a046e78c3290
3066 finally: 3066 finally:
3067 lockmod.release(tr, lock, wlock) 3067 lockmod.release(tr, lock, wlock)
3068 3068
3069 @command('^fold|squash', 3069 @command('^fold|squash',
3070 [('r', 'rev', [], _("revision to fold")), 3070 [('r', 'rev', [], _("revision to fold")),
3071 ('', 'exact', None, _("only fold specified revisions")) 3071 ('', 'exact', None, _("only fold specified revisions")),
3072 ('', 'from', None, _("fold revisions linearly to working copy parent"))
3072 ] + commitopts + commitopts2, 3073 ] + commitopts + commitopts2,
3073 _('hg fold [OPTION]... [-r] REV')) 3074 _('hg fold [OPTION]... [-r] REV'))
3074 def fold(ui, repo, *revs, **opts): 3075 def fold(ui, repo, *revs, **opts):
3075 """fold multiple revisions into a single one 3076 """fold multiple revisions into a single one
3076 3077
3077 By default, folds all the revisions linearly between the given revisions 3078 With --from, folds all the revisions linearly between the given revisions
3078 and the parent of the working directory. 3079 and the parent of the working directory.
3079 3080
3080 Use --exact for folding only the specified revisions while ignoring the 3081 With --exact, folds only the specified revisions while ignoring the
3081 parent of the working directory. In this case, the given revisions must 3082 parent of the working directory. In this case, the given revisions must
3082 form a linear unbroken chain. 3083 form a linear unbroken chain.
3083 3084
3084 .. container:: verbose 3085 .. container:: verbose
3085 3086
3086 Some examples: 3087 Some examples:
3087 3088
3088 - Fold the current revision with its parent:: 3089 - Fold the current revision with its parent::
3089 3090
3090 hg fold .^ 3091 hg fold --from .^
3091 3092
3092 - Fold all draft revisions with working directory parent:: 3093 - Fold all draft revisions with working directory parent::
3093 3094
3094 hg fold 'draft()' 3095 hg fold --from 'draft()'
3095 3096
3096 See :hg:`help phases` for more about draft revisions and 3097 See :hg:`help phases` for more about draft revisions and
3097 :hg:`help revsets` for more about the `draft()` keyword 3098 :hg:`help revsets` for more about the `draft()` keyword
3098 3099
3099 - Fold revisions between 3 and 6 with the working directory parent:: 3100 - Fold revisions between 3 and 6 with the working directory parent::
3100 3101
3101 hg fold 3::6 3102 hg fold --from 3::6
3102 3103
3103 - Fold revisions 3 and 4: 3104 - Fold revisions 3 and 4:
3104 3105
3105 hg fold "3 + 4" --exact 3106 hg fold "3 + 4" --exact
3106 3107
3113 if not revs: 3114 if not revs:
3114 raise error.Abort(_('no revisions specified')) 3115 raise error.Abort(_('no revisions specified'))
3115 3116
3116 revs = scmutil.revrange(repo, revs) 3117 revs = scmutil.revrange(repo, revs)
3117 3118
3118 if not opts['exact']: 3119 if opts['from'] and opts['exact']:
3120 raise error.Abort(_('cannot use both --from and --exact'))
3121 elif opts['from']:
3119 # Try to extend given revision starting from the working directory 3122 # Try to extend given revision starting from the working directory
3120 extrevs = repo.revs('(%ld::.) or (.::%ld)', revs, revs) 3123 extrevs = repo.revs('(%ld::.) or (.::%ld)', revs, revs)
3121 discardedrevs = [r for r in revs if r not in extrevs] 3124 discardedrevs = [r for r in revs if r not in extrevs]
3122 if discardedrevs: 3125 if discardedrevs:
3123 raise error.Abort(_("cannot fold non-linear revisions"), 3126 raise error.Abort(_("cannot fold non-linear revisions"),
3124 hint=_("given revisions are unrelated to parent " 3127 hint=_("given revisions are unrelated to parent "
3125 "of working directory")) 3128 "of working directory"))
3126 revs = extrevs 3129 revs = extrevs
3130 elif opts['exact']:
3131 # Nothing to do; "revs" is already set correctly
3132 pass
3133 else:
3134 raise error.Abort(_('must specify either --from or --exact'))
3127 3135
3128 if len(revs) == 1: 3136 if len(revs) == 1:
3129 ui.write_err(_('single revision specified, nothing to fold\n')) 3137 ui.write_err(_('single revision specified, nothing to fold\n'))
3130 return 1 3138 return 1
3131 3139