comparison hgext/mq.py @ 34505:91250ff7d48a

py3: fix keyword arguments handling in mq This patch fixes the handling of keyword arguments to functions on Python 3. On python3, the keys of keyword arguments need to str which is unicode. So any keyword argument will get will have str keys and any dictionary we pass as kwargs must have all the keys as str. This patch uses pycompat.(strkwargs|byteskwargs) to do so conversion between bytes keys and str keys and use r'' if there are very less uses and conversion can be prevented. Differential Revision: https://phab.mercurial-scm.org/D972
author Pulkit Goyal <7895pulkit@gmail.com>
date Mon, 02 Oct 2017 04:46:17 +0530
parents b5bbfe176004
children c2d2e18f9700
comparison
equal deleted inserted replaced
34504:8cef8f7d51d0 34505:91250ff7d48a
2264 """print the patches already applied 2264 """print the patches already applied
2265 2265
2266 Returns 0 on success.""" 2266 Returns 0 on success."""
2267 2267
2268 q = repo.mq 2268 q = repo.mq
2269 opts = pycompat.byteskwargs(opts)
2269 2270
2270 if patch: 2271 if patch:
2271 if patch not in q.series: 2272 if patch not in q.series:
2272 raise error.Abort(_("patch %s is not in series file") % patch) 2273 raise error.Abort(_("patch %s is not in series file") % patch)
2273 end = q.series.index(patch) + 1 2274 end = q.series.index(patch) + 1
2297 """print the patches not yet applied 2298 """print the patches not yet applied
2298 2299
2299 Returns 0 on success.""" 2300 Returns 0 on success."""
2300 2301
2301 q = repo.mq 2302 q = repo.mq
2303 opts = pycompat.byteskwargs(opts)
2302 if patch: 2304 if patch:
2303 if patch not in q.series: 2305 if patch not in q.series:
2304 raise error.Abort(_("patch %s is not in series file") % patch) 2306 raise error.Abort(_("patch %s is not in series file") % patch)
2305 start = q.series.index(patch) + 1 2307 start = q.series.index(patch) + 1
2306 else: 2308 else:
2359 2361
2360 hg qimport -e existing-patch -n new-name 2362 hg qimport -e existing-patch -n new-name
2361 2363
2362 Returns 0 if import succeeded. 2364 Returns 0 if import succeeded.
2363 """ 2365 """
2366 opts = pycompat.byteskwargs(opts)
2364 with repo.lock(): # cause this may move phase 2367 with repo.lock(): # cause this may move phase
2365 q = repo.mq 2368 q = repo.mq
2366 try: 2369 try:
2367 imported = q.qimport( 2370 imported = q.qimport(
2368 repo, filename, patchname=opts.get('name'), 2371 repo, filename, patchname=opts.get('name'),
2413 an unversioned patch repository into a versioned one). You can use 2416 an unversioned patch repository into a versioned one). You can use
2414 qcommit to commit changes to this queue repository. 2417 qcommit to commit changes to this queue repository.
2415 2418
2416 This command is deprecated. Without -c, it's implied by other relevant 2419 This command is deprecated. Without -c, it's implied by other relevant
2417 commands. With -c, use :hg:`init --mq` instead.""" 2420 commands. With -c, use :hg:`init --mq` instead."""
2418 return qinit(ui, repo, create=opts.get('create_repo')) 2421 return qinit(ui, repo, create=opts.get(r'create_repo'))
2419 2422
2420 @command("qclone", 2423 @command("qclone",
2421 [('', 'pull', None, _('use pull protocol to copy metadata')), 2424 [('', 'pull', None, _('use pull protocol to copy metadata')),
2422 ('U', 'noupdate', None, 2425 ('U', 'noupdate', None,
2423 _('do not update the new working directories')), 2426 _('do not update the new working directories')),
2443 The patch directory must be a nested Mercurial repository, as 2446 The patch directory must be a nested Mercurial repository, as
2444 would be created by :hg:`init --mq`. 2447 would be created by :hg:`init --mq`.
2445 2448
2446 Return 0 on success. 2449 Return 0 on success.
2447 ''' 2450 '''
2451 opts = pycompat.byteskwargs(opts)
2448 def patchdir(repo): 2452 def patchdir(repo):
2449 """compute a patch repo url from a repo object""" 2453 """compute a patch repo url from a repo object"""
2450 url = repo.url() 2454 url = repo.url()
2451 if url.endswith('/'): 2455 if url.endswith('/'):
2452 url = url[:-1] 2456 url = url[:-1]
2524 _('hg qseries [-ms]')) 2528 _('hg qseries [-ms]'))
2525 def series(ui, repo, **opts): 2529 def series(ui, repo, **opts):
2526 """print the entire series file 2530 """print the entire series file
2527 2531
2528 Returns 0 on success.""" 2532 Returns 0 on success."""
2529 repo.mq.qseries(repo, missing=opts.get('missing'), 2533 repo.mq.qseries(repo, missing=opts.get(r'missing'),
2530 summary=opts.get('summary')) 2534 summary=opts.get(r'summary'))
2531 return 0 2535 return 0
2532 2536
2533 @command("qtop", seriesopts, _('hg qtop [-s]')) 2537 @command("qtop", seriesopts, _('hg qtop [-s]'))
2534 def top(ui, repo, **opts): 2538 def top(ui, repo, **opts):
2535 """print the name of the current patch 2539 """print the name of the current patch
2541 else: 2545 else:
2542 t = 0 2546 t = 0
2543 2547
2544 if t: 2548 if t:
2545 q.qseries(repo, start=t - 1, length=1, status='A', 2549 q.qseries(repo, start=t - 1, length=1, status='A',
2546 summary=opts.get('summary')) 2550 summary=opts.get(r'summary'))
2547 else: 2551 else:
2548 ui.write(_("no patches applied\n")) 2552 ui.write(_("no patches applied\n"))
2549 return 1 2553 return 1
2550 2554
2551 @command("qnext", seriesopts, _('hg qnext [-s]')) 2555 @command("qnext", seriesopts, _('hg qnext [-s]'))
2556 q = repo.mq 2560 q = repo.mq
2557 end = q.seriesend() 2561 end = q.seriesend()
2558 if end == len(q.series): 2562 if end == len(q.series):
2559 ui.write(_("all patches applied\n")) 2563 ui.write(_("all patches applied\n"))
2560 return 1 2564 return 1
2561 q.qseries(repo, start=end, length=1, summary=opts.get('summary')) 2565 q.qseries(repo, start=end, length=1, summary=opts.get(r'summary'))
2562 2566
2563 @command("qprev", seriesopts, _('hg qprev [-s]')) 2567 @command("qprev", seriesopts, _('hg qprev [-s]'))
2564 def prev(ui, repo, **opts): 2568 def prev(ui, repo, **opts):
2565 """print the name of the preceding applied patch 2569 """print the name of the preceding applied patch
2566 2570
2573 if not l: 2577 if not l:
2574 ui.write(_("no patches applied\n")) 2578 ui.write(_("no patches applied\n"))
2575 return 1 2579 return 1
2576 idx = q.series.index(q.applied[-2].name) 2580 idx = q.series.index(q.applied[-2].name)
2577 q.qseries(repo, start=idx, length=1, status='A', 2581 q.qseries(repo, start=idx, length=1, status='A',
2578 summary=opts.get('summary')) 2582 summary=opts.get(r'summary'))
2579 2583
2580 def setupheaderopts(ui, opts): 2584 def setupheaderopts(ui, opts):
2581 if not opts.get('user') and opts.get('currentuser'): 2585 if not opts.get('user') and opts.get('currentuser'):
2582 opts['user'] = ui.username() 2586 opts['user'] = ui.username()
2583 if not opts.get('date') and opts.get('currentdate'): 2587 if not opts.get('date') and opts.get('currentdate'):
2619 is important for preserving permission changes and copy/rename 2623 is important for preserving permission changes and copy/rename
2620 information. 2624 information.
2621 2625
2622 Returns 0 on successful creation of a new patch. 2626 Returns 0 on successful creation of a new patch.
2623 """ 2627 """
2628 opts = pycompat.byteskwargs(opts)
2624 msg = cmdutil.logmessage(ui, opts) 2629 msg = cmdutil.logmessage(ui, opts)
2625 q = repo.mq 2630 q = repo.mq
2626 opts['msg'] = msg 2631 opts['msg'] = msg
2627 setupheaderopts(ui, opts) 2632 setupheaderopts(ui, opts)
2628 q.new(repo, patch, *args, **opts) 2633 q.new(repo, patch, *args, **pycompat.strkwargs(opts))
2629 q.savedirty() 2634 q.savedirty()
2630 return 0 2635 return 0
2631 2636
2632 @command("^qrefresh", 2637 @command("^qrefresh",
2633 [('e', 'edit', None, _('invoke editor on commit messages')), 2638 [('e', 'edit', None, _('invoke editor on commit messages')),
2664 and renames. See the diffs help topic for more information on the 2669 and renames. See the diffs help topic for more information on the
2665 git diff format. 2670 git diff format.
2666 2671
2667 Returns 0 on success. 2672 Returns 0 on success.
2668 """ 2673 """
2674 opts = pycompat.byteskwargs(opts)
2669 q = repo.mq 2675 q = repo.mq
2670 message = cmdutil.logmessage(ui, opts) 2676 message = cmdutil.logmessage(ui, opts)
2671 setupheaderopts(ui, opts) 2677 setupheaderopts(ui, opts)
2672 with repo.wlock(): 2678 with repo.wlock():
2673 ret = q.refresh(repo, pats, msg=message, **opts) 2679 ret = q.refresh(repo, pats, msg=message, **pycompat.strkwargs(opts))
2674 q.savedirty() 2680 q.savedirty()
2675 return ret 2681 return ret
2676 2682
2677 @command("^qdiff", 2683 @command("^qdiff",
2678 cmdutil.diffopts + cmdutil.diffopts2 + cmdutil.walkopts, 2684 cmdutil.diffopts + cmdutil.diffopts2 + cmdutil.walkopts,
2692 qrefresh. 2698 qrefresh.
2693 2699
2694 Returns 0 on success. 2700 Returns 0 on success.
2695 """ 2701 """
2696 ui.pager('qdiff') 2702 ui.pager('qdiff')
2697 repo.mq.diff(repo, pats, opts) 2703 repo.mq.diff(repo, pats, pycompat.byteskwargs(opts))
2698 return 0 2704 return 0
2699 2705
2700 @command('qfold', 2706 @command('qfold',
2701 [('e', 'edit', None, _('invoke editor on commit messages')), 2707 [('e', 'edit', None, _('invoke editor on commit messages')),
2702 ('k', 'keep', None, _('keep folded patch files')), 2708 ('k', 'keep', None, _('keep folded patch files')),
2714 2720
2715 The header for each folded patch will be concatenated with the 2721 The header for each folded patch will be concatenated with the
2716 current patch header, separated by a line of ``* * *``. 2722 current patch header, separated by a line of ``* * *``.
2717 2723
2718 Returns 0 on success.""" 2724 Returns 0 on success."""
2725 opts = pycompat.byteskwargs(opts)
2719 q = repo.mq 2726 q = repo.mq
2720 if not files: 2727 if not files:
2721 raise error.Abort(_('qfold requires at least one patch name')) 2728 raise error.Abort(_('qfold requires at least one patch name'))
2722 if not q.checktoppatch(repo)[0]: 2729 if not q.checktoppatch(repo)[0]:
2723 raise error.Abort(_('no patches applied')) 2730 raise error.Abort(_('no patches applied'))
2772 _('hg qgoto [OPTION]... PATCH')) 2779 _('hg qgoto [OPTION]... PATCH'))
2773 def goto(ui, repo, patch, **opts): 2780 def goto(ui, repo, patch, **opts):
2774 '''push or pop patches until named patch is at top of stack 2781 '''push or pop patches until named patch is at top of stack
2775 2782
2776 Returns 0 on success.''' 2783 Returns 0 on success.'''
2784 opts = pycompat.byteskwargs(opts)
2777 opts = fixkeepchangesopts(ui, opts) 2785 opts = fixkeepchangesopts(ui, opts)
2778 q = repo.mq 2786 q = repo.mq
2779 patch = q.lookup(patch) 2787 patch = q.lookup(patch)
2780 nobackup = opts.get('no_backup') 2788 nobackup = opts.get('no_backup')
2781 keepchanges = opts.get('keep_changes') 2789 keepchanges = opts.get('keep_changes')
2837 ui.write('\n') 2845 ui.write('\n')
2838 q = repo.mq 2846 q = repo.mq
2839 applied = set(p.name for p in q.applied) 2847 applied = set(p.name for p in q.applied)
2840 patch = None 2848 patch = None
2841 args = list(args) 2849 args = list(args)
2842 if opts.get('list'): 2850 if opts.get(r'list'):
2843 if args or opts.get('none'): 2851 if args or opts.get('none'):
2844 raise error.Abort(_('cannot mix -l/--list with options or ' 2852 raise error.Abort(_('cannot mix -l/--list with options or '
2845 'arguments')) 2853 'arguments'))
2846 for i in xrange(len(q.series)): 2854 for i in xrange(len(q.series)):
2847 status(i) 2855 status(i)
2931 Return 0 on success. 2939 Return 0 on success.
2932 """ 2940 """
2933 q = repo.mq 2941 q = repo.mq
2934 mergeq = None 2942 mergeq = None
2935 2943
2944 opts = pycompat.byteskwargs(opts)
2936 opts = fixkeepchangesopts(ui, opts) 2945 opts = fixkeepchangesopts(ui, opts)
2937 if opts.get('merge'): 2946 if opts.get('merge'):
2938 if opts.get('name'): 2947 if opts.get('name'):
2939 newpath = repo.vfs.join(opts.get('name')) 2948 newpath = repo.vfs.join(opts.get('name'))
2940 else: 2949 else:
2971 overlap with patched files. With -f/--force, backup and discard 2980 overlap with patched files. With -f/--force, backup and discard
2972 changes made to such files. 2981 changes made to such files.
2973 2982
2974 Return 0 on success. 2983 Return 0 on success.
2975 """ 2984 """
2985 opts = pycompat.byteskwargs(opts)
2976 opts = fixkeepchangesopts(ui, opts) 2986 opts = fixkeepchangesopts(ui, opts)
2977 localupdate = True 2987 localupdate = True
2978 if opts.get('name'): 2988 if opts.get('name'):
2979 q = queue(ui, repo.baseui, repo.path, repo.vfs.join(opts.get('name'))) 2989 q = queue(ui, repo.baseui, repo.path, repo.vfs.join(opts.get('name')))
2980 ui.warn(_('using patch queue: %s\n') % q.path) 2990 ui.warn(_('using patch queue: %s\n') % q.path)
3050 """restore the queue state saved by a revision (DEPRECATED) 3060 """restore the queue state saved by a revision (DEPRECATED)
3051 3061
3052 This command is deprecated, use :hg:`rebase` instead.""" 3062 This command is deprecated, use :hg:`rebase` instead."""
3053 rev = repo.lookup(rev) 3063 rev = repo.lookup(rev)
3054 q = repo.mq 3064 q = repo.mq
3055 q.restore(repo, rev, delete=opts.get('delete'), 3065 q.restore(repo, rev, delete=opts.get(r'delete'),
3056 qupdate=opts.get('update')) 3066 qupdate=opts.get(r'update'))
3057 q.savedirty() 3067 q.savedirty()
3058 return 0 3068 return 0
3059 3069
3060 @command("qsave", 3070 @command("qsave",
3061 [('c', 'copy', None, _('copy patch directory')), 3071 [('c', 'copy', None, _('copy patch directory')),
3067 def save(ui, repo, **opts): 3077 def save(ui, repo, **opts):
3068 """save current queue state (DEPRECATED) 3078 """save current queue state (DEPRECATED)
3069 3079
3070 This command is deprecated, use :hg:`rebase` instead.""" 3080 This command is deprecated, use :hg:`rebase` instead."""
3071 q = repo.mq 3081 q = repo.mq
3082 opts = pycompat.byteskwargs(opts)
3072 message = cmdutil.logmessage(ui, opts) 3083 message = cmdutil.logmessage(ui, opts)
3073 ret = q.save(repo, msg=message) 3084 ret = q.save(repo, msg=message)
3074 if ret: 3085 if ret:
3075 return ret 3086 return ret
3076 q.savedirty() # save to .hg/patches before copying 3087 q.savedirty() # save to .hg/patches before copying
3136 (no other arguments needed). Use -v for more information. 3147 (no other arguments needed). Use -v for more information.
3137 3148
3138 Returns 0 on success.''' 3149 Returns 0 on success.'''
3139 3150
3140 q = repo.mq 3151 q = repo.mq
3152 opts = pycompat.byteskwargs(opts)
3141 guards = q.active() 3153 guards = q.active()
3142 pushable = lambda i: q.pushable(q.applied[i].name)[0] 3154 pushable = lambda i: q.pushable(q.applied[i].name)[0]
3143 if args or opts.get('none'): 3155 if args or opts.get('none'):
3144 old_unapplied = q.unapplied(repo) 3156 old_unapplied = q.unapplied(repo)
3145 old_guarded = [i for i in xrange(len(q.applied)) if not pushable(i)] 3157 old_guarded = [i for i in xrange(len(q.applied)) if not pushable(i)]
3224 an upstream repository, or if you are about to push your changes 3236 an upstream repository, or if you are about to push your changes
3225 to upstream. 3237 to upstream.
3226 3238
3227 Returns 0 on success. 3239 Returns 0 on success.
3228 """ 3240 """
3229 if not opts.get('applied') and not revrange: 3241 if not opts.get(r'applied') and not revrange:
3230 raise error.Abort(_('no revisions specified')) 3242 raise error.Abort(_('no revisions specified'))
3231 elif opts.get('applied'): 3243 elif opts.get(r'applied'):
3232 revrange = ('qbase::qtip',) + revrange 3244 revrange = ('qbase::qtip',) + revrange
3233 3245
3234 q = repo.mq 3246 q = repo.mq
3235 if not q.applied: 3247 if not q.applied:
3236 ui.status(_('no patches applied\n')) 3248 ui.status(_('no patches applied\n'))
3355 continue 3367 continue
3356 fh.write('%s\n' % (queue,)) 3368 fh.write('%s\n' % (queue,))
3357 fh.close() 3369 fh.close()
3358 repo.vfs.rename('patches.queues.new', _allqueues) 3370 repo.vfs.rename('patches.queues.new', _allqueues)
3359 3371
3372 opts = pycompat.byteskwargs(opts)
3360 if not name or opts.get('list') or opts.get('active'): 3373 if not name or opts.get('list') or opts.get('active'):
3361 current = _getcurrent() 3374 current = _getcurrent()
3362 if opts.get('active'): 3375 if opts.get('active'):
3363 ui.write('%s\n' % (current,)) 3376 ui.write('%s\n' % (current,))
3364 return 3377 return
3526 3539
3527 repo._phasedefaults.append(mqphasedefaults) 3540 repo._phasedefaults.append(mqphasedefaults)
3528 3541
3529 def mqimport(orig, ui, repo, *args, **kwargs): 3542 def mqimport(orig, ui, repo, *args, **kwargs):
3530 if (util.safehasattr(repo, 'abortifwdirpatched') 3543 if (util.safehasattr(repo, 'abortifwdirpatched')
3531 and not kwargs.get('no_commit', False)): 3544 and not kwargs.get(r'no_commit', False)):
3532 repo.abortifwdirpatched(_('cannot import over an applied patch'), 3545 repo.abortifwdirpatched(_('cannot import over an applied patch'),
3533 kwargs.get('force')) 3546 kwargs.get(r'force'))
3534 return orig(ui, repo, *args, **kwargs) 3547 return orig(ui, repo, *args, **kwargs)
3535 3548
3536 def mqinit(orig, ui, *args, **kwargs): 3549 def mqinit(orig, ui, *args, **kwargs):
3537 mq = kwargs.pop('mq', None) 3550 mq = kwargs.pop(r'mq', None)
3538 3551
3539 if not mq: 3552 if not mq:
3540 return orig(ui, *args, **kwargs) 3553 return orig(ui, *args, **kwargs)
3541 3554
3542 if args: 3555 if args: