monotone-commits-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Monotone-commits-diffs] net.venge.monotone.log-with-certs: 7a37886ddacc


From: code
Subject: [Monotone-commits-diffs] net.venge.monotone.log-with-certs: 7a37886ddacc3b66ea25eb1cbc340ceaac3d8ab8
Date: Wed, 25 Apr 2012 19:21:50 +0200 (CEST)

revision:            7a37886ddacc3b66ea25eb1cbc340ceaac3d8ab8
date:                2012-04-25T14:32:18
author:              Richard Hopkins <address@hidden>
branch:              net.venge.monotone.log-with-certs
changelog:
propagate from branch 'net.venge.monotone' (head 
7d7661fcd091878e42d265f2544445b3b53b16d1)
            to branch 'net.venge.monotone.log-with-certs' (head 
485dbe5582f16e43a91d56590d402808d4837990)

manifest:
format_version "1"

new_manifest [3f0878075c841e372b8fa198807a0deca95b520b]

old_revision [485dbe5582f16e43a91d56590d402808d4837990]

add_dir "test/func/disapprove_root_revision"

add_file "contrib/basicio.vim"
 content [ff652790f22fb5e3421c0b70b5c45d6c8d470d3b]

add_file "contrib/colortone.pl"
 content [4de0235589831da1b9daeeba18841074c240fe78]

add_file "test/func/disapprove_root_revision/__driver__.lua"
 content [743f82c455ccc4d57b1ee123d0c8fcf7341f8207]

patch "Attic/pcre/README"
 from [420b5f8ab281ef77f9caa6cde682d24ea5f68322]
   to [903cf10e0439d34e3137fa24171f747306da11e5]

patch "Makefile.am"
 from [d8bebdb36192f09f35b5737b9975fce92b11eeb9]
   to [e601735ae7a62b55743bef936b8acf1f2ff490fb]

patch "NEWS"
 from [8cae90559bb06b2bc77c211397218299c1660d13]
   to [38617aa326d5e6371c347e2b14ac51ebbcbc177c]

patch "doc/monotone.texi"
 from [b93a39c40870fce709e383709d45003fb638bc0f]
   to [e0b88a30f08867f9e0f593e5004789ca17753a94]

patch "doc/pcrepattern.texi"
 from [10041ae21b3ce5f6971aca811ce57abc0827da8b]
   to [43ef52850c1fd113b8a21d63634bafe61b3aec45]

patch "extra/mtn-hooks/monotone-buildbot.lua"
 from [41d82aee6613c5d1775fd8ebf97ffd0c29ea807c]
   to [d1439935004ff6fb523dfa6b2c5fd5c8641339ab]

patch "src/cmd.cc"
 from [47891700f02feb1a6278c175fc56f5253c91ea49]
   to [94f7a433246032017e7c9a61645903feef68128e]

patch "src/cmd_diff_log.cc"
 from [b24dffb0470d057fa1e91ccc5a81627b40252e78]
   to [55dcbe5e40b8e706559f8b76a83b7fb81caecde1]

patch "src/cmd_ws_commit.cc"
 from [aa290a0418e1944d17768dd0d07fe6c3f348f2cf]
   to [431aff612ada586c56b63247423ae72df1650b88]

patch "src/database.cc"
 from [4c259f963c440fc95564dfec99b2f832f0bad643]
   to [87efeeff2d3263ba98af684a4022f1897434ed2d]

patch "src/gzip.cc"
 from [e7c19bee910e3d421fd073933810ec52092b1d9b]
   to [9da41f6820cdf39707b22c716e3682e0fa0fd745]

patch "src/gzip.hh"
 from [649dfc0b250954f39c0f73870f8bec3f32f7fa43]
   to [17093f66e365b3730a49ef1910295f622972c36e]

patch "src/key_packet.cc"
 from [d1306df89dd684badac02c03744cd446381c07d3]
   to [c97262d161b23c9640972188979669b3e95afe7b]

patch "src/key_store.cc"
 from [64c4c4bed1fadc26b51207b9f61343f9dd7d3c6e]
   to [b7859345f7c665914d16357409bdff24a48b7996]

patch "src/monotone.cc"
 from [a25ecdd170a601db798b63a60add7681609a34c4]
   to [764bc9ca406b41d21efd552a0d810bc2849e0588]

patch "src/netxx/serverbase.cxx"
 from [7a9b465ce4b0b02cb8ff126acf86d3896b4eb456]
   to [156f2090341d2a36bdb718e7c69df58f9251983e]

patch "src/packet.cc"
 from [f61360ed2524fdf53411bd24d022a2a3c9e6e9c7]
   to [571ff6eae1d269a146da74f2730b70376957d3bb]

patch "src/packet.hh"
 from [0a224e6e92f244e2c3e9a5cdb935eb8613d7e85b]
   to [9c43d30145f0292d6ceda5e717e366fdead5a4d6]

patch "src/pcrewrap.cc"
 from [7f5bd4e7d8d9e02f2b0271fa9a0f64dcbce2467d]
   to [59b11bb0076d4724c95c34840409be6d8357a68e]

patch "src/selectors.cc"
 from [3efba0ce3139290b4088cea0d6e82a912565471e]
   to [588c6b5fd3ded29f5f778a78e707352564acbc02]

patch "src/sha1.cc"
 from [5e1aa972d7c7d66e06320b039989652b830dcd75]
   to [42e48b22fd88b25e0d38d4f91e1f13f8a83c7120]

patch "src/ssh_agent.cc"
 from [6d188e7012a0b82f782563b09bbd7adf3f70cf75]
   to [4a0dcab873559e934e41c5f220b5434d35600d9b]

patch "src/transforms.cc"
 from [cdfb6854ef4992faba21074145f3c8269b845b11]
   to [b99278ffe95c0081bf4986bc74d3699c37a52948]

patch "src/win32/terminal.cc"
 from [036785c31b25174a945c09d04030552377394221]
   to [8aa0b4610e4683fea74c0378e6d934d2829f2799]

patch "src/work.hh"
 from [00e100f44763cad0019683c16c4a13d53a94d5e0]
   to [0ca2a0f0ab94c2421db119216af9373b81f38e61]

patch "test/func/attr_mtn_execute/__driver__.lua"
 from [ac0c1f7ecf54690607e55d5aa43544c023e3700c]
   to [b5bfcf8f4fdb98c59f95da35b93e7d97d08b99e7]

patch "test/func/branch_leaves_sync_bug/__driver__.lua"
 from [6b227867aeb3692dba4e68efdfe5c59ff5c15919]
   to [943c3f2d7c3294e5da221d44911c08511058acb2]

patch "test/func/clone_aborts_on_branch_pattern_in_uri/__driver__.lua"
 from [bf16d8dcec86e4ae012d1c6078082f9d13a9fd80]
   to [e75946886b2b0b4ee301016860238e6315c22a59]

patch "test/func/clone_branch_no_dir/__driver__.lua"
 from [b490cd593cefd9aa0b4dec9ab177eb72c3fb8058]
   to [1ab33d8f6d1bdc38d3804d8fcd41b6c2f65a6e61]

patch "test/func/clone_creates__MTN_log/__driver__.lua"
 from [5a8fe703d56ea39db22dcfbe6183294c1eb3f01b]
   to [b412d2f37df048846fc1f76ab62572d4c39b0796]

patch "test/func/clone_creates_right__MTN_options/__driver__.lua"
 from [12e86831366aa0f5573d1ec511872b6f9034aeb2]
   to [9891e77e30b8830f8040bcb817a0db26a433c9dd]

patch "test/func/clone_validates_target_directory/__driver__.lua"
 from [1286723ee00ea9ea6831e12575ba7ac32a066645]
   to [0c6f70282431ed62359ad0b4a827575406889f4b]

patch "test/func/clone_warning_with_multiple_heads/__driver__.lua"
 from [4333c6de0518517ff9bc04b4baef0d2d5ff08914]
   to [18e8670ea08dcb9602425ebdb97a786b20945ff6]

patch "test/func/clone_weird_branch_names/__driver__.lua"
 from [205c20a2809513b93ee9ab6c1affb24070f284a2]
   to [0afc1816afa8d3e4b2dfb9fd016500f224432f0a]

patch "test/func/extended-selectors/__driver__.lua"
 from [435f44fb1b33bdfb53929fe6bd15ba7fa4c2c1d3]
   to [cab379ef6f3439ab7f5a4424202ebf9097171c4c]

patch "test/func/imp_test_filesync_confdir/__driver__.lua"
 from [5262dae96bcf38a2a27cea3d17523e08ad3e03aa]
   to [19822aa249d9300dc8695f41adbd12cbce5a9234]

patch "test/func/netsync_over_pipes/__driver__.lua"
 from [e4ee774912c36ca34a2bfe897daecac570f626a7]
   to [e769e909c59f15351c957a47d98bd7be5868e9f7]

patch "test/func/serve-automate/__driver__.lua"
 from [ae4b03baf16d8401f31a32c8377021f879788d01]
   to [1343490c3b79e3d936a5b72ba7561055239235f8]

patch "test/func/serve-automate-single-run/__driver__.lua"
 from [01013ad10150f9056bee7609338cb09b47d8c677]
   to [7a75e9ff02a15ebc62a44c1c596ed39e3fdae0a0]

patch "test/func/syntax_errors_in_.mtn-ignore/mtn-ignore"
 from [c46ecd3b4771b7b0af41b6caff2074df0427fbfa]
   to [55bfcaa55ef14ee091aa6279251af51121f910b9]

patch "test/func/util_mtnopt/__driver__.lua"
 from [84307ea94ec302c6d9bbe163955e8f5e86973ce0]
   to [6981b9fe1aa7800aaaf76bd18f0ddbb73b0e6046]

patch "test/src/testlib.lua"
 from [6d2a308918594226fa6549ed0268ccaea3921038]
   to [f236da6fce62c15acac578b42756b552e0453d99]

