[PATCH] mq: add --currentuser and --user options to qnew and qrefresh
Peter Arrenbrecht
peter.arrenbrecht at gmail.com
Tue Dec 18 02:59:54 CST 2007
Brendan,
I have started the separate patch for the date part. Turns out mq does
not read a plain "Date: " tag, only the "# Date " line within an "# HG
changeset patch". However, some people would be happy if they could
set/update the date when they do qnew/qrefresh and have mq use that
date when they do qpush.
I could
(a) read "Date: " too, but I don't think people really want to read
email dates as commit dates automatically,
(b) only support updating existing "# Date " lines in qrefresh and
write an "#HG changeset patch" header in qnew when -d or -D is
specified; I would then also write "# User " rather than "From:" when
-u or -U is also specified.
(c) switch to "#HG changeset patch" style when -d or -D is specified
to qrefresh, clobbering other headers (they are not read anyway); this
is what you initially suggested even for -u and -U.
I favor (b). It would mean you only get to update dates on patches
that you started with a proper hg patch header (using qnew -D). Since
I expect people to set
[defaults]
qnew = -D -U
qrefresh = -D
that should pan out. It does, however, mean that -d and -D on qrefresh
are only advisory. I cannot let them fail if there is no "# HG
changeset patch" header exactly because they will be used as defaults
and so be active even for non-conforming patches. I might issue a
warning, but I don't really think I should.
Unless you guys object, I'll continue with (b), as outlined above, in
a few days.
-peter
On Dec 18, 2007 8:57 AM, Peter Arrenbrecht <peter.arrenbrecht at gmail.com> wrote:
> # HG changeset patch
> # User peter.arrenbrecht at gmail.com
> # Date 1197963907 -3600
> # Node ID 10fa9311ee977ac413e0575cf9c02004f0ba565f
> # Parent 812dbb08d59a6ccfdb873bb50f752c4e0272c518
> mq: add --currentuser and --user options to qnew and qrefresh
>
> These options make qnew and qrefresh add/update the "From:" header (or, if present,
> the "# User" header). This allows proper attribution of patches in patch queues
> with multiple contributors.
>
> diff --git a/hgext/mq.py b/hgext/mq.py
> --- a/hgext/mq.py
> +++ b/hgext/mq.py
> @@ -603,6 +603,7 @@ class queue:
> def new(self, repo, patch, *pats, **opts):
> msg = opts.get('msg')
> force = opts.get('force')
> + user = opts.get('user')
> if os.path.exists(self.join(patch)):
> raise util.Abort(_('patch "%s" already exists') % patch)
> if opts.get('include') or opts.get('exclude') or pats:
> @@ -617,7 +618,7 @@ class queue:
> try:
> insert = self.full_series_end()
> commitmsg = msg and msg or ("[mq]: %s" % patch)
> - n = repo.commit(commitfiles, commitmsg, match=match, force=True)
> + n = repo.commit(commitfiles, commitmsg, user, match=match, force=True)
> if n == None:
> raise util.Abort(_("repo commit failed"))
> self.full_series[insert:insert] = [patch]
> @@ -626,6 +627,8 @@ class queue:
> self.series_dirty = 1
> self.applied_dirty = 1
> p = self.opener(patch, "w")
> + if user:
> + p.write("From: " + user + "\n\n")
> if msg:
> msg = msg + "\n"
> p.write(msg)
> @@ -945,6 +948,22 @@ class queue:
> while message[mi] != comments[ci]:
> ci += 1
> del comments[ci]
> +
> + newuser = opts.get('user')
> + if newuser:
> + # Update all references to a user in the patch header.
> + # If none found, add "From: " header.
> + needfrom = True
> + for prefix in ['# User ', 'From: ']:
> + for i in xrange(len(comments)):
> + if comments[i].startswith(prefix):
> + comments[i] = prefix + newuser
> + needfrom = False
> + break
> + if needfrom:
> + comments = ['From: ' + newuser, ''] + comments
> + user = newuser
> +
> if msg:
> comments.append(msg)
>
> @@ -1070,9 +1089,12 @@ class queue:
> else:
> message = msg
>
> + if not user:
> + user = changes[1]
> +
> self.strip(repo, top, update=False,
> backup='strip')
> - n = repo.commit(filelist, message, changes[1], match=matchfn,
> + n = repo.commit(filelist, message, user, match=matchfn,
> force=1)
> self.applied[-1] = statusentry(revlog.hex(n), patchfn)
> self.applied_dirty = 1
> @@ -1605,6 +1627,12 @@ def prev(ui, repo, **opts):
> return q.qseries(repo, start=l-2, length=1, status='A',
> summary=opts.get('summary'))
>
> +def setupheaderopts(ui, opts):
> + def do(opt,val):
> + if not opts[opt] and opts['current' + opt]:
> + opts[opt] = val
> + do('user', ui.username())
> +
> def new(ui, repo, patch, *args, **opts):
> """create a new patch
>
> @@ -1623,6 +1651,7 @@ def new(ui, repo, patch, *args, **opts):
> if opts['edit']:
> message = ui.edit(message, ui.username())
> opts['msg'] = message
> + setupheaderopts(ui, opts)
> q.new(repo, patch, *args, **opts)
> q.save_dirty()
> return 0
> @@ -1648,6 +1677,7 @@ def refresh(ui, repo, *pats, **opts):
> patch = q.applied[-1].name
> (message, comment, user, date, hasdiff) = q.readheaders(patch)
> message = ui.edit('\n'.join(message), user or ui.username())
> + setupheaderopts(ui, opts)
> ret = q.refresh(repo, pats, msg=message, **opts)
> q.save_dirty()
> return ret
> @@ -2138,6 +2168,10 @@ def reposetup(ui, repo):
>
> seriesopts = [('s', 'summary', None, _('print first line of patch header'))]
>
> +headeropts = [
> + ('U', 'currentuser', None, _('add "From: <current user>" to patch')),
> + ('u', 'user', '', _('add "From: <given user>" to patch'))]
> +
> cmdtable = {
> "qapplied": (applied, [] + seriesopts, _('hg qapplied [-s] [PATCH]')),
> "qclone":
> @@ -2196,7 +2230,7 @@ cmdtable = {
> [('e', 'edit', None, _('edit commit message')),
> ('f', 'force', None, _('import uncommitted changes into patch')),
> ('g', 'git', None, _('use git extended diff format')),
> - ] + commands.walkopts + commands.commitopts,
> + ] + commands.walkopts + commands.commitopts + headeropts,
> _('hg qnew [-e] [-m TEXT] [-l FILE] [-f] PATCH [FILE]...')),
> "qnext": (next, [] + seriesopts, _('hg qnext [-s]')),
> "qprev": (prev, [] + seriesopts, _('hg qprev [-s]')),
> @@ -2219,7 +2253,7 @@ cmdtable = {
> [('e', 'edit', None, _('edit commit message')),
> ('g', 'git', None, _('use git extended diff format')),
> ('s', 'short', None, _('refresh only files already in the patch')),
> - ] + commands.walkopts + commands.commitopts,
> + ] + commands.walkopts + commands.commitopts + headeropts,
> _('hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] [FILE]...')),
> 'qrename|qmv':
> (rename, [], _('hg qrename PATCH1 [PATCH2]')),
> diff --git a/tests/test-mq-header-from b/tests/test-mq-header-from
> new file mode 100755
> --- /dev/null
> +++ b/tests/test-mq-header-from
> @@ -0,0 +1,107 @@
> +#!/bin/sh
> +
> +echo "[extensions]" >> $HGRCPATH
> +echo "mq=" >> $HGRCPATH
> +echo "[diff]" >> $HGRCPATH
> +echo "nodates=true" >> $HGRCPATH
> +
> +
> +catlog() {
> + cat .hg/patches/$1.patch | sed -e "s/^diff \-r [0-9a-f]* /diff -r ... /"
> + hg log --template "{rev}: {desc} - {author}\n"
> +}
> +
> +
> +echo ==== init
> +hg init a
> +cd a
> +hg qinit
> +
> +
> +echo ==== qnew -U
> +hg qnew -U 1.patch
> +catlog 1
> +
> +echo ==== qref
> +echo "1" >1
> +hg add
> +hg qref
> +catlog 1
> +
> +echo ==== qref -u
> +hg qref -u mary
> +catlog 1
> +
> +echo ==== qnew
> +hg qnew 2.patch
> +echo "2" >2
> +hg add
> +hg qref
> +catlog 2
> +
> +echo ==== qref -u
> +hg qref -u jane
> +catlog 2
> +
> +
> +echo ==== qnew -U -m
> +hg qnew -U -m "Three" 3.patch
> +catlog 3
> +
> +echo ==== qref
> +echo "3" >3
> +hg add
> +hg qref
> +catlog 3
> +
> +echo ==== qref -m
> +hg qref -m "Drei"
> +catlog 3
> +
> +echo ==== qref -u
> +hg qref -u mary
> +catlog 3
> +
> +echo ==== qref -u -m
> +hg qref -u maria -m "Three (again)"
> +catlog 3
> +
> +echo ==== qnew -m
> +hg qnew -m "Four" 4.patch
> +echo "4" >4
> +hg add
> +hg qref
> +catlog 4
> +
> +echo ==== qref -u
> +hg qref -u jane
> +catlog 4
> +
> +
> +echo ==== qnew with HG header
> +hg qnew 5.patch
> +hg qpop
> +echo "# HG changeset patch" >>.hg/patches/5.patch
> +echo "# User johndoe" >>.hg/patches/5.patch
> +hg qpush
> +catlog 5
> +
> +echo ==== hg qref
> +echo "5" >5
> +hg add
> +hg qref
> +catlog 5
> +
> +echo ==== hg qref -U
> +hg qref -U
> +catlog 5
> +
> +echo ==== hg qref -u
> +hg qref -u johndeere
> +catlog 5
> +
> +
> +echo ==== "qpop -a / qpush -a"
> +hg qpop -a
> +hg qpush -a
> +hg log --template "{rev}: {desc} - {author}\n"
> diff --git a/tests/test-mq-header-from.out b/tests/test-mq-header-from.out
> new file mode 100644
> --- /dev/null
> +++ b/tests/test-mq-header-from.out
> @@ -0,0 +1,201 @@
> +==== init
> +==== qnew -U
> +From: test
> +
> +0: [mq]: 1.patch - test
> +==== qref
> +adding 1
> +From: test
> +
> +diff -r ... 1
> +--- /dev/null
> ++++ b/1
> +@@ -0,0 +1,1 @@
> ++1
> +0: [mq]: 1.patch - test
> +==== qref -u
> +From: mary
> +
> +diff -r ... 1
> +--- /dev/null
> ++++ b/1
> +@@ -0,0 +1,1 @@
> ++1
> +0: [mq]: 1.patch - mary
> +==== qnew
> +adding 2
> +diff -r ... 2
> +--- /dev/null
> ++++ b/2
> +@@ -0,0 +1,1 @@
> ++2
> +1: [mq]: 2.patch - test
> +0: [mq]: 1.patch - mary
> +==== qref -u
> +From: jane
> +
> +
> +diff -r ... 2
> +--- /dev/null
> ++++ b/2
> +@@ -0,0 +1,1 @@
> ++2
> +1: [mq]: 2.patch - jane
> +0: [mq]: 1.patch - mary
> +==== qnew -U -m
> +From: test
> +
> +Three
> +2: Three - test
> +1: [mq]: 2.patch - jane
> +0: [mq]: 1.patch - mary
> +==== qref
> +adding 3
> +From: test
> +
> +Three
> +
> +diff -r ... 3
> +--- /dev/null
> ++++ b/3
> +@@ -0,0 +1,1 @@
> ++3
> +2: Three - test
> +1: [mq]: 2.patch - jane
> +0: [mq]: 1.patch - mary
> +==== qref -m
> +From: test
> +
> +Drei
> +
> +diff -r ... 3
> +--- /dev/null
> ++++ b/3
> +@@ -0,0 +1,1 @@
> ++3
> +2: Drei - test
> +1: [mq]: 2.patch - jane
> +0: [mq]: 1.patch - mary
> +==== qref -u
> +From: mary
> +
> +Drei
> +
> +diff -r ... 3
> +--- /dev/null
> ++++ b/3
> +@@ -0,0 +1,1 @@
> ++3
> +2: Drei - mary
> +1: [mq]: 2.patch - jane
> +0: [mq]: 1.patch - mary
> +==== qref -u -m
> +From: maria
> +
> +Three (again)
> +
> +diff -r ... 3
> +--- /dev/null
> ++++ b/3
> +@@ -0,0 +1,1 @@
> ++3
> +2: Three (again) - maria
> +1: [mq]: 2.patch - jane
> +0: [mq]: 1.patch - mary
> +==== qnew -m
> +adding 4
> +Four
> +
> +diff -r ... 4
> +--- /dev/null
> ++++ b/4
> +@@ -0,0 +1,1 @@
> ++4
> +3: Four - test
> +2: Three (again) - maria
> +1: [mq]: 2.patch - jane
> +0: [mq]: 1.patch - mary
> +==== qref -u
> +From: jane
> +
> +Four
> +
> +diff -r ... 4
> +--- /dev/null
> ++++ b/4
> +@@ -0,0 +1,1 @@
> ++4
> +3: Four - jane
> +2: Three (again) - maria
> +1: [mq]: 2.patch - jane
> +0: [mq]: 1.patch - mary
> +==== qnew with HG header
> +Now at: 4.patch
> +applying 5.patch
> +/usr/bin/patch: **** Only garbage was found in the patch input.
> +patch failed, unable to continue (try -v)
> +patch 5.patch is empty
> +Now at: 5.patch
> +# HG changeset patch
> +# User johndoe
> +4: imported patch 5.patch - johndoe
> +3: Four - jane
> +2: Three (again) - maria
> +1: [mq]: 2.patch - jane
> +0: [mq]: 1.patch - mary
> +==== hg qref
> +adding 5
> +# HG changeset patch
> +# User johndoe
> +
> +diff -r ... 5
> +--- /dev/null
> ++++ b/5
> +@@ -0,0 +1,1 @@
> ++5
> +4: [mq]: 5.patch - johndoe
> +3: Four - jane
> +2: Three (again) - maria
> +1: [mq]: 2.patch - jane
> +0: [mq]: 1.patch - mary
> +==== hg qref -U
> +# HG changeset patch
> +# User test
> +
> +diff -r ... 5
> +--- /dev/null
> ++++ b/5
> +@@ -0,0 +1,1 @@
> ++5
> +4: [mq]: 5.patch - test
> +3: Four - jane
> +2: Three (again) - maria
> +1: [mq]: 2.patch - jane
> +0: [mq]: 1.patch - mary
> +==== hg qref -u
> +# HG changeset patch
> +# User johndeere
> +
> +diff -r ... 5
> +--- /dev/null
> ++++ b/5
> +@@ -0,0 +1,1 @@
> ++5
> +4: [mq]: 5.patch - johndeere
> +3: Four - jane
> +2: Three (again) - maria
> +1: [mq]: 2.patch - jane
> +0: [mq]: 1.patch - mary
> +==== qpop -a / qpush -a
> +Patch queue now empty
> +applying 1.patch
> +applying 2.patch
> +applying 3.patch
> +applying 4.patch
> +applying 5.patch
> +Now at: 5.patch
> +4: imported patch 5.patch - johndeere
> +3: Four - jane
> +2: Three (again) - maria
> +1: imported patch 2.patch - jane
> +0: imported patch 1.patch - mary
>
More information about the Mercurial-devel
mailing list