[PATCH] mq: add --currentdate and --date options to qnew and qrefresh

Peter Arrenbrecht peter.arrenbrecht at gmail.com
Wed Jan 2 09:27:29 CST 2008


# HG changeset patch
# User Peter Arrenbrecht <peter.arrenbrecht at gmail.com>
# Date 1199287453 -3600
# Node ID 490caf7cde69a67bbfc3c7edaef0eed238e25b6e
# Parent  ebd0a91bad2d7fc877b29774b9f94f9051e58467
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.)

diff --git a/hgext/mq.py b/hgext/mq.py
--- a/hgext/mq.py
+++ b/hgext/mq.py
@@ -604,6 +604,7 @@ class queue:
         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 @@ class queue:
         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 @@ class queue:
             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,20 +957,32 @@ class queue:
                         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 @@ class queue:
 
                 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 @@ def setupheaderopts(ui, opts):
         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 @@ seriesopts = [('s', 'summary', None, _('
 
 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]')),
diff --git a/tests/test-mq-header-date b/tests/test-mq-header-date
new file mode 100755
--- /dev/null
+++ b/tests/test-mq-header-date
@@ -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"
diff --git a/tests/test-mq-header-date.out b/tests/test-mq-header-date.out
new file mode 100644
--- /dev/null
+++ b/tests/test-mq-header-date.out
@@ -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


More information about the Mercurial-devel mailing list