old_revision [7d7661fcd091878e42d265f2544445b3b53b16d1]

patch "src/rev_output.cc"
 from [a2c70b893b31296917d1a2b974faa1da46c13f1e]
   to [6b9862bfda95d0d558d8335fb2accfc0180e8fbd]
============================================================
--- Attic/pcre/README	420b5f8ab281ef77f9caa6cde682d24ea5f68322
+++ Attic/pcre/README	903cf10e0439d34e3137fa24171f747306da11e5
@@ -1,4 +1,4 @@
-This is the library component of pcre 7.4, downloaded from
+This is the library component of pcre 7.6, downloaded from
 <ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/>.  The only
 modification made to the code is that each .c file has been changed to
 #include "pcre_config.h" unconditionally, instead of "config.h" only when
============================================================
--- Makefile.am	d8bebdb36192f09f35b5737b9975fce92b11eeb9
+++ Makefile.am	e601735ae7a62b55743bef936b8acf1f2ff490fb
@@ -724,6 +724,11 @@ mostlyclean-tests:
 	  rmdir $${d%/*} || :; \
 	done
 
+# With the MacOS X toolchain, some stuff may be generated in the form of subdirs
+.PHONY: mostlyclean-util
+mostlyclean-util:
+	rm -rf util/txt2c.dSYM
+
 MOSTLYCLEANFILES = mtn.1 \
 	run_tester_tests   run_func_tests   run_unit_tests   run_extra_tests \
 	test/tester.status test/func.status test/unit.status test/extra.status
@@ -881,7 +886,7 @@ distcheck-base.hh:
 .PHONY: distcheck-base.hh
 distcheck-base.hh:
 	cd $(srcdir) && $(SHELL) util/audit-includes \
-		$(sort $(mtn_SOURCES) $(test_unit_tester_SOURCES) $(test_bin_tester_SOURCES) \
+		$(sort $(mtn_SOURCES) $(test_bin_unit_tester_SOURCES) $(test_bin_tester_SOURCES) \
                        $(UNIX_PLATFORM_SOURCES) $(WIN32_PLATFORM_SOURCES) \
                        src/win32/main.cc src/unix/main.cc)
 
@@ -896,7 +901,7 @@ uninstall-local: uninstall-nls \
 	install-contrib-data install-examples-data
 uninstall-local: uninstall-nls \
 	uninstall-contrib-data uninstall-examples-data
-mostlyclean-local: mostlyclean-tests
+mostlyclean-local: mostlyclean-tests mostlyclean-util
 check-local: check-testers
 
 # All hooks supported by automake here, depending on all the things we want
============================================================
--- NEWS	8cae90559bb06b2bc77c211397218299c1660d13
+++ NEWS	38617aa326d5e6371c347e2b14ac51ebbcbc177c
@@ -10,10 +10,29 @@ XXX XXX XX XX:XX:XX UTC 201X
           and returns the attributes for a specific file from the
           revision's manifest
 
+        - New 'not(A)' selector is now available which returns all
+          revisions not selected by 'A'.
+           
         Bugs fixed
 
+        - Monotone now compiles against Botan 1.10.x (as well as most of
+          the testing releases in 1.9.y).
+
+        - Struct file_handle got renamed to avoid clash with newer glibc's
+          fcntl.h.
+
+        - Monotone now compiles just fine with gcc's option
+          "-Werror=format-security."
+
+        - Fixed recursive file removal on Solaris.
+
         Internal
 
+        - The performance and memory usage of regular expressions has
+          been improved throughout. This affects any use of the
+          ".mtn-ignore" file such as "mtn ls unknown" and "mtn add",
+          and any calls to "regex.search" in Lua hooks.
+
         Other
 
 
============================================================
--- /dev/null	
+++ contrib/basicio.vim	ff652790f22fb5e3421c0b70b5c45d6c8d470d3b
@@ -0,0 +1,13 @@
+" Syntax highlighting for monotone basic_io format 
+" used by 'read-permissions', and 'write-permissions'
+"
+" Set up keywords and patterns we want to highlight
+syn match basicIOSymbol /[a-z_]*/
+syn region basicIOString start=+"+  skip=+\\\\\|\\"+  end=+"+
+syn match basicIOHexID /\[[a-fA-F0-9]*\]/
+
+" Set up sane default highlighting links, such as basicIOString->String
+hi def link basicIOSymbol	Keyword
+hi def link basicIOString	String
+hi def link basicIOHexID	Identifier
+
============================================================
--- /dev/null	
+++ contrib/colortone.pl	4de0235589831da1b9daeeba18841074c240fe78
@@ -0,0 +1,89 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+
+# colortone.pl - colors monotone output such as status, log and diff
+#
+# Reads input from STDIN and adds ANSI escape codes before outputting
+# to STDOUT. Passing filenames on the command line is also supported.
+#
+# Windows systems need Win32::Console::ANSI installed to support showing
+# color within cmd.exe.
+#
+# Usage
+# mtn diff | colortone.pl
+# mtn diff > diff.txt && colortone.pl diff.txt
+#
+# Windows Usage
+# To make it easier to use, create a new file 'myname.bat' with the
+# following contents (keeping quotes).
+#
+# @"C:\Program Files\monotone\mtn.exe" %* | perl "C:\Full\Path\To\colortone.pl"
+#
+# This allows you to use 'myname' as a replacement for mtn and output will
+# be colored automatically. Only use it if your key passphrase is not
+# required: diff, status, and log are fine.
+#
+# The piping has to be done through perl manually due to
+# http://support.microsoft.com/kb/321788.
+#
+# Copyright 2011 Richard Hopkins
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+use Term::ANSIColor;
+
+if ( $^O eq 'MSWin32' ) {
+    require Win32::Console::ANSI;
+    import  Win32::Console::ANSI;
+}
+
+# pattern => attributes
+#
+# pattern should contain a grouping as only the group will be colored.
+#
+# attributes is a single string containing any attributes supported by
+# Term::ANSIColor separated with a space.
+# eg. 'red on_white bold'
+my %patterns = (
+    q/(^#.*)/             => 'yellow',          # diff header
+    q/(^@@.*)/            => 'magenta',         # diff encloser
+    q/(^\+.*)/            => 'green',           # diff added
+    q/(^\|\s+\+.*)/       => 'green',           # diff added (with graph)
+    q/(^-.*)/             => 'red',             # diff removed
+    q/(^\|\s+-.*)/        => 'red',             # diff removed (with graph)
+    q/([a-f0-9]{40})/     => 'magenta bold',    # revision or file id
+    q/(^\| +\w+:)/        => 'white bold',      # log header (with graph)
+    q/(^\w+:)/            => 'white bold',      # status header
+    q/(^\*\*\*.+\*\*\*$)/ => 'yellow bold',     # status warning
+    q/(  added)/          => 'green',           # status added
+    q/(  patched)/        => 'cyan bold',       # status patched
+    q/(  dropped)/        => 'red',             # status dropped
+    q/(  renamed)/        => 'blue bold',       # status renamed
+);
+
+my $reset = color('reset');
+
+while (<>) {
+
+    # colorize any matching patterns in the current line.
+    foreach my $pattern ( keys %patterns ) {
+        my $color = color( $patterns{$pattern} );
+        $_ =~ s/$pattern/$color$1$reset/;
+    }
+
+    print colored $_;
+}
+
+exit(0);
============================================================
--- doc/monotone.texi	b93a39c40870fce709e383709d45003fb638bc0f
+++ doc/monotone.texi	e0b88a30f08867f9e0f593e5004789ca17753a94
@@ -2935,6 +2935,14 @@ @heading Composite selectors
 example, @code{difference(a:graydon;b:net.venge.monotone)} would return all
 revisions which have an @code{author} cert beginning with @code{graydon} which
 are not in the branch @code{net.venge.monotone}.
address@hidden not(A)
+Set complement; this returns all revisions not selected by A. For example,
address@hidden(c:testresult)} would return all revisions which do not have any
address@hidden certs. Conceptually @code{not(A)} is equivalent to
address@hidden(*, A)}, where @code{*} selects all revisions. The previous
+example to return all revisions which have an @code{author} cert beginning
+with @code{graydon} and are not in the branch @code{net.venge.monotone},
+can be written as @code{a:graydon/not(b:net.venge.monotone)}.
 @item lca(A;B)
 Least common ancestors; this is identical to
 @code{max((ancestors(A)|A)/(ancestors(B)|B))},
@@ -4799,7 +4807,9 @@ @subsection Global Options
 
 @item --xargs <arg>
 @itemx -@@ <arg>
-Insert command line arguments taken from the given file.
+Insert command line arguments taken from the given file. A '-'
+can be used to read the arguments from standard input.
+e.g. @code{--xargs=-}
 @end ftable
 
 @node Common Options,  , Global Options, Global and Common Options
@@ -12467,7 +12477,7 @@ @section Additional Lua Functions
 @item guess_terminal_width()
 
 Returns the size of the terminal window as number or a sane default
-(80) if the information cannot be retrieved.
+(72) if the information cannot be retrieved.
 
 @item include(@var{scriptfile})
 
============================================================
--- doc/pcrepattern.texi	10041ae21b3ce5f6971aca811ce57abc0827da8b
+++ doc/pcrepattern.texi	43ef52850c1fd113b8a21d63634bafe61b3aec45
@@ -2209,7 +2209,7 @@ @subsubheading Recursive Patterns
 @verbatim
          \( ( ( (?>[^()]+) | (?R) )* ) \)
             ^                        ^
address@hidden example
address@hidden verbatim
 
 @noindent
 the string they capture is @samp{ab(cd)ef}, the contents of the top
============================================================
--- extra/mtn-hooks/monotone-buildbot.lua	41d82aee6613c5d1775fd8ebf97ffd0c29ea807c
+++ extra/mtn-hooks/monotone-buildbot.lua	d1439935004ff6fb523dfa6b2c5fd5c8641339ab
@@ -10,6 +10,8 @@
 --     - initial version
 -- 0.2 (2011-03-11) Richard Levitte <address@hidden>
 --     - updated to have things more protected
