mq: add --currentdate and --date options to qnew and qrefresh
These options make qnew add and qrefresh update a "# Date "-style
header line. This allows proper recording of creation / last
modification dates of patches in patch queues.
Note that `qrefresh -D` only updates existing header lines. It never
adds them, and does not warn about this. This is because I expect
people to have `[default] qrefresh -D` in their .hgrc so patches with
tracked dates get updated, others are left unchanged. The suggested
setup in .hgrc is, in fact,
[default]
qnew = -D -U
qrefresh = -D
I tried to not mix header styles, so `qnew -D -U` now writes the user in
"# User "-style, while `qnew -U` still writes it "From: "-style. Also, if
`qrefresh -U` must add the user, it does so in "# User "-style if the
header contains a "# HG changeset patch" line. (This is caused by mq
not supporting the "Date: "-style header line at all - a reasonable choice
given its standard date format.)
--- a/hgext/mq.py Mon Dec 31 09:15:39 2007 -0600
+++ b/hgext/mq.py Wed Jan 02 16:24:13 2008 +0100
@@ -604,6 +604,7 @@
msg = opts.get('msg')
force = opts.get('force')
user = opts.get('user')
+ date = opts.get('date')
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:
@@ -618,7 +619,7 @@
try:
insert = self.full_series_end()
commitmsg = msg and msg or ("[mq]: %s" % patch)
- n = repo.commit(commitfiles, commitmsg, user, match=match, force=True)
+ n = repo.commit(commitfiles, commitmsg, user, date, match=match, force=True)
if n == None:
raise util.Abort(_("repo commit failed"))
self.full_series[insert:insert] = [patch]
@@ -627,8 +628,15 @@
self.series_dirty = 1
self.applied_dirty = 1
p = self.opener(patch, "w")
- if user:
- p.write("From: " + user + "\n\n")
+ if date:
+ p.write("# HG changeset patch\n")
+ if user:
+ p.write("# User " + user + "\n")
+ p.write("# Date " + date + "\n")
+ p.write("\n")
+ elif user:
+ p.write("From: " + user + "\n")
+ p.write("\n")
if msg:
msg = msg + "\n"
p.write(msg)
@@ -949,21 +957,33 @@
ci += 1
del comments[ci]
+ def setheaderfield(comments, prefixes, new):
+ # Update all references to a field in the patch header.
+ # If none found, add it email style.
+ res = False
+ for prefix in prefixes:
+ for i in xrange(len(comments)):
+ if comments[i].startswith(prefix):
+ comments[i] = prefix + new
+ res = True
+ break
+ return res
+
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
+ if not setheaderfield(comments, ['From: ', '# User '], newuser):
+ try:
+ patchheaderat = comments.index('# HG changeset patch')
+ comments.insert(patchheaderat + 1,'# User ' + newuser)
+ except ValueError:
+ comments = ['From: ' + newuser, ''] + comments
user = newuser
+ newdate = opts.get('date')
+ if newdate:
+ if setheaderfield(comments, ['# Date '], newdate):
+ date = newdate
+
if msg:
comments.append(msg)
@@ -1094,7 +1114,7 @@
self.strip(repo, top, update=False,
backup='strip')
- n = repo.commit(filelist, message, user, match=matchfn,
+ n = repo.commit(filelist, message, user, date, match=matchfn,
force=1)
self.applied[-1] = statusentry(revlog.hex(n), patchfn)
self.applied_dirty = 1
@@ -1632,6 +1652,7 @@
if not opts[opt] and opts['current' + opt]:
opts[opt] = val
do('user', ui.username())
+ do('date', "%d %d" % util.makedate())
def new(ui, repo, patch, *args, **opts):
"""create a new patch
@@ -2170,7 +2191,9 @@
headeropts = [
('U', 'currentuser', None, _('add "From: <current user>" to patch')),
- ('u', 'user', '', _('add "From: <given user>" to patch'))]
+ ('u', 'user', '', _('add "From: <given user>" to patch')),
+ ('D', 'currentdate', None, _('add "Date: <current date>" to patch')),
+ ('d', 'date', '', _('add "Date: <given date>" to patch'))]
cmdtable = {
"qapplied": (applied, [] + seriesopts, _('hg qapplied [-s] [PATCH]')),
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-mq-header-date Wed Jan 02 16:24:13 2008 +0100
@@ -0,0 +1,178 @@
+#!/bin/sh
+
+echo "[extensions]" >> $HGRCPATH
+echo "mq=" >> $HGRCPATH
+echo "[diff]" >> $HGRCPATH
+echo "nodates=true" >> $HGRCPATH
+
+
+catpatch() {
+ cat .hg/patches/$1.patch | sed -e "s/^diff \-r [0-9a-f]* /diff -r ... /"
+}
+
+catlog() {
+ catpatch $1
+ hg log --template "{rev}: {desc} - {author}\n"
+}
+
+catlogd() {
+ catpatch $1
+ hg log --template "{rev}: {desc} - {author} - {date}\n"
+}
+
+drop() {
+ hg qpop
+ hg qdel $1.patch
+}
+
+
+echo ==== init
+hg init a
+cd a
+hg qinit
+
+
+echo ==== qnew -d
+hg qnew -d '3 0' 1.patch
+catlogd 1
+
+echo ==== qref
+echo "1" >1
+hg add
+hg qref
+catlogd 1
+
+echo ==== qref -d
+hg qref -d '4 0'
+catlogd 1
+
+
+echo ==== qnew
+hg qnew 2.patch
+echo "2" >2
+hg add
+hg qref
+catlog 2
+
+echo ==== qref -d
+hg qref -d '5 0'
+catlog 2
+
+drop 2
+
+
+echo ==== qnew -d -m
+hg qnew -d '6 0' -m "Three" 3.patch
+catlogd 3
+
+echo ==== qref
+echo "3" >3
+hg add
+hg qref
+catlogd 3
+
+echo ==== qref -m
+hg qref -m "Drei"
+catlogd 3
+
+echo ==== qref -d
+hg qref -d '7 0'
+catlogd 3
+
+echo ==== qref -d -m
+hg qref -d '8 0' -m "Three (again)"
+catlogd 3
+
+
+echo ==== qnew -m
+hg qnew -m "Four" 4.patch
+echo "4" >4
+hg add
+hg qref
+catlog 4
+
+echo ==== qref -d
+hg qref -d '9 0'
+catlog 4
+
+drop 4
+
+
+echo ==== qnew with HG header
+hg qnew 5.patch
+hg qpop
+echo "# HG changeset patch" >>.hg/patches/5.patch
+echo "# Date 10 0" >>.hg/patches/5.patch
+# Drop patch specific error line
+hg qpush 2>&1 | grep -v garbage
+catlogd 5
+
+echo ==== hg qref
+echo "5" >5
+hg add
+hg qref
+catlogd 5
+
+echo ==== hg qref -d
+hg qref -d '11 0'
+catlogd 5
+
+
+echo ==== qnew -u
+hg qnew -u jane 6.patch
+echo "6" >6
+hg add
+hg qref
+catlog 6
+
+echo ==== qref -d
+hg qref -d '12 0'
+catlog 6
+
+drop 6
+
+
+echo ==== qnew -d
+hg qnew -d '13 0' 7.patch
+echo "7" >7
+hg add
+hg qref
+catlog 7
+
+echo ==== qref -u
+hg qref -u john
+catlogd 7
+
+
+echo ==== qnew
+hg qnew 8.patch
+echo "8" >8
+hg add
+hg qref
+catlog 8
+
+echo ==== qref -u -d
+hg qref -u john -d '14 0'
+catlog 8
+
+drop 8
+
+
+echo ==== qnew -m
+hg qnew -m "Nine" 9.patch
+echo "9" >9
+hg add
+hg qref
+catlog 9
+
+echo ==== qref -u -d
+hg qref -u john -d '15 0'
+catlog 9
+
+drop 9
+
+
+echo ==== "qpop -a / qpush -a"
+hg qpop -a
+hg qpush -a
+hg log --template "{rev}: {desc} - {author} - {date}\n"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-mq-header-date.out Wed Jan 02 16:24:13 2008 +0100
@@ -0,0 +1,287 @@
+==== init
+==== qnew -d
+# HG changeset patch
+# Date 3 0
+
+0: [mq]: 1.patch - test - 3.00
+==== qref
+adding 1
+# HG changeset patch
+# Date 3 0
+
+diff -r ... 1
+--- /dev/null
++++ b/1
+@@ -0,0 +1,1 @@
++1
+0: [mq]: 1.patch - test - 3.00
+==== qref -d
+# HG changeset patch
+# Date 4 0
+
+diff -r ... 1
+--- /dev/null
++++ b/1
+@@ -0,0 +1,1 @@
++1
+0: [mq]: 1.patch - test - 4.00
+==== qnew
+adding 2
+diff -r ... 2
+--- /dev/null
++++ b/2
+@@ -0,0 +1,1 @@
++2
+1: [mq]: 2.patch - test
+0: [mq]: 1.patch - test
+==== qref -d
+diff -r ... 2
+--- /dev/null
++++ b/2
+@@ -0,0 +1,1 @@
++2
+1: [mq]: 2.patch - test
+0: [mq]: 1.patch - test
+Now at: 1.patch
+==== qnew -d -m
+# HG changeset patch
+# Date 6 0
+
+Three
+1: Three - test - 6.00
+0: [mq]: 1.patch - test - 4.00
+==== qref
+adding 3
+# HG changeset patch
+# Date 6 0
+
+Three
+
+diff -r ... 3
+--- /dev/null
++++ b/3
+@@ -0,0 +1,1 @@
++3
+1: Three - test - 6.00
+0: [mq]: 1.patch - test - 4.00
+==== qref -m
+# HG changeset patch
+# Date 6 0
+
+Drei
+
+diff -r ... 3
+--- /dev/null
++++ b/3
+@@ -0,0 +1,1 @@
++3
+1: Drei - test - 6.00
+0: [mq]: 1.patch - test - 4.00
+==== qref -d
+# HG changeset patch
+# Date 7 0
+
+Drei
+
+diff -r ... 3
+--- /dev/null
++++ b/3
+@@ -0,0 +1,1 @@
++3
+1: Drei - test - 7.00
+0: [mq]: 1.patch - test - 4.00
+==== qref -d -m
+# HG changeset patch
+# Date 8 0
+
+Three (again)
+
+diff -r ... 3
+--- /dev/null
++++ b/3
+@@ -0,0 +1,1 @@
++3
+1: Three (again) - test - 8.00
+0: [mq]: 1.patch - test - 4.00
+==== qnew -m
+adding 4
+Four
+
+diff -r ... 4
+--- /dev/null
++++ b/4
+@@ -0,0 +1,1 @@
++4
+2: Four - test
+1: Three (again) - test
+0: [mq]: 1.patch - test
+==== qref -d
+Four
+
+diff -r ... 4
+--- /dev/null
++++ b/4
+@@ -0,0 +1,1 @@
++4
+2: Four - test
+1: Three (again) - test
+0: [mq]: 1.patch - test
+Now at: 3.patch
+==== qnew with HG header
+Now at: 3.patch
+applying 5.patch
+patch failed, unable to continue (try -v)
+patch 5.patch is empty
+Now at: 5.patch
+# HG changeset patch
+# Date 10 0
+2: imported patch 5.patch - test - 10.00
+1: Three (again) - test - 8.00
+0: [mq]: 1.patch - test - 4.00
+==== hg qref
+adding 5
+# HG changeset patch
+# Date 10 0
+
+diff -r ... 5
+--- /dev/null
++++ b/5
+@@ -0,0 +1,1 @@
++5
+2: [mq]: 5.patch - test - 10.00
+1: Three (again) - test - 8.00
+0: [mq]: 1.patch - test - 4.00
+==== hg qref -d
+# HG changeset patch
+# Date 11 0
+
+diff -r ... 5
+--- /dev/null
++++ b/5
+@@ -0,0 +1,1 @@
++5
+2: [mq]: 5.patch - test - 11.00
+1: Three (again) - test - 8.00
+0: [mq]: 1.patch - test - 4.00
+==== qnew -u
+adding 6
+From: jane
+
+diff -r ... 6
+--- /dev/null
++++ b/6
+@@ -0,0 +1,1 @@
++6
+3: [mq]: 6.patch - jane
+2: [mq]: 5.patch - test
+1: Three (again) - test
+0: [mq]: 1.patch - test
+==== qref -d
+From: jane
+
+diff -r ... 6
+--- /dev/null
++++ b/6
+@@ -0,0 +1,1 @@
++6
+3: [mq]: 6.patch - jane
+2: [mq]: 5.patch - test
+1: Three (again) - test
+0: [mq]: 1.patch - test
+Now at: 5.patch
+==== qnew -d
+adding 7
+# HG changeset patch
+# Date 13 0
+
+diff -r ... 7
+--- /dev/null
++++ b/7
+@@ -0,0 +1,1 @@
++7
+3: [mq]: 7.patch - test
+2: [mq]: 5.patch - test
+1: Three (again) - test
+0: [mq]: 1.patch - test
+==== qref -u
+# HG changeset patch
+# User john
+# Date 13 0
+
+diff -r ... 7
+--- /dev/null
++++ b/7
+@@ -0,0 +1,1 @@
++7
+3: [mq]: 7.patch - john - 13.00
+2: [mq]: 5.patch - test - 11.00
+1: Three (again) - test - 8.00
+0: [mq]: 1.patch - test - 4.00
+==== qnew
+adding 8
+diff -r ... 8
+--- /dev/null
++++ b/8
+@@ -0,0 +1,1 @@
++8
+4: [mq]: 8.patch - test
+3: [mq]: 7.patch - john
+2: [mq]: 5.patch - test
+1: Three (again) - test
+0: [mq]: 1.patch - test
+==== qref -u -d
+From: john
+
+
+diff -r ... 8
+--- /dev/null
++++ b/8
+@@ -0,0 +1,1 @@
++8
+4: [mq]: 8.patch - john
+3: [mq]: 7.patch - john
+2: [mq]: 5.patch - test
+1: Three (again) - test
+0: [mq]: 1.patch - test
+Now at: 7.patch
+==== qnew -m
+adding 9
+Nine
+
+diff -r ... 9
+--- /dev/null
++++ b/9
+@@ -0,0 +1,1 @@
++9
+4: Nine - test
+3: [mq]: 7.patch - john
+2: [mq]: 5.patch - test
+1: Three (again) - test
+0: [mq]: 1.patch - test
+==== qref -u -d
+From: john
+
+Nine
+
+diff -r ... 9
+--- /dev/null
++++ b/9
+@@ -0,0 +1,1 @@
++9
+4: Nine - john
+3: [mq]: 7.patch - john
+2: [mq]: 5.patch - test
+1: Three (again) - test
+0: [mq]: 1.patch - test
+Now at: 7.patch
+==== qpop -a / qpush -a
+Patch queue now empty
+applying 1.patch
+applying 3.patch
+applying 5.patch
+applying 7.patch
+Now at: 7.patch
+3: imported patch 7.patch - john - 13.00
+2: imported patch 5.patch - test - 11.00
+1: Three (again) - test - 8.00
+0: imported patch 1.patch - test - 4.00