+-- 0.3 (2012-04-10) Markus Wanner <address@hidden>
+--     - adapt to buildbot 0.8.3 and newer
 --
 -- License: GPL
 --
@@ -58,17 +60,21 @@ do
 	    end
 	 end
 
+    -- Note: for buildbot versions before 0.8.3, you need to give a
+    -- 'username' argument instead of 'auth' and 'who'.
 	 print("monotone-buildbot-notification: Running script:",
 	       buildbot_bin, "sendchange",
 	       "--master", buildbot_master,
-	       "--username", "'"..author.."'",
+	       "--auth", "change:changepw",
+	       "--who", "'"..author.."'",
 	       "--revision", rev_id,
 	       "--comments", "'"..changelog.."'",
 	       "--branch", branch,
 	       touched_files)
 	 execute(buildbot_bin, "sendchange",
 		 "--master", buildbot_master,
-		 "--username", author,
+		 "--auth", "change:changepw",
+		 "--who", "'"..author.."'",
 		 "--revision", rev_id,
 		 "--comments", changelog,
 		 "--branch", branch,
============================================================
--- src/cmd.cc	47891700f02feb1a6278c175fc56f5253c91ea49
+++ src/cmd.cc	94f7a433246032017e7c9a61645903feef68128e
@@ -974,7 +974,7 @@ CMD_NO_WORKSPACE(manpage, "manpage", "",
     F("could not execute man page formatter command '%s': %s")
       % cmd % strerror(errno));
 
-  fprintf(fp, ss.str().c_str());
+  fputs(ss.str().c_str(), fp);
   pclose(fp);
 }
 
============================================================
--- src/cmd_diff_log.cc	b24dffb0470d057fa1e91ccc5a81627b40252e78
+++ src/cmd_diff_log.cc	55dcbe5e40b8e706559f8b76a83b7fb81caecde1
@@ -369,6 +369,9 @@ prepare_diff(app_state & app,
 
       old_from_db = true;
       new_from_db = true;
+
+      header << "# old_revision [" << r_old_id << "]\n";
+      header << "# new_revision [" << r_new_id << "]\n";
     }
   else
     {
============================================================
--- src/cmd_ws_commit.cc	aa290a0418e1944d17768dd0d07fe6c3f348f2cf
+++ src/cmd_ws_commit.cc	431aff612ada586c56b63247423ae72df1650b88
@@ -670,6 +670,8 @@ CMD(disapprove, "disapprove", "", CMD_RE
   unsigned int old_head_size = heads.size();
 
   edge_entry const & old_edge (*rev.edges.begin());
+  E(!null_id(edge_old_revision(old_edge)), origin::user,
+    F("cannot disapprove root revision"));
   db.get_revision_manifest(edge_old_revision(old_edge),
                                rev_inverse.new_manifest);
   {
============================================================
--- src/database.cc	4c259f963c440fc95564dfec99b2f832f0bad643
+++ src/database.cc	87efeeff2d3263ba98af684a4022f1897434ed2d
@@ -3425,9 +3425,8 @@ database::encrypt_rsa(key_id const & pub
   rsa_pub_key pub;
   get_key(pub_id, pub);
 
-  SecureVector<Botan::byte> pub_block;
-  pub_block.set(reinterpret_cast<Botan::byte const *>(pub().data()),
-                pub().size());
+  SecureVector<Botan::byte> pub_block
+    (reinterpret_cast<Botan::byte const *>(pub().data()), pub().size());
 
   shared_ptr<X509_PublicKey> x509_key(Botan::X509::load_key(pub_block));
   shared_ptr<RSA_PublicKey> pub_key
@@ -3471,14 +3470,13 @@ database::check_signature(key_id const &
   else
     {
       rsa_pub_key pub;
-      SecureVector<Botan::byte> pub_block;
 
       if (!public_key_exists(id))
         return cert_unknown;
 
       get_key(id, pub);
-      pub_block.set(reinterpret_cast<Botan::byte const *>(pub().data()),
-                    pub().size());
+      SecureVector<Botan::byte> pub_block
+        (reinterpret_cast<Botan::byte const *>(pub().data()), pub().size());
 
       L(FL("building verifier for %d-byte pub key") % pub_block.size());
       shared_ptr<X509_PublicKey> x509_key(Botan::X509::load_key(pub_block));
============================================================
--- src/gzip.cc	e7c19bee910e3d421fd073933810ec52092b1d9b
+++ src/gzip.cc	9da41f6820cdf39707b22c716e3682e0fa0fd745
@@ -110,7 +110,7 @@ Gzip_Compression::Gzip_Compression(u32bi
    if(deflateInit2(&(zlib->stream), level, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY) != Z_OK)
       {
       delete zlib; zlib = 0;
-      throw Exception("Gzip_Compression: Memory allocation error");
+      throw Memory_Exhaustion();
       }
    }
 
@@ -137,7 +137,7 @@ void Gzip_Compression::start_msg()
 /*************************************************
 * Compress Input with Gzip                       *
 *************************************************/
-void Gzip_Compression::write(const byte input[], u32bit length)
+void Gzip_Compression::write(const byte input[], filter_length_t length)
    {
 
    count += length;
@@ -152,7 +152,7 @@ void Gzip_Compression::write(const byte 
       zlib->stream.avail_out = buffer.size();
       int rc = deflate(&(zlib->stream), Z_NO_FLUSH);
       if (rc != Z_OK && rc != Z_STREAM_END)
-         throw Exception("Internal error in Gzip_Compression deflate.");
+         throw Invalid_State("Internal error in Gzip_Compression deflate.");
       send(buffer.begin(), buffer.size() - zlib->stream.avail_out);
       }
    }
@@ -172,7 +172,7 @@ void Gzip_Compression::end_msg()
       zlib->stream.avail_out = buffer.size();
       rc = deflate(&(zlib->stream), Z_FINISH);
       if (rc != Z_OK && rc != Z_STREAM_END)
-         throw Exception("Internal error in Gzip_Compression finishing deflate.");
+         throw Invalid_State("Internal error in Gzip_Compression finishing deflate.");
       send(buffer.begin(), buffer.size() - zlib->stream.avail_out);
       }
 
@@ -228,7 +228,7 @@ Gzip_Decompression::Gzip_Decompression()
    no_writes(true), pipe(new Hash_Filter("CRC32")), footer(0)
    {
    if (DEFAULT_BUFFERSIZE < sizeof(GZIP::GZIP_HEADER))
-      throw Exception("DEFAULT_BUFFERSIZE is too small");
+      throw Decoding_Error("DEFAULT_BUFFERSIZE is too small");
 
    zlib = new Zlib_Stream;
 
@@ -237,7 +237,7 @@ Gzip_Decompression::Gzip_Decompression()
    if(inflateInit2(&(zlib->stream), -15) != Z_OK)
       {
       delete zlib; zlib = 0;
-      throw Exception("Gzip_Decompression: Memory allocation error");
+      throw Memory_Exhaustion();
       }
    }
 
@@ -256,7 +256,7 @@ void Gzip_Decompression::start_msg()
 void Gzip_Decompression::start_msg()
    {
    if (!no_writes)
-      throw Exception("Gzip_Decompression: start_msg after already writing");
+      throw Decoding_Error("Gzip_Decompression: start_msg after already writing");
 
    pipe.start_msg();
    datacount = 0;
@@ -267,7 +267,7 @@ void Gzip_Decompression::start_msg()
 /*************************************************
 * Decompress Input with Gzip                     *
 *************************************************/
-void Gzip_Decompression::write(const byte input[], u32bit length)
+void Gzip_Decompression::write(const byte input[], filter_length_t length)
    {
    if(length) no_writes = false;
 
@@ -277,15 +277,16 @@ void Gzip_Decompression::write(const byt
          u32bit eat_len = eat_footer(input, length);
          input += eat_len;
          length -= eat_len;
-         if (length == 0)
-            return;
       }
 
+   if (length == 0)
+     return;
+
    // Check the gzip header
    if (pos < sizeof(GZIP::GZIP_HEADER))
       {
-      u32bit len = std::min((u32bit)sizeof(GZIP::GZIP_HEADER)-pos, length);
-      u32bit cmplen = len;
+      filter_length_t len = std::min((filter_length_t)sizeof(GZIP::GZIP_HEADER)-pos, length);
+      filter_length_t cmplen = len;
       // The last byte is the OS flag - we don't care about that
       if (pos + len - 1 >= GZIP::HEADER_POS_OS)
          cmplen--;
@@ -317,8 +318,8 @@ void Gzip_Decompression::write(const byt
          if(rc == Z_NEED_DICT)
             throw Decoding_Error("Gzip_Decompression: Need preset dictionary");
          if(rc == Z_MEM_ERROR)
-            throw Exception("Gzip_Decompression: Memory allocation error");
-         throw Exception("Gzip_Decompression: Unknown decompress error");
+            throw Memory_Exhaustion();
+         throw Decoding_Error("Gzip_Decompression: Unknown decompress error");
          }
       send(buffer.begin(), buffer.size() - zlib->stream.avail_out);
       pipe.write(buffer.begin(), buffer.size() - zlib->stream.avail_out);
@@ -346,8 +347,14 @@ u32bit Gzip_Decompression::eat_footer(co
       if (footer.size() >= GZIP::FOOTER_LENGTH)
          throw Decoding_Error("Gzip_Decompression: Data integrity error in footer");
 
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,9,11)
+      size_t eat_len = std::min(GZIP::FOOTER_LENGTH-footer.size(),
+                                static_cast<size_t>(length));
+      footer += std::make_pair(input, eat_len);
+#else
       u32bit eat_len = std::min(GZIP::FOOTER_LENGTH-footer.size(), length);
       footer.append(input, eat_len);
+#endif
 
       if (footer.size() == GZIP::FOOTER_LENGTH)
          {
@@ -364,7 +371,7 @@ void Gzip_Decompression::check_footer()
 void Gzip_Decompression::check_footer()
    {
    if (footer.size() != GZIP::FOOTER_LENGTH)
-      throw Exception("Gzip_Decompression: Error finalizing decompression");
+      throw Decoding_Error("Gzip_Decompression: Error finalizing decompression");
 
    pipe.end_msg();
 
@@ -377,7 +384,12 @@ void Gzip_Decompression::check_footer()
   for (int i = 0; i < 4; i++)
      buf[3-i] = tmpbuf[i];
 
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,9,11)
+  tmpbuf.resize(4);
+  tmpbuf.copy(footer.begin(), 4);
+#else
   tmpbuf.set(footer.begin(), 4);
+#endif
   if (buf != tmpbuf)
       throw Decoding_Error("Gzip_Decompression: Data integrity error - CRC32 error");
 
@@ -400,7 +412,7 @@ void Gzip_Decompression::end_msg()
    // read, clear() will reset no_writes
    if(no_writes) return;
 
-   throw Exception("Gzip_Decompression: didn't find footer");
+   throw Decoding_Error("Gzip_Decompression: didn't find footer");
 
    }
 
@@ -412,7 +424,11 @@ void Gzip_Decompression::clear()
    no_writes = true;
    inflateReset(&(zlib->stream));
 
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,9,11)
+   footer.clear();
+#else
    footer.destroy();
+#endif
    pos = 0;
    datacount = 0;
    }
============================================================
--- src/gzip.hh	649dfc0b250954f39c0f73870f8bec3f32f7fa43
+++ src/gzip.hh	17093f66e365b3730a49ef1910295f622972c36e
@@ -7,11 +7,25 @@
 #ifndef BOTAN_EXT_GZIP_H__
 #define BOTAN_EXT_GZIP_H__
 
+#include <botan/version.h>
 #include <botan/filter.h>
 #include <botan/pipe.h>
 
 namespace Botan {
 
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,7,12) && \
+  BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,9,4)
+// Botan versions between 1.7.12 and 1.9.3 (including) keep their
+// Memory_Exception private. Give this gzip implementation something
+// compatible to work with.
+class Memory_Exhaustion : public Exception
+{
+public:
+  Memory_Exhaustion() :
+    Exception("Ran out of memory, allocation failed") {}
+};
+#endif
+
 namespace GZIP {
 
    /* A basic header - we only need to set the IDs and compression method */
@@ -30,13 +44,19 @@ namespace GZIP {
 
 }
 
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,9,11)
+typedef size_t filter_length_t;
+#else
+typedef u32bit filter_length_t;
+#endif
+
 /*************************************************
 * Gzip Compression Filter                        *
 *************************************************/
 class Gzip_Compression : public Filter
    {
    public:
-      void write(const byte input[], u32bit length);
+      void write(const byte input[], filter_length_t length);
       void start_msg();
       void end_msg();
       std::string name() const { return "Gzip_Compression"; }
@@ -60,7 +80,7 @@ class Gzip_Decompression : public Filter
 class Gzip_Decompression : public Filter
    {
    public:
-      void write(const byte input[], u32bit length);
+      void write(const byte input[], filter_length_t length);
       void start_msg();
       void end_msg();
       std::string name() const { return "Gzip_Decompression"; }
============================================================
--- src/key_packet.cc	d1306df89dd684badac02c03744cd446381c07d3
+++ src/key_packet.cc	c97262d161b23c9640972188979669b3e95afe7b
@@ -106,8 +106,8 @@ namespace
     void validate_public_key_data(string const & name, string const & keydata) const
     {
       string decoded = decode_base64_as<string>(keydata, origin::user);
-      Botan::SecureVector<Botan::byte> key_block;
-      key_block.set(reinterpret_cast<Botan::byte const *>(decoded.c_str()), decoded.size());
+      Botan::SecureVector<Botan::byte> key_block
+        (reinterpret_cast<Botan::byte const *>(decoded.c_str()), decoded.size());
       try
         {
           Botan::X509::load_key(key_block);
============================================================
--- src/key_store.cc	64c4c4bed1fadc26b51207b9f61343f9dd7d3c6e
+++ src/key_store.cc	b7859345f7c665914d16357409bdff24a48b7996
@@ -572,13 +572,21 @@ key_store_state::decrypt_private_key(key
   try // with empty passphrase
     {
       Botan::DataSource_Memory ds(kp.priv());
-#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,7,7)
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,9,11)
+      pkcs8_key.reset(Botan::PKCS8::load_key(ds, lazy_rng::get(), Dummy_UI()));
+#elif BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,7,7)
       pkcs8_key.reset(Botan::PKCS8::load_key(ds, lazy_rng::get(), ""));
 #else
       pkcs8_key.reset(Botan::PKCS8::load_key(ds, ""));
 #endif
     }
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,9,11)
+  catch (Passphrase_Required & e)
+#elif BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,9,4)
+  catch (Botan::Invalid_Argument & e)
+#else
   catch (Botan::Exception & e)
+#endif
     {
       L(FL("failed to load key with no passphrase: %s") % e.what());
 
@@ -605,13 +613,18 @@ key_store_state::decrypt_private_key(key
           {
             Botan::DataSource_Memory ds(kp.priv());
 #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,7,7)
-            pkcs8_key.reset(Botan::PKCS8::load_key(ds, lazy_rng::get(), phrase()));
+            pkcs8_key.reset(Botan::PKCS8::load_key(ds, lazy_rng::get(),
+                                                   phrase()));
 #else
             pkcs8_key.reset(Botan::PKCS8::load_key(ds, phrase()));
 #endif
             break;
           }
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,9,4)
+        catch (Botan::Invalid_Argument)
+#else
         catch (Botan::Exception & e)
+#endif
           {
             cycles++;
             L(FL("decrypt_private_key: failure %d to load encrypted key: %s")
@@ -822,10 +835,14 @@ key_store::decrypt_rsa(key_id const & id
       plaintext = string(reinterpret_cast<char const*>(plain.begin()),
                          plain.size());
     }
-  catch (Botan::Exception & ex)
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,9,4)
+  catch (std::exception & e)
+#else
+  catch (Botan::Exception & e)
+#endif
     {
       E(false, ciphertext.made_from,
-        F("Botan error decrypting data: '%s'") % ex.what());
+        F("Botan error decrypting data: '%s'") % e.what());
     }
 }
 
@@ -856,9 +873,9 @@ key_store::make_signature(database & db,
     {
       if (agent.connected()) {
         //grab the monotone public key as an RSA_PublicKey
-        SecureVector<Botan::byte> pub_block;
-        pub_block.set(reinterpret_cast<Botan::byte const *>(key.pub().data()),
-                      key.pub().size());
+        SecureVector<Botan::byte> pub_block
+          (reinterpret_cast<Botan::byte const *>(key.pub().data()),
+           key.pub().size());
         L(FL("make_signature: building %d-byte pub key") % pub_block.size());
         shared_ptr<X509_PublicKey> x509_key =
           shared_ptr<X509_PublicKey>(Botan::X509::load_key(pub_block));
@@ -1031,8 +1048,14 @@ key_store_state::migrate_old_key_pair
   for (;;)
     try
       {
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,9,11)
+        arc4_key.resize(phrase().size());
+        arc4_key.copy(reinterpret_cast<Botan::byte const *>(phrase().data()),
+                      phrase().size());
+#else
         arc4_key.set(reinterpret_cast<Botan::byte const *>(phrase().data()),
                      phrase().size());
+#endif
 
         Pipe arc4_decryptor(get_cipher("ARC4", arc4_key, Botan::DECRYPTION));
 
@@ -1051,7 +1074,11 @@ key_store_state::migrate_old_key_pair
 #endif
         break;
       }
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,9,4)
+    catch (Botan::Invalid_Argument & e)
+#else
     catch (Botan::Exception & e)
+#endif
       {
         L(FL("migrate_old_key_pair: failure %d to load old private key: %s")
           % cycles % e.what());
============================================================
--- src/monotone.cc	a25ecdd170a601db798b63a60add7681609a34c4
+++ src/monotone.cc	764bc9ca406b41d21efd552a0d810bc2849e0588
@@ -156,27 +156,53 @@ cpp_main(int argc, char ** argv)
       E(linked_botan_version != BOTAN_VERSION_CODE_FOR(1,7,14), origin::system,
         F("monotone does not support Botan 1.7.14"));
 
-#if BOTAN_VERSION_CODE <= BOTAN_VERSION_CODE_FOR(1,7,6)
+      // In Botan 1.9.9, the DataSink_Stream cannot be instantiated per
+      // se. As 1.10.1 is already out, let's simply disable support for
+      // that specific (testing) version of botan.
+      E(linked_botan_version != BOTAN_VERSION_CODE_FOR(1,9,9), origin::system,
+        F("monotone does not support Botan 1.9.9"));
+
+#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,7,7)
+      // motonote binary compiled against botan younger than 1.7.7
       E(linked_botan_version >= BOTAN_VERSION_CODE_FOR(1,6,3), origin::system,
         F("this monotone binary requires Botan 1.6.3 or newer"));
-      E(linked_botan_version <= BOTAN_VERSION_CODE_FOR(1,7,6), origin::system,
-        F("this monotone binary does not work with Botan newer than 1.7.6"));
-#elif BOTAN_VERSION_CODE <= BOTAN_VERSION_CODE_FOR(1,7,22)
-      E(linked_botan_version > BOTAN_VERSION_CODE_FOR(1,7,6), origin::system,
+      E(linked_botan_version < BOTAN_VERSION_CODE_FOR(1,7,7), origin::system,
+        F("this monotone binary does not work with Botan 1.7.7 or newer"));
+
+#elif BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,7,22)
+      // motonote binary compiled against botan 1.7.7 - 1.7.21
+      E(linked_botan_version >= BOTAN_VERSION_CODE_FOR(1,7,7), origin::system,
         F("this monotone binary requires Botan 1.7.7 or newer"));
-      // While compiling against 1.7.22 or newer is recommended, because
-      // it enables new features of Botan, the monotone binary compiled
-      // against Botan 1.7.21 and before should still work with newer Botan
-      // versions, including all of the stable branch 1.8.x.
-      E(linked_botan_version < BOTAN_VERSION_CODE_FOR(1,9,0), origin::system,
-        F("this monotone binary does not work with Botan 1.9.x"));
-#else
-      E(linked_botan_version > BOTAN_VERSION_CODE_FOR(1,7,22), origin::system,
+      // While compiling against 1.7.22 or newer is recommended, because it
+      // enables new features of Botan, the monotone binary compiled against
+      // Botan 1.7.21 and before should still work with newer Botan version,
+      // including all of the stable branch 1.8.x, up to and including
+      // 1.9.3.
+      E(linked_botan_version < BOTAN_VERSION_CODE_FOR(1,9,4), origin::system,
+        F("this monotone binary does not work with Botan 1.9.4 or newer"));
+
+#elif BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,9,4)
+      // motonote binary compiled against botan 1.7.22 - 1.9.3
+      E(linked_botan_version >= BOTAN_VERSION_CODE_FOR(1,7,22), origin::system,
         F("this monotone binary requires Botan 1.7.22 or newer"));
-      E(linked_botan_version < BOTAN_VERSION_CODE_FOR(1,9,0), origin::system,
-        F("this monotone binary does not work with Botan 1.9.x"));
+      E(linked_botan_version < BOTAN_VERSION_CODE_FOR(1,9,4), origin::system,
+        F("this monotone binary does not work with Botan 1.9.4 or newer"));
+
+#elif BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,9,11)
+      // motonote binary compiled against botan 1.9.4 - 1.9.10
+#pragma message ( "The resulting monotone binary won't be able to run with any stable release of botan." )
+      E(linked_botan_version >= BOTAN_VERSION_CODE_FOR(1,9,4), origin::system,
+        F("this monotone binary requires Botan 1.9.4 or newer"));
+      E(linked_botan_version < BOTAN_VERSION_CODE_FOR(1,9,11), origin::system,
+        F("this monotone binary does not work with Botan 1.9.11 or newer"));
+
+#else
+      // motonote binary compiled against botan 1.9.11 and newer
+      E(linked_botan_version >= BOTAN_VERSION_CODE_FOR(1,9,11), origin::system,
+        F("this monotone binary requires Botan 1.9.11 or newer"));
 #endif
 
+
       app_state app;
       try
         {
============================================================
--- src/netxx/serverbase.cxx	7a9b465ce4b0b02cb8ff126acf86d3896b4eb456
+++ src/netxx/serverbase.cxx	156f2090341d2a36bdb718e7c69df58f9251983e
@@ -44,6 +44,8 @@
 #include "probeinfo.h"
 #include "socket.h"
 
+#include <cerrno>
+
 // standard includes
 #include <map>
 #include <vector>
@@ -167,13 +169,26 @@ void Netxx::ServerBase::bind_to(const Ad
 		if (saun->sun_path[0] == '/') {
 		    files_.push_back(saun->sun_path);
 		} else {
-		    char buffer[MAXPATHLEN];
+		    // BIG FAT WARNING: THIS CODE HAS NOT BEEN TESTED!
+		    // The original code is non-dynamic, depending on
+		    // the value of MAXPATHLEN.  Since that macro isn't
+		    // guaranteed to exist, a more dynamic use if getcwd()
+		    // was written.  However, since monotone doesn't use
+		    // AF_LOCAL sockets, this code will not be reached.
+		    int e = ERANGE;
+		    int n = 4096;
 
-		    if (getcwd(buffer, sizeof(buffer))) {
- 			std::string fullpath = buffer; fullpath += '/'; fullpath += saun->sun_path;
-			files_.push_back(fullpath);
-		    } else {
-			files_.push_back(saun->sun_path);
+		    while (e == ERANGE) {
+			char buffer[n];
+			e = 0;
+			n += 4096;
+
+			if (getcwd(buffer, n)) {
+			    std::string fullpath = buffer; fullpath += '/'; fullpath += saun->sun_path;
+			    files_.push_back(fullpath);
+			} else if ((e = errno) != ERANGE) {
+			    files_.push_back(saun->sun_path);
+			}
 		    }
 		}
 	    }
============================================================
--- src/packet.cc	f61360ed2524fdf53411bd24d022a2a3c9e6e9c7
+++ src/packet.cc	571ff6eae1d269a146da74f2730b70376957d3bb
@@ -156,8 +156,8 @@ namespace
     void validate_public_key_data(string const & name, string const & keydata) const
     {
       string decoded = decode_base64_as<string>(keydata, origin::user);
-      Botan::SecureVector<Botan::byte> key_block;
-      key_block.set(reinterpret_cast<Botan::byte const *>(decoded.c_str()), decoded.size());
+      Botan::SecureVector<Botan::byte> key_block
+        (reinterpret_cast<Botan::byte const *>(decoded.c_str()), decoded.size());
       try
         {
           Botan::X509::load_key(key_block);
@@ -175,7 +175,9 @@ namespace
       Botan::DataSource_Memory ds(decoded);
       try
         {
-#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,7,7)
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,9,11)
+          Botan::PKCS8::load_key(ds, lazy_rng::get(), Dummy_UI());
+#elif BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,7,7)
           Botan::PKCS8::load_key(ds, lazy_rng::get(), string());
 #else
           Botan::PKCS8::load_key(ds, string());
@@ -189,7 +191,11 @@ namespace
         }
       // since we do not want to prompt for a password to decode it finally,
       // we ignore all other exceptions
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,9,11)
+      catch (Passphrase_Required) {}
+#else
       catch (Botan::Invalid_Argument) {}
+#endif
     }
     void validate_certname(string const & cn) const
     {
@@ -460,8 +466,16 @@ read_packets(istream & in, packet_consum
   return count;
 }
 
+// Dummy User_Interface implementation for Botan
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,9,11)
+std::string
+Dummy_UI::get_passphrase(const std::string &, const std::string &,
+                         Botan::User_Interface::UI_Result&) const
+{
+  throw Passphrase_Required("Passphrase required");
+}
+#endif
 
-
 // Local Variables:
 // mode: C++
 // fill-column: 76
============================================================
--- src/packet.hh	0a224e6e92f244e2c3e9a5cdb935eb8613d7e85b
+++ src/packet.hh	9c43d30145f0292d6ceda5e717e366fdead5a4d6
@@ -10,6 +10,10 @@
 #ifndef __PACKET_HH__
 #define __PACKET_HH__
 
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,9,11)
+#include <botan/ui.h>
+#endif
+
 #include "vocab.hh"
 
 struct cert;
@@ -84,8 +88,23 @@ size_t read_packets(std::istream & in, p
 
 size_t read_packets(std::istream & in, packet_consumer & cons);
 
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,9,11)
+// A helper class implementing Botan::User_Interface - which doesn't really
+// interface with the user, but provides the necessary plumbing for Botan.
+//
+// See Botan commit 2d09d7d0cd4bd0e7155d001dd65a4f29103b158c
+typedef std::runtime_error Passphrase_Required;
+
+class Dummy_UI : public Botan::User_Interface
+{
+public:
+  virtual std::string get_passphrase(const std::string &, const std::string &,
+                                     Botan::User_Interface::UI_Result &) const;
+};
 #endif
 
+#endif
+
 // Local Variables:
 // mode: C++
 // fill-column: 76
============================================================
--- src/pcrewrap.cc	7f5bd4e7d8d9e02f2b0271fa9a0f64dcbce2467d
+++ src/pcrewrap.cc	59b11bb0076d4724c95c34840409be6d8357a68e
@@ -11,6 +11,7 @@
 #include "pcrewrap.hh"
 #include "sanity.hh"
 #include <cstring>
+#include <map>
 #include <vector>
 
 // This dirty trick is necessary to prevent the 'pcre' typedef defined by
@@ -19,6 +20,9 @@
 #include "pcre.h"
 #undef pcre
 
+using std::make_pair;
+using std::map;
+using std::pair;
 using std::string;
 using std::vector;
 
@@ -69,11 +73,63 @@ namespace pcre
 
 namespace pcre
 {
+  typedef map<char const *,
+              pair<struct real_pcre const *, struct pcre_extra const *> >
+              regex_cache;
+
+  class regex_cache_manager
+  {
+public:
+    regex_cache::const_iterator find(char const * pattern)
+      {
+        return cache.find(pattern);
+      }
+
+    void store(char const * pattern,
+               pair<struct real_pcre const *, struct pcre_extra const *>
+               data)
+      {
+        cache[pattern] = data;
+      }
+
+    regex_cache::const_iterator end()
+      {
+        return cache.end();
+      }
+
+    ~regex_cache_manager()
+      {
+        for (regex_cache::iterator iter = cache.begin();
+             iter != cache.end();
+             ++iter)
+          {
+            if (iter->second.first)
+              pcre_free(const_cast<pcre_t *>(iter->second.first));
+
+            if (iter->second.second)
+              pcre_free(const_cast<pcre_extra *>(iter->second.second));
+          }
+      }
+private:
+    regex_cache cache;
+  };
+
+  regex_cache_manager compiled;
+
   void regex::init(char const * pattern, flags options)
   {
     int errcode;
     int erroff;
     char const * err;
+    // use the cached data if we have it
+    regex_cache::const_iterator iter = compiled.find(pattern);
+    if (iter != compiled.end())
+      {
+        basedat = iter->second.first;
+        extradat = iter->second.second;
+        return;
+      }
+    // not in cache - compile them then store in cache
     basedat = pcre_compile2(pattern, flags_to_internal(options),
                             &errcode, &err, &erroff, 0);
     if (!basedat)
@@ -97,6 +153,8 @@ namespace pcre
     ed->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
     ed->match_limit_recursion = 2000;
     extradat = ed;
+    // store in cache
+    compiled.store(pattern, make_pair(basedat, extradat));
   }
 
   regex::regex(char const * pattern, origin::type whence, flags options)
@@ -113,10 +171,6 @@ namespace pcre
 
   regex::~regex()
   {
-    if (basedat)
-      pcre_free(const_cast<pcre_t *>(basedat));
-    if (extradat)
-      pcre_free(const_cast<pcre_extra *>(extradat));
   }
 
   bool
============================================================
--- src/selectors.cc	3efba0ce3139290b4088cea0d6e82a912565471e
+++ src/selectors.cc	588c6b5fd3ded29f5f778a78e707352564acbc02
@@ -523,6 +523,19 @@ public:
                        inserter(ret, ret.end()));
         return ret;
       }
+    else if (name == "not")
+      {
+        diagnose_wrong_arg_count("not", 1, args.size());
+        set<revision_id> lhs;
+        set<revision_id> rhs = args[0]->complete(project);
+
+        project.db.get_revision_ids(lhs);
+        set<revision_id> ret;
+        set_difference(lhs.begin(), lhs.end(),
+                       rhs.begin(), rhs.end(),
+                       inserter(ret, ret.end()));
+        return ret;
+      }
     else if (name == "lca")
       {
         diagnose_wrong_arg_count("lca", 2, args.size());
============================================================
--- src/sha1.cc	5e1aa972d7c7d66e06320b039989652b830dcd75
+++ src/sha1.cc	42e48b22fd88b25e0d38d4f91e1f13f8a83c7120
@@ -50,9 +50,12 @@ CMD_HIDDEN(benchmark_sha1, "benchmark_sh
   Botan::Default_Benchmark_Timer timer;
   std::map<std::string, double> results =
     Botan::algorithm_benchmark("SHA-1",  milliseconds, timer, rng, af);
+#elif BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,9,11)
+  std::map<std::string, double> results =
+    Botan::algorithm_benchmark("SHA-1",  milliseconds, rng, af);
 #else
   std::map<std::string, double> results =
-    Botan::algorithm_benchmark("SHA-1",  milliseconds, rng, af);
+    Botan::algorithm_benchmark("SHA-1",  af, rng, milliseconds, 16);
 #endif
 
   for(std::map<std::string, double>::const_iterator i = results.begin();
============================================================
--- src/ssh_agent.cc	6d188e7012a0b82f782563b09bbd7adf3f70cf75
+++ src/ssh_agent.cc	4a0dcab873559e934e41c5f220b5434d35600d9b
@@ -385,9 +385,9 @@ ssh_agent::has_key(const keypair & key)
 ssh_agent::has_key(const keypair & key)
 {
   //grab the monotone public key as an RSA_PublicKey
-  SecureVector<Botan::byte> pub_block;
-  pub_block.set(reinterpret_cast<Botan::byte const *>((key.pub)().data()),
-                (key.pub)().size());
+  SecureVector<Botan::byte> pub_block
+    (reinterpret_cast<Botan::byte const *>((key.pub)().data()),
+     (key.pub)().size());
   L(FL("has_key: building %d-byte pub key") % pub_block.size());
   shared_ptr<X509_PublicKey> x509_key =
     shared_ptr<X509_PublicKey>(Botan::X509::load_key(pub_block));
============================================================
--- src/transforms.cc	cdfb6854ef4992faba21074145f3c8269b845b11
+++ src/transforms.cc	b99278ffe95c0081bf4986bc74d3699c37a52948
@@ -53,15 +53,16 @@ using Botan::Hash_Filter;
 // paradigm "must" be used. this program is intended for source code
 // control and I make no bones about it.
 
-NORETURN(static inline void error_in_transform(Botan::Exception & e));
+NORETURN(static inline void error_in_transform(std::exception & e));
 
 static inline void
-error_in_transform(Botan::Exception & e, origin::type caused_by)
+error_in_transform(std::exception & e, origin::type caused_by)
 {
   // these classes can all indicate data corruption
   if (typeid(e) == typeid(Botan::Encoding_Error)
       || typeid(e) == typeid(Botan::Decoding_Error)
       || typeid(e) == typeid(Botan::Stream_IO_Error)
+      || typeid(e) == typeid(Botan::Invalid_Argument)
       || typeid(e) == typeid(Botan::Integrity_Failure))
     {
       // clean up the what() string a little: throw away the
@@ -107,7 +108,7 @@ error_in_transform(Botan::Exception & e,
         pipe->process_msg(in);                                  \
         out = pipe->read_all_as_string(Pipe::LAST_MESSAGE);     \
       }                                                         \
-    catch (Botan::Exception & e)                                \
+    catch (std::exception & e)                                   \
       {                                                         \
         pipe.reset(new Pipe(new T(carg)));                      \
         error_in_transform(e, made_from);                       \
@@ -173,7 +174,7 @@ template<> string xform<Botan::Hex_Decod
             {
               throw Botan::Decoding_Error(string("invalid hex character '") + (char)c + "'");
             }
-          catch(Botan::Exception & e)
+          catch(std::exception & e)
             {
               error_in_transform(e, made_from);
             }
@@ -219,7 +220,7 @@ void pack(T const & in, base64< gzip<T> 
       tmp = pipe->read_all_as_string(Pipe::LAST_MESSAGE);
       out = base64< gzip<T> >(tmp, in.made_from);
     }
-  catch (Botan::Exception & e)
+  catch (std::exception & e)
     {
       pipe.reset(new Pipe(new Gzip_Compression,
                           new Base64_Encoder));
@@ -237,7 +238,7 @@ void unpack(base64< gzip<T> > const & in
       pipe->process_msg(in());
       out = T(pipe->read_all_as_string(Pipe::LAST_MESSAGE), in.made_from);
     }
-  catch (Botan::Exception & e)
+  catch (std::exception & e)
     {
       pipe.reset(new Pipe(new Base64_Decoder,
                           new Gzip_Decompression));
@@ -264,7 +265,7 @@ calculate_ident(data const & dat,
       p->process_msg(dat());
       ident = id(p->read_all_as_string(Pipe::LAST_MESSAGE), dat.made_from);
     }
-  catch (Botan::Exception & e)
+  catch (std::exception & e)
     {
       p.reset(new Pipe(new Hash_Filter("SHA-160")));
       error_in_transform(e, dat.made_from);
============================================================
--- src/win32/terminal.cc	036785c31b25174a945c09d04030552377394221
+++ src/win32/terminal.cc	8aa0b4610e4683fea74c0378e6d934d2829f2799
@@ -49,8 +49,7 @@ unsigned int terminal_width()
         }
     }
 
-  // default to 80 columns if the width query failed.
-  return 80;
+  return 0;
 }
 
 // Local Variables:
============================================================
--- src/work.hh	00e100f44763cad0019683c16c4a13d53a94d5e0
+++ src/work.hh	0ca2a0f0ab94c2421db119216af9373b81f38e61
@@ -18,7 +18,7 @@ class lua_hooks;
 class node_restriction;
 struct content_merge_adaptor;
 class lua_hooks;
-class i18n_format;
+struct i18n_format;
 struct options;
 class app_state;
 
============================================================
--- test/func/attr_mtn_execute/__driver__.lua	ac0c1f7ecf54690607e55d5aa43544c023e3700c
+++ test/func/attr_mtn_execute/__driver__.lua	b5bfcf8f4fdb98c59f95da35b93e7d97d08b99e7
@@ -30,7 +30,7 @@ copy("test.db", "test-clone.db")
 -- test clone with mtn:execute
 
 copy("test.db", "test-clone.db")
-testURI="file://" .. test.root .. "/test-clone.db?testbranch"
+test_uri="file://" .. url_encode_path(test.root .. "/test-clone.db") .. "?testbranch"
 
-check(nodb_mtn("clone", testURI, "clone"), 0, false, true)
+check(nodb_mtn("clone", test_uri, "clone"), 0, false, true)
 check(indir("clone", {"test", "-x","foo"}, 0, false, false))
============================================================
--- test/func/branch_leaves_sync_bug/__driver__.lua	6b227867aeb3692dba4e68efdfe5c59ff5c15919
+++ test/func/branch_leaves_sync_bug/__driver__.lua	943c3f2d7c3294e5da221d44911c08511058acb2
@@ -46,7 +46,9 @@ chdir(test.root)
 
 -- Create Beth's workspace via checkout, so 'update' works
 chdir(test.root)
-check(abe_mtn("sync", "file://" .. test.root .. "/beth.db?*"), 0, false, false)
+
+test_uri="file://" .. url_encode_path(test.root .. "/beth.db") .. "?*"
+check(abe_mtn("sync", test_uri), 0, false, false)
 check(beth_mtn("checkout", "--branch", "testbranch", "Beth"), 0, false, false)
 chdir("Beth")
 check(beth_mtn("genkey", "address@hidden"), 0, false, false, string.rep("address@hidden", 2))
@@ -64,7 +66,7 @@ rev_b = base_revision()
 rev_b = base_revision()
 
 -- Sync dbs
-check(abe_mtn("sync", "file://" .. test.root .. "/beth.db?*"), 0, false, false)
+check(abe_mtn("sync", test_uri), 0, false, false)
 
 -- Abe merges
 chdir("Abe")
@@ -80,7 +82,8 @@ rev_d = base_revision()
 rev_d = base_revision()
 
 -- Sync dbs (not clear if direction of sync matters)
-check(beth_mtn("sync", "file://" .. test.root .. "/abe.db?*"), 0, false, false)
+test_uri="file://" .. url_encode_path(test.root .. "/abe.db") .. "?*"
+check(beth_mtn("sync", test_uri), 0, false, false)
 
 -- bug; rev_d and rev_c are both heads according to branch_leaves table.
 check(beth_mtn("db", "check"), 0, false, false)
============================================================
--- test/func/clone_aborts_on_branch_pattern_in_uri/__driver__.lua	bf16d8dcec86e4ae012d1c6078082f9d13a9fd80
+++ test/func/clone_aborts_on_branch_pattern_in_uri/__driver__.lua	e75946886b2b0b4ee301016860238e6315c22a59
@@ -6,9 +6,9 @@ copy("test.db", "test-clone.db")
 commit("mybranch")
 
 copy("test.db", "test-clone.db")
-testURI="file://" .. test.root .. "/test-clone.db?mybranch*"
 
-check(nodb_mtn("clone", testURI), 1, false, true)
+test_uri="file://" .. url_encode_path(test.root .. "/test-clone.db") .. "?mybranch*"
+check(nodb_mtn("clone", test_uri), 1, false, true)
 check(qgrep("you must specify an unambiguous branch to clone", "stderr"))
 
 -- the branch option is invalid in non-URI mode
@@ -16,7 +16,7 @@ check(qgrep("the '--branch' option is on
 check(qgrep("the '--branch' option is only valid with an URI to clone", "stderr"))
 
 -- finally, this should succeed
-check(nodb_mtn("clone", testURI, "--branch=mybranch"), 0, false, false)
+check(nodb_mtn("clone", test_uri, "--branch=mybranch"), 0, false, false)
 check(exists("mybranch"))
 check(readfile("foo") == readfile("mybranch/foo"))
 
============================================================
--- test/func/clone_branch_no_dir/__driver__.lua	b490cd593cefd9aa0b4dec9ab177eb72c3fb8058
+++ test/func/clone_branch_no_dir/__driver__.lua	1ab33d8f6d1bdc38d3804d8fcd41b6c2f65a6e61
@@ -6,18 +6,18 @@ copy("test.db", "test-clone.db")
 commit("mybranch")
 
 copy("test.db", "test-clone.db")
-testURI="file://" .. test.root .. "/test-clone.db?mybranch"
 
-check(nodb_mtn("clone", testURI), 0, false, false)
+test_uri="file://" .. url_encode_path(test.root .. "/test-clone.db") .. "?mybranch"
+check(nodb_mtn("clone", test_uri), 0, false, false)
 check(exists("mybranch"))
 check(readfile("foo") == readfile("mybranch/foo"))
 
 -- but now that that directory exists, this clone should fail
-check(nodb_mtn("clone", testURI), 1, false, false)
+check(nodb_mtn("clone", test_uri), 1, false, false)
 
 -- but succeed if given a specific dir
-check(nodb_mtn("clone", testURI, "otherdir"), 0, false, false)
+check(nodb_mtn("clone", test_uri, "otherdir"), 0, false, false)
 
 -- clone into . should not fail, like checkout
 mkdir("test4")
-check(indir("test4", nodb_mtn("clone", testURI, ".")), 0, false, false)
+check(indir("test4", nodb_mtn("clone", test_uri, ".")), 0, false, false)
============================================================
--- test/func/clone_creates__MTN_log/__driver__.lua	5a8fe703d56ea39db22dcfbe6183294c1eb3f01b
+++ test/func/clone_creates__MTN_log/__driver__.lua	b412d2f37df048846fc1f76ab62572d4c39b0796
@@ -13,9 +13,9 @@ copy("test.db", "test-clone.db")
 check(mtn("--branch=testbranch", "--rcfile=commit_log.lua", "commit"), 0, false, false)
 
 copy("test.db", "test-clone.db")
-testURI="file://" .. test.root .. "/test-clone.db?testbranch"
 
-check(nodb_mtn("clone", testURI, "testbranch"), 0, false, true)
+test_uri="file://" .. url_encode_path(test.root .. "/test-clone.db") .. "?testbranch"
+check(nodb_mtn("clone", test_uri, "testbranch"), 0, false, true)
 
 check(exists("testbranch/_MTN/log"))
 check(fsize("_MTN/log") == 0)
============================================================
--- test/func/clone_creates_right__MTN_options/__driver__.lua	12e86831366aa0f5573d1ec511872b6f9034aeb2
+++ test/func/clone_creates_right__MTN_options/__driver__.lua	9891e77e30b8830f8040bcb817a0db26a433c9dd
@@ -10,7 +10,7 @@ commit()
 writefile("testfile", "blah")
 commit()
 
-testURI="file://" .. test.root .. "/test-clone.db?testbranch"
+test_uri="file://" .. url_encode_path(test.root .. "/test-clone.db") .. "?testbranch"
 
 -- We use RAW_MTN because it used to be that passing --db= (as
 -- MTN does) would hide a bug in this functionality...
@@ -18,16 +18,17 @@ testURI="file://" .. test.root .. "/test
 -- all of these inherit options settings from the current _MTN dir
 -- unless they override them on the command line
 
-check(nodb_mtn("clone", testURI, "test_dir1"), 0, false, false)
-check(nodb_mtn("clone", "--revision", rev, testURI, "test_dir2"), 0, false, false)
-check(nodb_mtn("--db=" .. test.root .. "/test-new.db", "clone", testURI, "test_dir3"), 0, false, false)
-check(nodb_mtn("--db=" .. test.root .. "/test-new.db", "clone", testURI, "--revision", rev, "test_dir4"), 0, false, false)
+check(nodb_mtn("clone", test_uri, "test_dir1"), 0, false, false)
+check(nodb_mtn("clone", "--revision", rev, test_uri, "test_dir2"), 0, false, false)
+check(nodb_mtn("--db=" .. test.root .. "/test-new.db", "clone", test_uri, "test_dir3"), 0, false, false)
+check(nodb_mtn("--db=" .. test.root .. "/test-new.db", "clone", test_uri, "--revision", rev, "test_dir4"), 0, false, false)
 
 -- checkout fails if the specified revision is not a member of the specified branch
-testURI="file://" .. test.root .. "/test-clone.db?foobar"
-check(nodb_mtn("clone", testURI, "--revision", rev, "test_dir5"), 1, false, false)
+test_uri="file://" .. url_encode_path(test.root .. "/test-clone.db") .. "?foobar"
+
+check(nodb_mtn("clone", test_uri, "--revision", rev, "test_dir5"), 1, false, false)
 check(nodb_mtn("cert", rev, "branch", "foobar", "-d", "test-clone.db"), 0, false, false)
-check(nodb_mtn("clone", testURI, "--revision", rev, "test_dir6"), 0, false, false)
+check(nodb_mtn("clone", test_uri, "--revision", rev, "test_dir6"), 0, false, false)
 
 
 for i = 1,2 do
============================================================
--- test/func/clone_validates_target_directory/__driver__.lua	1286723ee00ea9ea6831e12575ba7ac32a066645
+++ test/func/clone_validates_target_directory/__driver__.lua	0c6f70282431ed62359ad0b4a827575406889f4b
@@ -6,15 +6,15 @@ copy("test.db", "test-clone.db")
 commit()
 
 copy("test.db", "test-clone.db")
-testURI="file://" .. test.root .. "/test-clone.db?testbranch"
 
-check(nodb_mtn("clone", testURI, "test_dir1"), 0, false, false)
+test_uri="file://" .. url_encode_path(test.root .. "/test-clone.db") .. "?testbranch"
+check(nodb_mtn("clone", test_uri, "test_dir1"), 0, false, false)
 
 writefile("test_dir2")
-check(nodb_mtn("clone", testURI, "test_dir2"), 1, false, false)
+check(nodb_mtn("clone", test_uri, "test_dir2"), 1, false, false)
 
 mkdir("test_dir3")
-check(nodb_mtn("clone", testURI, "test_dir3"), 1, false, false)
+check(nodb_mtn("clone", test_uri, "test_dir3"), 1, false, false)
 
 if existsonpath("chmod") and existsonpath("test") then
   -- skip this part if run as root (hi Gentoo!)
@@ -27,9 +27,9 @@ if existsonpath("chmod") and existsonpat
   else
     mkdir("test_dir4")
     check({"chmod", "444", "test_dir4"}, 0, false)
-    check(nodb_mtn("clone", testURI, "test_dir4"),
+    check(nodb_mtn("clone", test_uri, "test_dir4"),
              1, false, false)
-    check(nodb_mtn("clone", testURI, "test_dir4/subdir"),
+    check(nodb_mtn("clone", test_uri, "test_dir4/subdir"),
              1, false, false)
     -- Reset the permissions so Autotest can correctly clean up our
     -- temporary directory.
============================================================
--- test/func/clone_warning_with_multiple_heads/__driver__.lua	4333c6de0518517ff9bc04b4baef0d2d5ff08914
+++ test/func/clone_warning_with_multiple_heads/__driver__.lua	18e8670ea08dcb9602425ebdb97a786b20945ff6
@@ -16,9 +16,9 @@ copy("test.db", "test-clone.db")
 REV3=base_revision()
 
 copy("test.db", "test-clone.db")
-testURI="file://" .. test.root .. "/test-clone.db?testbranch"
 
-check(nodb_mtn("clone", testURI, "test_dirA"),
+test_uri="file://" .. url_encode_path(test.root .. "/test-clone.db") .. "?testbranch"
+check(nodb_mtn("clone", test_uri, "test_dirA"),
          1, false, true)
 check(qgrep(REV2, "stderr"))
 check(qgrep(REV3, "stderr"))
============================================================
--- test/func/clone_weird_branch_names/__driver__.lua	205c20a2809513b93ee9ab6c1affb24070f284a2
+++ test/func/clone_weird_branch_names/__driver__.lua	0afc1816afa8d3e4b2dfb9fd016500f224432f0a
@@ -6,10 +6,11 @@ copy("test.db", "test-clone.db")
 commit("my-branch[1,2]-1^3")
 
 copy("test.db", "test-clone.db")
+
 -- some of the special chars need to get double-escaped to get "through"
-testURI="file://" .. test.root .. "/test-clone.db?my-branch\\\[1,2\\\]-1^3"
-
-check(nodb_mtn("clone", testURI), 0, false, false)
+test_uri="file://" .. url_encode_path(test.root .. "/test-clone.db") ..
+  "?" .. url_encode_query("my-branch\\\[1,2\\\]-1^3")
+check(nodb_mtn("clone", test_uri), 0, false, false)
 check(exists("my-branch[1,2]-1^3"))
 check(readfile("foo") == readfile("my-branch[1,2]-1^3/foo"))
 
============================================================
--- /dev/null	
+++ test/func/disapprove_root_revision/__driver__.lua	743f82c455ccc4d57b1ee123d0c8fcf7341f8207
@@ -0,0 +1,11 @@
+mtn_setup()
+
+addfile("foo", "bar")
+commit()
+to_disapprove = base_revision()
+addfile("xyzzy", "xyzzy")
+commit()
+addfile("123", "456")
+commit()
+check(mtn("disapprove", to_disapprove), 1, true, true)
+check(qgrep("cannot disapprove root revision", "stderr"))
============================================================
--- test/func/extended-selectors/__driver__.lua	435f44fb1b33bdfb53929fe6bd15ba7fa4c2c1d3
+++ test/func/extended-selectors/__driver__.lua	cab379ef6f3439ab7f5a4424202ebf9097171c4c
@@ -1,5 +1,6 @@
 -- selector functions are:
 --   difference(a,b)
+--   not(a)
 --   lca(a,b)
 --   max(a)
 --   ancestors(a)
@@ -78,6 +79,18 @@ expect("b:testbranch|b:otherbranch", roo
 expect("b:testbranch/b:otherbranch", lhs)
 expect("b:testbranch|b:otherbranch", root, lhs, rhs, m, other, other_2)
 
+-- now do same tests again with a double not - should get same results
+expect("not(not(b:testbranch))", root, lhs, rhs, m)
+expect("not(not(b:otherbranch))", lhs, other, other_2)
+expect("not(not(b:testbranch/b:otherbranch))", lhs)
+expect("not(not(b:testbranch|b:otherbranch))", root, lhs, rhs, m, other, other_2)
+
+expect("not(b:otherbranch)", root, rhs, m)
+expect("not(b:testbranch)", other, other_2)
+expect("not(h:testbranch)", root, lhs, rhs, other, other_2)
+expect("not(lca(h:testbranch;h:otherbranch))", root, rhs, m, other, other_2)
+expect("b:testbranch/not(a:Joe)", rhs, m)
+
 expect("lca(h:testbranch;h:otherbranch)", lhs)
 expect("max(b:testbranch/a:Joe)", lhs)
 expect("max(b:otherbranch/a:Anne)")
============================================================
--- test/func/imp_test_filesync_confdir/__driver__.lua	5262dae96bcf38a2a27cea3d17523e08ad3e03aa
+++ test/func/imp_test_filesync_confdir/__driver__.lua	19822aa249d9300dc8695f41adbd12cbce5a9234
@@ -18,7 +18,8 @@ end
    rcfile:close()
 end
 
-check(mtn("sync", "file://" .. test.root .. "/test2.db?testbranch"), 0, true, false)
+test_uri="file://" .. url_encode_path(test.root .. "/test2.db") .. "?testbranch"
+check(mtn("sync", test_uri), 0, true, false)
 
 n = 0
 
============================================================
--- test/func/netsync_over_pipes/__driver__.lua	e4ee774912c36ca34a2bfe897daecac570f626a7
+++ test/func/netsync_over_pipes/__driver__.lua	e769e909c59f15351c957a47d98bd7be5868e9f7
@@ -7,6 +7,7 @@ commit()
 addfile("testfile", "foo")
 commit()
 
-check(mtn("sync", "file://" .. test.root .. "/test2.db?testbranch"), 0, false, true)
+test_uri="file://" .. url_encode_path(test.root .. "/test2.db") .. "?testbranch"
+check(mtn("sync", test_uri), 0, false, true)
 check(not qgrep("error", "stderr"))
 check_same_db_contents("test.db", "test2.db")
============================================================
--- test/func/serve-automate/__driver__.lua	ae4b03baf16d8401f31a32c8377021f879788d01
+++ test/func/serve-automate/__driver__.lua	1343490c3b79e3d936a5b72ba7561055239235f8
@@ -56,7 +56,8 @@ if ostype ~= "Windows" then
 if ostype ~= "Windows" then
 -- 'file:' not supported on Windows
 
-check(mtn2("automate", "remote_stdio", "file://" .. test.root .. "/test.db"),
+test_uri="file://" .. url_encode_path(test.root .. "/test.db")
+check(mtn2("automate", "remote_stdio", test_uri),
       0, true, false, "l17:interface_versione")
 check(parse_stdio(readfile("stdout"), 0, 0, "m") ~= nil)
 end
============================================================
--- test/func/serve-automate-single-run/__driver__.lua	01013ad10150f9056bee7609338cb09b47d8c677
+++ test/func/serve-automate-single-run/__driver__.lua	7a75e9ff02a15ebc62a44c1c596ed39e3fdae0a0
@@ -60,8 +60,9 @@ copy("allow-automate.lua", "custom_test_
 -- 'file:' not supported on Windows
 
 copy("allow-automate.lua", "custom_test_hooks.lua")
+test_uri="file://" .. url_encode_path(test.root .. "/test.db")
 check(mtn2("automate", "remote", "--remote-stdio-host",
-	   "file://"..test.root.."/test.db",
+	   test_uri,
 	   "get_file_of", "--", "-r".. R1, "foo"), 0, true, false)
 check(qgrep("bar", "stdout"))
 end
============================================================
--- test/func/syntax_errors_in_.mtn-ignore/mtn-ignore	c46ecd3b4771b7b0af41b6caff2074df0427fbfa
+++ test/func/syntax_errors_in_.mtn-ignore/mtn-ignore	55bfcaa55ef14ee091aa6279251af51121f910b9
@@ -21,7 +21,6 @@ abc\3
 [[:fnord:]]
 \\x{123456}
 (?(0))
-(?<=\C)
 \l
 (?C256)
 (?C1
============================================================
--- test/func/util_mtnopt/__driver__.lua	84307ea94ec302c6d9bbe163955e8f5e86973ce0
+++ test/func/util_mtnopt/__driver__.lua	6981b9fe1aa7800aaaf76bd18f0ddbb73b0e6046
@@ -6,6 +6,11 @@ normalized_testroot = normalize_path (te
 
 normalized_testroot = normalize_path (test.root)
 
+-- Escape regexp special characters to form a proper regexp that correctly
+-- checks for the given path.
+escaped_testroot = string.gsub(normalized_testroot, "([*+.()[\\^$|?])",
+  function (x) return "\\" .. x end)
+
 -- check default operation
 
 -- MinGW does not process the shebang in mtnopt; must invoke sh directly
@@ -13,7 +18,7 @@ check({"sh", "./mtnopt"}, 0, true)
 -- Don't pass the full /bin/sh path, it looks like that doesn't always
 -- work under mingw.
 check({"sh", "./mtnopt"}, 0, true)
-check(qgrep('^MTN_database="' .. normalized_testroot .. '/test.db";$', "stdout"))
+check(qgrep('^MTN_database="' .. escaped_testroot .. '/test.db";$', "stdout"))
 check(qgrep('^MTN_branch="testbranch";$', "stdout"))
 
 -- check operation with a specific key and just returning the value
============================================================
--- test/src/testlib.lua	6d2a308918594226fa6549ed0268ccaea3921038
+++ test/src/testlib.lua	f236da6fce62c15acac578b42756b552e0453d99
@@ -144,6 +144,22 @@ end
   return n
 end
 
+-- encodes a query by percent escaping reserved characters (as defined
+-- in RFC 3986) - except for the directory separator ('/').
+function url_encode_path(path)
+  path = string.gsub(path, "([!*'();:@&=+$,?#[%]])",
+    function (x) return string.format("%%%02X", string.byte(x)) end)
+  return string.gsub(path, " ", "+")
+end
+
+-- encodes a query by percent escaping reserved characters (as defined
+-- in RFC 3986) - except for the ampersand and equal sign ('&', '=')
+function url_encode_query(path)
+  path = string.gsub(path, "([!*'();:@+$,/?#[%]])",
+    function (x) return string.format("%%%02X", string.byte(x)) end)
+  return string.gsub(path, " ", "+")
+end
+
 function open_or_err(filename, mode, depth)
   local file, e = io.open(filename, mode)
   if file == nil then
============================================================
--- src/rev_output.cc	a2c70b893b31296917d1a2b974faa1da46c13f1e
+++ src/rev_output.cc	6b9862bfda95d0d558d8335fb2accfc0180e8fbd
@@ -98,6 +98,23 @@ revision_header(revision_id const rid, r
     if (i->name == tag)
       out << _("Tag:      ") << i->value << '\n';
 
+  // Output "custom" certs if we have any, under a heading of "Other certs"
+  bool need_to_output_heading = true;
+  for (vector<cert>::const_iterator i = certs.begin(); i != certs.end(); ++i)
+    {
+      if (i->name != author && i->name != branch && i->name != changelog &&
+          i->name != comment && i->name != date && i->name != tag)
+        {
+          if (need_to_output_heading)
+            {
+              out << _("Other certs:") << '\n';
+              need_to_output_heading = false;
+            }
+
+          out << "  " << i->name << ": " << i->value << '\n';
+        }
+    }
+
   out << "\n";
 
   for (vector<cert>::const_iterator i = certs.begin(); i != certs.end(); ++i)

reply via email to

[Prev in Thread] Current Thread [Next in Thread]