The unified diff between revisions [d43f812d..] and [2235bcdf..] is displayed below. It can also be downloaded as a raw diff.

#
#
# add_file "tests/t_commit_validate.at"
#  content [2d6e25f801aa61c96d7c063bd1c7e7d1224b55c3]
#
# patch "AUTHORS"
#  from [be2883d201fdd61b63582334f52312a640e012a1]
#    to [66d90072b355ef6e2b66f56c0dfa00de1565dc98]
#
# patch "ChangeLog"
#  from [35e27c7c13b9eaa89a3e64071fc9b3194ffcfd3f]
#    to [345c085f01768304628331900de5b92dd42745b0]
#
# patch "Makefile.am"
#  from [0de9670ac5adedfcfcee3b28078ee70a5736dbcb]
#    to [d4ad27fc9fa7d8d2b82c512a67adbd237b7fcca1]
#
# patch "NEWS"
#  from [112d26a960169d8b6a649c1823c97531a702cf41]
#    to [f564158219d07affd4e05ce10fd131f87157387f]
#
# patch "commands.cc"
#  from [5b867838ffc06ed2fc1fb7e652e18f8905dbf620]
#    to [b3a8d32282111f7f405d1c250e9a22dddad24aab]
#
# patch "database.hh"
#  from [c40cffcb2dfd1083a9cbc78967de69bec751cfe9]
#    to [c33e9d5d1f292ec396c695121530347a065aceaf]
#
# patch "lua.cc"
#  from [78722201fdc513bfee248ce6b30b1b1ae593250e]
#    to [8284c5010bee38f15141c3e60eeeeb7c288ee20c]
#
# patch "lua.hh"
#  from [0d1c63ed6c7b36665ad92780ed88afa1edff3194]
#    to [a682ec35ee70ef30fd080616f8f21d8ef2a1a6ea]
#
# patch "monotone.texi"
#  from [1be851e48f4681094a44ef4d30a5fbefc7985cc3]
#    to [200d3e76ba97251314502d5e9dd0bdb1215289cb]
#
# patch "netsync.cc"
#  from [8c4cbdeb2898f87f5f74457e7148a4cc0afde674]
#    to [4d15f2c47aed8bb45b5dc8267ab60c35703d49e9]
#
# patch "paths.cc"
#  from [227025632497d6849fc4946feeded4d7980f7008]
#    to [f5e27ba6d46c0f26db552d0e1a78641bc4083cff]
#
# patch "po/sv.po"
#  from [d559c2affdfc33f21190e9a6fdc412e37ca1bb46]
#    to [754e90276863a8b1a53cad17c575bb93ffcdd5b4]
#
# patch "std_hooks.lua"
#  from [1740ad529749fadac6c115b8373ca26e9f932ad6]
#    to [259f2956124c69bd0f616943ad64663f67213cd6]
#
# patch "tests/t_database_check_normalized.at"
#  from [a226dd38826693885d4b9209528dac5fced42d6f]
#    to [903b3a090390261102a713b0339e99322d728f16]
#
# patch "tests/t_drop_missing.at"
#  from [b57855a8b89e7f7c8c7cab3ae9fdf660bc4c0111]
#    to [7d7b49bf0e6aee2bb8a7bf96202f464367673274]
#
# patch "tests/t_netsync_permissions.at"
#  from [a02747cf46bece412d85d63694356704a482c8ff]
#    to [9a8356b76404d50e044f74e5f59d6e055ad64d1e]
#
# patch "tests/t_rename.at"
#  from [b95e23675e65c4c3c9bd2b3490d08ce117b11836]
#    to [f9830fde9e91d2b2c97e3ec7d4c423d3e12d2726]
#
# patch "testsuite.at"
#  from [2b15c3a7b584370ff89e92002dcac047ff2df357]
#    to [24fda35bb35a7e2ddd7a98c55741d919899270e2]
#
# patch "work.cc"
#  from [974c1d8a5295fd7317898e60abc636fdcc82ba65]
#    to [bc48e2db4924f6b85004818aeb401f14c94a9bfe]
#
============================================================
--- tests/t_commit_validate.at	2d6e25f801aa61c96d7c063bd1c7e7d1224b55c3
+++ tests/t_commit_validate.at	2d6e25f801aa61c96d7c063bd1c7e7d1224b55c3
@@ -0,0 +1,31 @@
+# -*- Autoconf -*-
+# vim: tw=0
+
+AT_SETUP([commit validation lua hook])
+
+MONOTONE_SETUP
+
+AT_DATA(commit_validate.lua, [
+function validate_commit_message(message, info)
+  if (not string.find(info, "input.txt")) then
+    return false, "Wrong info message"
+  end
+  if (message == "denyme") then
+    return false, "input.txt"
+  end
+
+  return true, ""
+end
+])
+
+AT_DATA(input.txt, [version 0 of the file
+])
+
+AT_CHECK(MONOTONE add input.txt, [], [ignore], [ignore])
+
+AT_CHECK(MONOTONE --branch=testbranch --rcfile=commit_validate.lua commit -m "denyme", 1, [ignore], [monotone: beginning commit on branch 'testbranch'
+monotone: misuse: log message rejected: input.txt
+])
+AT_CHECK(MONOTONE --branch=testbranch --rcfile=commit_validate.lua commit -m "allowme", 0, ignore, ignore)
+
+AT_CLEANUP
============================================================
--- AUTHORS	be2883d201fdd61b63582334f52312a640e012a1
+++ AUTHORS	66d90072b355ef6e2b66f56c0dfa00de1565dc98
@@ -72,6 +72,7 @@ contributing authors, including:
   Roland McGrath <roland@redhat.com>
   Daniel Carosone <dan@geek.com.au>
   Vinzenz Feenstra <evilissimo@c-plusplus.de>
+  Blake Kaplan <mrbkap@gmail.com>

 Several people have also contributed to the translation of monotone
 into non-English languages; their work is available in the po/
============================================================
--- ChangeLog	35e27c7c13b9eaa89a3e64071fc9b3194ffcfd3f
+++ ChangeLog	345c085f01768304628331900de5b92dd42745b0
@@ -1,3 +1,66 @@
+2006-02-11  Matt Johnston  <matt@ucc.asn.au>
+
+	* database.hh: increase checkpoint batch size from 100 to 1000
+
+2006-02-11  Matt Johnston  <matt@ucc.asn.au>
+
+	* NEWS: Fix rename example.
+
+2006-02-11  Richard Levitte  <richard@levitte.org>
+
+	* NEWS: Update with the netsync change.
+
+2006-02-11  Nathaniel Smith  <njs@pobox.com>
+
+	* NEWS: Draft for 0.26pre2.
+
+2006-02-11  Richard Levitte  <richard@levitte.org>
+
+	* netsync.cc (serve_connections): Enclose more or less everything
+	in a try-catch block to catch if using IPv6 failed, and to try
+	with just IPv4 in that case.  This is important for those who
+	copy a IPv6-enabled binary to a system that doesn't use IPv6.
+
+	* po/sv.po: Adapt translation to the newly changed messages.
+
+2006-02-10  Derek Scherger  <derek@echologic.com>
+
+	* tests/t_drop_missing.at:
+	* tests/t_rename.at:
+	* work.cc (visit_file): attempt to improve a couple of messages;
+	remove some unrequired \n's
+
+2006-02-10  Derek Scherger  <derek@echologic.com>
+
+	* netsync.cc (process_anonymous_cmd, process_auth_cmd): don't
+	report misleading permission denied errors for branches that are
+	not being served
+	* paths.cc (find_and_go_to_workspace): delete stale comment
+	* tests/t_netsync_permissions.at: add test pull of branch that is
+	not served
+
+2006-02-10  Richard Levitte  <richard@levitte.org>
+
+	* monotone.texi (Hooks): Change the example for
+	get_revisions_cert_trust to check "branch" certs instead of
+	"ancestor" ones, and thereby match the effect of the "approve"
+	command.
+
+2006-02-10  Matt Johnston  <matt@ucc.asn.au>
+
+	* commands.cc (CMD(checkout)): wrapping in a transaction makes
+	a big difference.
+
+2006-02-09  Nathaniel Smith  <njs@pobox.com>
+
+	* Makefile.am (SQLITE_SOURCES): Remove header files lost in
+	latest SQLite upstream import.
+
+2006-02-09  Graydon Hoare  <graydon@pobox.com>
+
+	* lua.cc (hook_validate_commit_message): make validated the
+	default.
+
 2006-02-09  Richard Levitte  <richard@levitte.org>

 	* tests/t_cvsimport.at, tests/t_cvsimport3.at,
@@ -41,6 +104,15 @@ 2006-02-08  Richard Levitte  <richard@le
 	* commands.cc (ls_changed, CMD(list)): Add a new command, "list
 	changed", to list changed files, always sorted in lexical order.

+2006-02-06  Blake Kaplan  <mrbkap@gmail.com>
+
+	* commands.cc CMD(commit): Call a new lua hook to validate the commit
+	message. Don't ignore -m "" when it's passed on the command line.
+	* lua.cc, lua.hh: Add a new hook that validates a given commit message
+	and passes in the added files, deleted files, and modified files.
+	* std_hooks.lua: Give a default hook to validate commit messages. This
+	currently disallows empty messages, as monotone currently does.
+
 2006-02-05  Benoît Dejean  <benoit@placenet.org>

 	* ui.cc (tick_write_count::write_ticks): Reverted lexical_cast,
============================================================
--- Makefile.am	0de9670ac5adedfcfcee3b28078ee70a5736dbcb
+++ Makefile.am	d4ad27fc9fa7d8d2b82c512a67adbd237b7fcca1
@@ -183,8 +183,8 @@ SQLITE_SOURCES = \
 	sqlite/analyze.c sqlite/vdbefifo.c \
 	sqlite/complete.c \
 	\
-        sqlite/btree.h sqlite/config.h sqlite/hash.h sqlite/opcodes.h sqlite/os.h \
-        sqlite/os_common.h sqlite/os_unix.h sqlite/os_win.h \
+        sqlite/btree.h sqlite/hash.h sqlite/opcodes.h sqlite/os.h \
+        sqlite/os_common.h \
         sqlite/parse.h sqlite/sqlite3.h sqlite/sqliteInt.h sqlite/vdbe.h sqlite/vdbeInt.h \
 	sqlite/pager.h

============================================================
--- NEWS	112d26a960169d8b6a649c1823c97531a702cf41
+++ NEWS	f564158219d07affd4e05ce10fd131f87157387f
@@ -1,7 +1,15 @@
 ????????????????????????????
-        x.yz release.  This is where we write a short summary of the changes
-        for this release.

+        0.26pre2 release.  Inching towards 0.26.  If you are using
+        0.25 or earlier, then make sure to read the very important
+        notes for 0.26pre1, below.  In particular, like 0.26pre1, this
+        is a pre-release for testing.  Do not package it.  DO NOT USE
+        THIS RELEASE UNLESS YOU WANT TO BE A DAREDEVIL.
+
+        (Though, in fact, in a month of usage, only one bug has been
+        found in the new history code, and it was both minor and
+        harmless.  It has additionally been fixed.)
+
         Database changes:

         - SQLite 3.3.3 has been imported.  3.3 introduces a new database
@@ -9,8 +17,45 @@
           New databases will be created using this new format.  Existing
           databases remain compatible, and are not converted automatically.
           Existing databases can be converted by performing a database
-          vacuum.
+          vacuum ('monotone db execute vacuum').

+        UI improvements:
+
+        - rename (and mv) commands now accept a broader range of
+          syntax:
+            monotone rename foo some_dir
+              -> renames foo to some_dir/foo
+            monotone rename foo bar baz some_dir
+              -> moves foo, bar, and baz to some_dir/foo,
+                 some_dir/bar, and some_dir/baz
+        - Print a warning if it looks like a user has made a quoting
+          mistake on push/pull/sync/serve (windows cmd.exe has
+          confusing rules here).
+        - New command "ls changed".
+        - New option "--next" to log, which displays descendents of
+          the start revision.
+        - Updating to an arbitrary revision now works again (as it did
+          in 0.25 and earlier).  This allows one to, for instance,
+          switch a working copy to another head, or back up to an
+          earlier version, while preserving uncommitted changes.
+        - New option --brief to annotate, gives somewhat more friendly
+          output.
+        - Fixed bug that made ticker output from netsync inaccurate.
+        - In 'log', --no-merges is now the default, use --merges to
+          override.
+
+        Other:
+        - Better detection when users have not run "rosterify", and
+          more helpful suggestions on what to do in this case.
+        - Documentation, translation, error message,
+          etc. improvements.
+        - Updates to contrib/mtbrowse.sh, simple shell-based monotone
+          interface.
+        - Updates to many other contrib/ files, mostly to maintain
+          compatibility with monotone changes.
+	- Update netsync.cc so "monotone serve" uses IPv4 if IPv6 fails
+	  for some reason.
+
 Sun Jan  8 01:08:56 PST 2006

         0.26pre1 release.  Massive rewrites, released for shakedown.
============================================================
--- commands.cc	5b867838ffc06ed2fc1fb7e652e18f8905dbf620
+++ commands.cc	b3a8d32282111f7f405d1c250e9a22dddad24aab
@@ -1,4 +1,5 @@
 // -*- mode: C++; c-file-style: "gnu"; indent-tabs-mode: nil -*-
+// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:
 // copyright (C) 2002, 2003 graydon hoare <graydon@pobox.com>
 // all rights reserved.
 // licensed to the public under the terms of the GNU GPL (>= 2)
@@ -1417,6 +1418,8 @@ CMD(checkout, N_("tree"), N_("[DIRECTORY
   // we have a special case for "checkout .", i.e., to current dir
   bool checkout_dot = false;

+  transaction_guard guard(app.db, false);
+
   if (args.size() > 1 || app.revision_selectors.size() > 1)
     throw usage(name);

@@ -1519,6 +1522,7 @@ CMD(checkout, N_("tree"), N_("[DIRECTORY
   remove_work_cset();
   update_any_attrs(app);
   maybe_update_inodeprints(app);
+  guard.commit();
 }

 ALIAS(co, checkout)
@@ -2323,12 +2327,12 @@ process_commit_message_args(bool & given
   N(app.message().length() == 0 || app.message_file().length() == 0,
     F("--message and --message-file are mutually exclusive"));

-  if (app.message().length() > 0)
+  if (app.is_explicit_option(OPT_MESSAGE))
     {
       log_message = app.message();
       given = true;
     }
-  else if (app.message_file().length() > 0)
+  else if (app.is_explicit_option(OPT_MSGFILE))
     {
       data dat;
       read_data_for_command_line(app.message_file(), dat);
@@ -2339,7 +2343,6 @@ process_commit_message_args(bool & given
     given = false;
 }

-
 CMD(commit, N_("workspace"), N_("[PATH]..."),
     N_("commit workspace to database"),
     OPT_BRANCH_NAME % OPT_MESSAGE % OPT_MSGFILE % OPT_DATE %
@@ -2405,6 +2408,16 @@ CMD(commit, N_("workspace"), N_("[PATH].
       write_user_log(data(log_message));
     }

+  // If the hook doesn't exist, allow the message to be used.
+  bool message_validated;
+  string reason, new_manifest_text;
+
+  dump(rs, new_manifest_text);
+
+  app.lua.hook_validate_commit_message(log_message, new_manifest_text,
+                                       message_validated, reason);
+  N(message_validated, F("log message rejected: %s\n") % reason);
+
   {
     transaction_guard guard(app.db);
     packet_db_writer dbw(app);
============================================================
--- database.hh	c40cffcb2dfd1083a9cbc78967de69bec751cfe9
+++ database.hh	c33e9d5d1f292ec396c695121530347a065aceaf
@@ -475,7 +475,7 @@ public:
   size_t checkpointed_bytes;
 public:
   transaction_guard(database & d, bool exclusive=true,
-                    size_t checkpoint_batch_size=100,
+                    size_t checkpoint_batch_size=1000,
                     size_t checkpoint_batch_bytes=0xfffff);
   ~transaction_guard();
   void do_checkpoint();
============================================================
--- lua.cc	78722201fdc513bfee248ce6b30b1b1ae593250e
+++ lua.cc	8284c5010bee38f15141c3e60eeeeb7c288ee20c
@@ -1,4 +1,5 @@
 // -*- mode: C++; c-file-style: "gnu"; indent-tabs-mode: nil -*-
+// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:
 // copyright (C) 2002, 2003 graydon hoare <graydon@pobox.com>
 // all rights reserved.
 // licensed to the public under the terms of the GNU GPL (>= 2)
@@ -1382,6 +1383,25 @@ lua_hooks::hook_get_linesep_conv(file_pa
   return ll.ok();
 }

+bool
+lua_hooks::hook_validate_commit_message(std::string const & message,
+                                        std::string const & new_manifest_text,
+                                        bool & validated,
+                                        std::string & reason)
+{
+  validated = true;
+  return Lua(st)
+    .func("validate_commit_message")
+    .push_str(message)
+    .push_str(new_manifest_text)
+    .call(2, 2)
+    .extract_str(reason)
+    // XXX When validated, the extra returned string is superfluous.
+    .pop()
+    .extract_bool(validated)
+    .ok();
+}
+
 bool
 lua_hooks::hook_note_commit(revision_id const & new_id,
                             revision_data const & rdat,
============================================================
--- lua.hh	0d1c63ed6c7b36665ad92780ed88afa1edff3194
+++ lua.hh	a682ec35ee70ef30fd080616f8f21d8ef2a1a6ea
@@ -106,6 +106,12 @@ public:
   bool hook_get_linesep_conv(file_path const & p,
                              std::string & db, std::string & ext);

+  // validation hooks
+  bool hook_validate_commit_message(std::string const & message,
+                                    std::string const & new_manifest_text,
+                                    bool & validated,
+                                    std::string & reason);
+
   // notification hooks
   bool hook_note_commit(revision_id const & new_id,
                         revision_data const & rdat,
============================================================
--- monotone.texi	1be851e48f4681094a44ef4d30a5fbefc7985cc3
+++ monotone.texi	200d3e76ba97251314502d5e9dd0bdb1215289cb
@@ -6367,8 +6367,8 @@ @subsection Trust Evaluation Hooks

    if t == nil then return false end

-   if    (name ~= "ancestor" and table.getn(t) >= 1)
-      or (name == "ancestor" and table.getn(t) >= 2)
+   if    (name ~= "branch" and table.getn(t) >= 1)
+      or (name == "branch" and table.getn(t) >= 2)
    then
       return true
    else
@@ -6380,10 +6380,10 @@ @subsection Trust Evaluation Hooks

 In this example, any revision certificate is trusted if it is signed
 by at least one of three ``trusted'' keys, unless it is an
-@code{ancestor} certificate, in which case it must be signed by
+@code{branch} certificate, in which case it must be signed by
 @emph{two} or more trusted keys. This is one way of requiring that
-ancestry assertions go through an extra ``reviewer'' before they are
-accepted.
+the revision has been approved by an extra ``reviewer'' who used the
+@code{approve} command.

 @item accept_testresult_change (@var{old_results}, @var{new_results})

============================================================
--- netsync.cc	8c4cbdeb2898f87f5f74457e7148a4cc0afde674
+++ netsync.cc	4d15f2c47aed8bb45b5dc8267ab60c35703d49e9
@@ -1318,13 +1318,18 @@ session::process_anonymous_cmd(protocol_
       i != branchnames.end(); i++)
     {
       if (their_matcher(*i))
-        if (our_matcher(*i) && app.lua.hook_get_netsync_read_permitted(*i))
-          ok_branches.insert(utf8(*i));
-        else
+        if (!our_matcher(*i))
           {
+            error((F("not serving branch '%s'") % *i).str());
+            return true;
+          }
+        else if (!app.lua.hook_get_netsync_read_permitted(*i))
+          {
             error((F("anonymous access to branch '%s' denied by server") % *i).str());
             return true;
           }
+        else
+          ok_branches.insert(utf8(*i));
     }

   P(F("allowed anonymous read permission for '%s' excluding '%s'\n")
@@ -1410,15 +1415,22 @@ session::process_auth_cmd(protocol_role
     {
       if (their_matcher(*i))
         {
-          if (our_matcher(*i) && app.lua.hook_get_netsync_read_permitted(*i, their_id))
-            ok_branches.insert(utf8(*i));
-          else
+          if (!our_matcher(*i))
             {
+              error((F("not serving branch '%s'") % *i).str());
+              return true;
+
+            }
+          else if (!app.lua.hook_get_netsync_read_permitted(*i, their_id))
+            {
               W(F("denied '%s' read permission for '%s' excluding '%s' because of branch '%s'\n")
                 % their_id % their_include_pattern % their_exclude_pattern % *i);
+
               error((F("access to branch '%s' denied by server") % *i).str());
               return true;
             }
+          else
+            ok_branches.insert(utf8(*i));
         }
     }

@@ -2563,102 +2575,138 @@ serve_connections(protocol_role role,
 #else
   bool use_ipv6=false;
 #endif
-  Netxx::Address addr(use_ipv6);
+  // This will be true when we try to bind while using IPv6.  See comments
+  // further down.
+  bool try_again=false;

-  if (!app.bind_address().empty())
-      addr.add_address(app.bind_address().c_str(), default_port);
-  else
-      addr.add_all_addresses (default_port);
+  do
+    {
+      try
+        {
+          try_again = false;

+          Netxx::Address addr(use_ipv6);

-  Netxx::StreamServer server(addr, timeout);
-  const char *name = addr.get_name();
-  P(F("beginning service on %s : %s\n")
-    % (name != NULL ? name : "all interfaces")
-    % lexical_cast<string>(addr.get_port()));
+          if (!app.bind_address().empty())
+            addr.add_address(app.bind_address().c_str(), default_port);
+          else
+            addr.add_all_addresses (default_port);
+
+          // If se use IPv6 and the initiasation of server fails, we want
+          // to try again with IPv4.  The reason is that someone may have
+          // downloaded a IPv6-enabled monotone on a system that doesn't
+          // have IPv6, and which might fail therefore.
+          // On failure, Netxx::NetworkException is thrown, and we catch
+          // it further down.
+          try_again=use_ipv6;
+
+          Netxx::StreamServer server(addr, timeout);
+
+          // If we came this far, whatever we used (IPv6 or IPv4) was
+          // accepted, so we don't need to try again any more.
+          try_again=false;
+
+          const char *name = addr.get_name();
+          P(F("beginning service on %s : %s\n")
+            % (name != NULL ? name : "all interfaces")
+            % lexical_cast<string>(addr.get_port()));

-  map<Netxx::socket_type, shared_ptr<session> > sessions;
-  set<Netxx::socket_type> armed_sessions;
+          map<Netxx::socket_type, shared_ptr<session> > sessions;
+          set<Netxx::socket_type> armed_sessions;

-  shared_ptr<transaction_guard> guard;
+          shared_ptr<transaction_guard> guard;

-  while (true)
-    {
-      probe.clear();
-      armed_sessions.clear();
+          while (true)
+            {
+              probe.clear();
+              armed_sessions.clear();

-      if (sessions.size() >= session_limit)
-        W(F("session limit %d reached, some connections "
-            "will be refused\n") % session_limit);
-      else
-        probe.add(server);
+              if (sessions.size() >= session_limit)
+                W(F("session limit %d reached, some connections "
+                    "will be refused\n") % session_limit);
+              else
+                probe.add(server);

-      arm_sessions_and_calculate_probe(probe, sessions, armed_sessions);
+              arm_sessions_and_calculate_probe(probe, sessions, armed_sessions);

-      L(FL("i/o probe with %d armed\n") % armed_sessions.size());
-      Netxx::Probe::result_type res = probe.ready(sessions.empty() ? forever
-                                           : (armed_sessions.empty() ? timeout
-                                              : instant));
-      Netxx::Probe::ready_type event = res.second;
-      Netxx::socket_type fd = res.first;
+              L(FL("i/o probe with %d armed\n") % armed_sessions.size());
+              Netxx::Probe::result_type res = probe.ready(sessions.empty() ? forever
+                                                          : (armed_sessions.empty() ? timeout
+                                                             : instant));
+              Netxx::Probe::ready_type event = res.second;
+              Netxx::socket_type fd = res.first;

-      if (!guard)
-        guard = shared_ptr<transaction_guard>(new transaction_guard(app.db));
+              if (!guard)
+                guard = shared_ptr<transaction_guard>(new transaction_guard(app.db));

-      I(guard);
+              I(guard);

-      if (fd == -1)
-        {
-          if (armed_sessions.empty())
-            L(FL("timed out waiting for I/O (listening on %s : %s)\n")
-              % addr.get_name() % lexical_cast<string>(addr.get_port()));
-        }
+              if (fd == -1)
+                {
+                  if (armed_sessions.empty())
+                    L(FL("timed out waiting for I/O (listening on %s : %s)\n")
+                      % addr.get_name() % lexical_cast<string>(addr.get_port()));
+                }

-      // we either got a new connection
-      else if (fd == server)
-        handle_new_connection(addr, server, timeout, role,
-                              include_pattern, exclude_pattern,
-                              sessions, app);
+              // we either got a new connection
+              else if (fd == server)
+                handle_new_connection(addr, server, timeout, role,
+                                      include_pattern, exclude_pattern,
+                                      sessions, app);

-      // or an existing session woke up
-      else
-        {
-          map<Netxx::socket_type, shared_ptr<session> >::iterator i;
-          i = sessions.find(fd);
-          if (i == sessions.end())
-            {
-              L(FL("got woken up for action on unknown fd %d\n") % fd);
-            }
-          else
-            {
-              shared_ptr<session> sess = i->second;
-              bool live_p = true;
+              // or an existing session woke up
+              else
+                {
+                  map<Netxx::socket_type, shared_ptr<session> >::iterator i;
+                  i = sessions.find(fd);
+                  if (i == sessions.end())
+                    {
+                      L(FL("got woken up for action on unknown fd %d\n") % fd);
+                    }
+                  else
+                    {
+                      shared_ptr<session> sess = i->second;
+                      bool live_p = true;

-              if (event & Netxx::Probe::ready_read)
-                handle_read_available(fd, sess, sessions,
-                                      armed_sessions, live_p);
+                      if (event & Netxx::Probe::ready_read)
+                        handle_read_available(fd, sess, sessions,
+                                              armed_sessions, live_p);

-              if (live_p && (event & Netxx::Probe::ready_write))
-                handle_write_available(fd, sess, sessions, live_p);
+                      if (live_p && (event & Netxx::Probe::ready_write))
+                        handle_write_available(fd, sess, sessions, live_p);

-              if (live_p && (event & Netxx::Probe::ready_oobd))
+                      if (live_p && (event & Netxx::Probe::ready_oobd))
+                        {
+                          P(F("got OOB from peer %s, disconnecting\n")
+                            % sess->peer_id);
+                          sessions.erase(i);
+                        }
+                    }
+                }
+              process_armed_sessions(sessions, armed_sessions, *guard);
+              reap_dead_sessions(sessions, timeout_seconds);
+
+              if (sessions.empty())
                 {
-                  P(F("got OOB from peer %s, disconnecting\n")
-                    % sess->peer_id);
-                  sessions.erase(i);
+                  // Let the guard die completely if everything's gone quiet.
+                  guard->commit();
+                  guard.reset();
                 }
             }
         }
-      process_armed_sessions(sessions, armed_sessions, *guard);
-      reap_dead_sessions(sessions, timeout_seconds);
-
-      if (sessions.empty())
+      catch (Netxx::NetworkException &e)
         {
-          // Let the guard die completely if everything's gone quiet.
-          guard->commit();
-          guard.reset();
+          // If we tried with IPv6 and failed, we want to try again using IPv4.
+          if (try_again)
+            {
+              use_ipv6 = false;
+            }
+          // In all other cases, just rethrow the exception.
+          else
+            throw;
         }
     }
+  while(try_again);
 }


============================================================
--- paths.cc	227025632497d6849fc4946feeded4d7980f7008
+++ paths.cc	f5e27ba6d46c0f26db552d0e1a78641bc4083cff
@@ -473,7 +473,6 @@ find_and_go_to_workspace(system_path con
 bool
 find_and_go_to_workspace(system_path const & search_root)
 {
-  // unimplemented
   fs::path root(search_root.as_external(), fs::native);
   fs::path bookdir(bookkeeping_root.as_external(), fs::native);
   fs::path current(fs::initial_path());
============================================================
--- po/sv.po	d559c2affdfc33f21190e9a6fdc412e37ca1bb46
+++ po/sv.po	754e90276863a8b1a53cad17c575bb93ffcdd5b4
@@ -144,8 +144,8 @@ msgstr ""
 msgstr ""
 "Project-Id-Version: monotone 0.26pre1\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2006-02-08 22:47+0100\n"
-"PO-Revision-Date: 2006-02-08 22:57+0100\n"
+"POT-Creation-Date: 2006-02-11 08:32+0100\n"
+"PO-Revision-Date: 2006-02-11 08:43+0100\n"
 "Last-Translator: Joel Rosdahl <joel@rosdahl.net>\n"
 "Language-Team: Richard Levitte <richard@levitte.org>\n"
 "MIME-Version: 1.0\n"
@@ -283,39 +283,39 @@ msgstr "flera grencert funna för revisi
 "multiple branch certs found for revision %s, please provide a branch name"
 msgstr "flera grencert funna för revision %s, var god ange en gren"

-#: commands.cc:159
+#: commands.cc:160
 #, c-format
 msgid "command '%s' has multiple ambiguous expansions:\n"
 msgstr "kommandot '%s' har mer än en betydelse:\n"

-#: commands.cc:202
+#: commands.cc:203
 msgid "commands:"
 msgstr "kommandon:"

-#: commands.cc:253
+#: commands.cc:254
 #, c-format
 msgid "unknown command '%s'\n"
 msgstr "okänt kommando '%s'\n"

-#: commands.cc:300
+#: commands.cc:301
 #, c-format
 msgid "pid file '%s' already exists"
 msgstr "pid-filen '%s' finns redan"

-#: commands.cc:324 commands.cc:1294 commands.cc:1364 commands.cc:1797
-#: commands.cc:2709 commands.cc:3253 commands.cc:3484 commands.cc:3523
+#: commands.cc:325 commands.cc:1295 commands.cc:1365 commands.cc:1801
+#: commands.cc:2722 commands.cc:3266 commands.cc:3497 commands.cc:3536
 msgid "informative"
 msgstr "informativ"

-#: commands.cc:324
+#: commands.cc:325
 msgid "command [ARGS...]"
 msgstr "kommandon [ARGUMENT...]"

-#: commands.cc:324
+#: commands.cc:325
 msgid "display command help"
 msgstr "skriv ut hjälptext"

-#: commands.cc:403
+#: commands.cc:404
 msgid ""
 "Enter a description of this change.\n"
 "Lines beginning with `MT:' are removed automatically.\n"
@@ -323,16 +323,16 @@ msgstr ""
 "Mata in en beskrivning av denna ändring.\n"
 "Rader som börjar med 'MT:' kommer att tas bort automatiskt.\n"

-#: commands.cc:410
+#: commands.cc:411
 #, c-format
 msgid "edit of log message failed"
 msgstr "redigering av loggmeddelandet misslyckades"

-#: commands.cc:419
+#: commands.cc:420
 msgid "note: "
 msgstr "obs: "

-#: commands.cc:420
+#: commands.cc:421
 #, c-format
 msgid ""
 "branch '%s' has multiple heads\n"
@@ -341,59 +341,59 @@ msgstr ""
 "grenen '%s' har mer än ett löv\n"
 "kanske borde du överväga 'monotone merge'"

-#: commands.cc:480 commands.cc:736 commands.cc:1382 commands.cc:1457
-#: commands.cc:1884 commands.cc:2759 commands.cc:2787 commands.cc:2790
-#: commands.cc:2926 commands.cc:3506
+#: commands.cc:481 commands.cc:737 commands.cc:1383 commands.cc:1460
+#: commands.cc:1888 commands.cc:2772 commands.cc:2800 commands.cc:2803
+#: commands.cc:2939 commands.cc:3519
 #, c-format
 msgid "no such revision '%s'"
 msgstr "det finns ingen revision med identiteten '%s'"

-#: commands.cc:487
+#: commands.cc:488
 #, c-format
 msgid "expanding selection '%s'\n"
 msgstr "expanderar valet '%s'\n"

-#: commands.cc:495
+#: commands.cc:496
 #, c-format
 msgid "no match for selection '%s'"
 msgstr "det finns inget som matchar '%s'"

-#: commands.cc:498
+#: commands.cc:499
 #, c-format
 msgid "selection '%s' has multiple ambiguous expansions: \n"
 msgstr "valet '%s' har mer än en möjlig betydelse: \n"

-#: commands.cc:505
+#: commands.cc:506
 #, c-format
 msgid "expanded to '%s'\n"
 msgstr "expanderar till '%s'\n"

-#: commands.cc:516
+#: commands.cc:517
 #, c-format
 msgid "non-hex digits in id"
 msgstr "något tecken i identiteten är inte hexadecimalt"

-#: commands.cc:525
+#: commands.cc:526
 #, c-format
 msgid "partial id '%s' does not have an expansion"
 msgstr "den partiella identiteten '%s' matchar inte befintliga identiteter"

-#: commands.cc:528
+#: commands.cc:529
 #, c-format
 msgid "partial id '%s' has multiple ambiguous expansions:\n"
 msgstr "den partiella identiteten '%s' har mer än en uttydning:\n"

-#: commands.cc:535
+#: commands.cc:536
 #, c-format
 msgid "expanded partial id '%s' to '%s'\n"
 msgstr "expanderade partiell identitet '%s' till '%s'\n"

-#: commands.cc:562 netsync.cc:1710
+#: commands.cc:563 netsync.cc:1722
 #, c-format
 msgid "no public key '%s' found in database"
 msgstr "den publika nyckeln '%s' finns inte i databasen"

-#: commands.cc:572
+#: commands.cc:573
 #, c-format
 msgid ""
 "Key   : %s\n"
@@ -406,87 +406,87 @@ msgstr ""
 "Namn     : %s\n"
 "Värde    : %s\n"

-#: commands.cc:606
+#: commands.cc:607
 msgid "ok"
 msgstr "ok"

-#: commands.cc:609
+#: commands.cc:610
 msgid "bad"
 msgstr "felaktig"

-#: commands.cc:612
+#: commands.cc:613
 msgid "unknown"
 msgstr "okänd"

-#: commands.cc:699
+#: commands.cc:700
 #, c-format
 msgid "(*) - only in %s/"
 msgstr "(*) - enbart i %s/"

-#: commands.cc:722
+#: commands.cc:723
 #, c-format
 msgid "no keys found\n"
 msgstr "hittade inga nycklar\n"

-#: commands.cc:724
+#: commands.cc:725
 #, c-format
 msgid "no keys found matching '%s'\n"
 msgstr "hittade inga nycklar som matchar '%s'\n"

-#: commands.cc:742
+#: commands.cc:743
 #, c-format
 msgid "revision %s already has children. We cannot kill it."
 msgstr "revisionen %s har barn. Vi kan inte ta bort den."

-#: commands.cc:882 commands.cc:906 commands.cc:943 commands.cc:964
-#: commands.cc:1000
+#: commands.cc:883 commands.cc:907 commands.cc:944 commands.cc:965
+#: commands.cc:1001
 msgid "key and cert"
 msgstr "nyckel och cert"

-#: commands.cc:882 commands.cc:906 commands.cc:943
+#: commands.cc:883 commands.cc:907 commands.cc:944
 msgid "KEYID"
 msgstr "NYCKELID"

-#: commands.cc:882
+#: commands.cc:883
 msgid "generate an RSA key-pair"
 msgstr "skapa ett RSA-nyckelpar"

-#: commands.cc:897
+#: commands.cc:898
 #, c-format
 msgid "key '%s' already exists"
 msgstr "nyckeln '%s' finns redan"

-#: commands.cc:900
+#: commands.cc:901
 #, c-format
 msgid "generating key-pair '%s'"
 msgstr "skapar nyckelparet '%s'"

-#: commands.cc:902
+#: commands.cc:903
 #, c-format
 msgid "storing key-pair '%s' in %s/"
 msgstr "lagrar nyckelparet '%s' i %s/"

-#: commands.cc:906
+#: commands.cc:907
 msgid "drop a public and private key"
 msgstr "släng publik och privat nyckel"

-#: commands.cc:920
+#: commands.cc:921
 #, c-format
 msgid "dropping public key '%s' from database\n"
 msgstr "tar bort den publika nyckeln '%s' ur databasen\n"

-#: commands.cc:930
+#: commands.cc:931
 #, c-format
 msgid "dropping key pair '%s' from keystore\n"
 msgstr "tar bort nyckelparet '%s' från nyckellagret\n"

-#: commands.cc:937
+#: commands.cc:938
 #, c-format
 msgid "public or private key '%s' does not exist in keystore or database"
 msgstr ""
 "den publika eller privata nyckeln '%s' finns inte i nyckellager eller databas"

-#: commands.cc:939
+#: commands.cc:940
 #, c-format
 msgid ""
 "public or private key '%s' does not exist in keystore, and no database was "
@@ -495,33 +495,33 @@ msgstr ""
 "den publika eller privata nyckeln '%s' finns inte i nyckellager och ingen "
 "databas angavs"

-#: commands.cc:944
+#: commands.cc:945
 msgid "change passphrase of a private RSA key"
 msgstr "ändra lösen till en privat RSA-nyckel"

-#: commands.cc:954
+#: commands.cc:955
 #, c-format
 msgid "key '%s' does not exist in the keystore"
 msgstr "nyckeln '%s' finns inte i nyckellagret"

-#: commands.cc:961
+#: commands.cc:962
 #, c-format
 msgid "passphrase changed\n"
 msgstr "lösen ändrat\n"

-#: commands.cc:964
+#: commands.cc:965
 msgid "REVISION CERTNAME [CERTVAL]"
 msgstr "REVISION CERTNAMN [CERTVÄRDE]"

-#: commands.cc:965
+#: commands.cc:966
 msgid "create a cert for a revision"
 msgstr "skapa ett cert för en revision"

-#: commands.cc:1000
+#: commands.cc:1001
 msgid "REVISION NAME VALUE SIGNER1 [SIGNER2 [...]]"
 msgstr "REVISION NAMN VÄRDE SIGNERARE1 [SIGNERARE2 [...]]"

-#: commands.cc:1001
+#: commands.cc:1002
 msgid ""
 "test whether a hypothetical cert would be trusted\n"
 "by current settings"
@@ -529,7 +529,7 @@ msgstr ""
 "kontrollera ifall ett hypotetiskt cert skulle vara pålitligt\n"
 "enligt nuvarande inställningar"

-#: commands.cc:1034
+#: commands.cc:1035
 #, c-format
 msgid ""
 "if a cert on: %s\n"
@@ -544,101 +544,101 @@ msgstr ""
 "signerades av: %s\n"
 "skulle det vara: %s\n"

-#: commands.cc:1043
+#: commands.cc:1044
 msgid "trusted"
 msgstr "pålitligt"

-#: commands.cc:1043
+#: commands.cc:1044
 msgid "UNtrusted"
 msgstr "Opålitligt"

-#: commands.cc:1046 commands.cc:1059 commands.cc:1072 commands.cc:1089
-#: commands.cc:1140
+#: commands.cc:1047 commands.cc:1060 commands.cc:1073 commands.cc:1090
+#: commands.cc:1141
 msgid "review"
 msgstr "granskning"

-#: commands.cc:1046
+#: commands.cc:1047
 msgid "REVISION TAGNAME"
 msgstr "REVISION TAGNAMN"

-#: commands.cc:1047
+#: commands.cc:1048
 msgid "put a symbolic tag cert on a revision version"
 msgstr "sätt ett symboliskt tagg-cert på en revision"

-#: commands.cc:1059
+#: commands.cc:1060
 msgid "ID (pass|fail|true|false|yes|no|1|0)"
 msgstr "ID (pass|fail|true|false|yes|no|1|0)"

-#: commands.cc:1060
+#: commands.cc:1061
 msgid "note the results of running a test on a revision"
 msgstr "notera ett testresultat för en revision"

-#: commands.cc:1072 commands.cc:1089
+#: commands.cc:1073 commands.cc:1090
 msgid "REVISION"
 msgstr "REVISION"

-#: commands.cc:1073
+#: commands.cc:1074
 msgid "approve of a particular revision"
 msgstr "godkänn en specifik revision"

-#: commands.cc:1084
+#: commands.cc:1085
 #, c-format
 msgid "need --branch argument for approval"
 msgstr "för godkännande behöver en gren anges med --branch"

-#: commands.cc:1090
+#: commands.cc:1091
 msgid "disapprove of a particular revision"
 msgstr "underkänn en specifik revision"

-#: commands.cc:1103
+#: commands.cc:1104
 #, c-format
 msgid "revision '%s' has %d changesets, cannot invert\n"
 msgstr "revisionen '%s' har %d föräldrar, kan inte invertera\n"

-#: commands.cc:1107
+#: commands.cc:1108
 #, c-format
 msgid "need --branch argument for disapproval"
 msgstr "för underkännande behöver en gren anges med --branch"

-#: commands.cc:1140
+#: commands.cc:1141
 msgid "REVISION [COMMENT]"
 msgstr "REVISION [KOMMENTAR]"

-#: commands.cc:1141
+#: commands.cc:1142
 msgid "comment on a particular revision"
 msgstr "kommentera en specifik revision"

-#: commands.cc:1151
+#: commands.cc:1152
 #, c-format
 msgid "edit comment failed"
 msgstr "misslyckades med att redigera kommentaren"

-#: commands.cc:1154
+#: commands.cc:1155
 #, c-format
 msgid "empty comment"
 msgstr "tom kommentar"

-#: commands.cc:1167 commands.cc:1195 commands.cc:1220 commands.cc:1341
-#: commands.cc:2220 commands.cc:2339 commands.cc:2862 commands.cc:3301
+#: commands.cc:1168 commands.cc:1196 commands.cc:1221 commands.cc:1342
+#: commands.cc:2224 commands.cc:2342 commands.cc:2875 commands.cc:3314
 msgid "workspace"
 msgstr "arbetskopia"

-#: commands.cc:1167 commands.cc:1195 commands.cc:1294 commands.cc:2339
-#: commands.cc:2709 commands.cc:3301
+#: commands.cc:1168 commands.cc:1196 commands.cc:1295 commands.cc:2342
+#: commands.cc:2722 commands.cc:3314
 msgid "[PATH]..."
 msgstr "[SÖKVÄG]..."

-#: commands.cc:1168
+#: commands.cc:1169
 #, fuzzy
 msgid "add files to workspace"
 msgstr "lägg till filer i arbetskopian"

-#: commands.cc:1196
+#: commands.cc:1197
 #, fuzzy
 msgid "drop files from workspace"
 msgstr "överge filer i arbetskopian"

-#: commands.cc:1221
+#: commands.cc:1222
 msgid ""
 "SRC DEST\n"
 "SRC1 [SRC2 [...]] DEST_DIR"
@@ -646,83 +646,83 @@ msgstr ""
 "KÄLLA MÅL\n"
 "KÄLLA1 [KÄLLA2 [...]] MÅLKATALOG"

-#: commands.cc:1223
+#: commands.cc:1224
 #, fuzzy
 msgid "rename entries in the workspace"
 msgstr "byt namn på filer i arbetskopian"

-#: commands.cc:1248 commands.cc:1261 commands.cc:3404 commands.cc:3844
+#: commands.cc:1249 commands.cc:1262 commands.cc:3417 commands.cc:3857
 msgid "debug"
 msgstr "felsökning"

-#: commands.cc:1248
+#: commands.cc:1249
 msgid "load file contents into db"
 msgstr "ladda in filinnehållet i databasen"

-#: commands.cc:1261
+#: commands.cc:1262
 msgid "<parent> <left> <right>"
 msgstr "<förälder> <vänster> <höger>"

-#: commands.cc:1262
+#: commands.cc:1263
 msgid "merge 3 files and output result"
 msgstr "slå ihop 3 filer och skriv ut resultatet"

-#: commands.cc:1272
+#: commands.cc:1273
 #, c-format
 msgid "ancestor file id does not exist"
 msgstr "förälderns filidentitet finns inte"

-#: commands.cc:1275
+#: commands.cc:1276
 #, c-format
 msgid "left file id does not exist"
 msgstr "vänster fils identitet finns inte"

-#: commands.cc:1278
+#: commands.cc:1279
 #, c-format
 msgid "right file id does not exist"
 msgstr "höger fils identitet finns inte"

-#: commands.cc:1289
+#: commands.cc:1290
 #, c-format
 msgid "merge failed"
 msgstr "ihopslagningen misslyckades"

-#: commands.cc:1294
+#: commands.cc:1295
 #, fuzzy
 msgid "show status of workspace"
 msgstr "visa arbetskopians status"

-#: commands.cc:1341
+#: commands.cc:1342
 msgid "[PATH]"
 msgstr "[SÖKVÄG]"

-#: commands.cc:1342
+#: commands.cc:1343
 msgid "calculate identity of PATH or stdin"
 msgstr "räkna ut identiteten för SÖKVÄG eller stdin"

-#: commands.cc:1365
+#: commands.cc:1366
 msgid "FILENAME"
 msgstr "FILNAMN"

-#: commands.cc:1366
+#: commands.cc:1367
 msgid "write file from database to stdout"
 msgstr "skriv ut angiven fil från databasen"

-#: commands.cc:1394 commands.cc:1396 commands.cc:3515
+#: commands.cc:1395 commands.cc:1397 commands.cc:3528
 #, c-format
 msgid "no file '%s' found in revision '%s'\n"
 msgstr "filen '%s' finns inte i revisionen '%s'\n"

-#: commands.cc:1408 commands.cc:1527 commands.cc:3063 commands.cc:3112
-#: commands.cc:3201 commands.cc:3208 commands.cc:3757
+#: commands.cc:1409 commands.cc:1531 commands.cc:3076 commands.cc:3125
+#: commands.cc:3214 commands.cc:3221 commands.cc:3770
 msgid "tree"
 msgstr "träd"

-#: commands.cc:1408
+#: commands.cc:1409
 msgid "[DIRECTORY]\n"
 msgstr "[KATALOG]\n"

-#: commands.cc:1409
+#: commands.cc:1410
 msgid ""
 "check out a revision from database into directory.\n"
 "If a revision is given, that's the one that will be checked out.\n"
@@ -734,62 +734,62 @@ msgstr ""
 "kommer lövet i grenen (implicit eller angiven) att hämtas. Om\n"
 "ingen katalog anges kommer grenens namn att användas som katalognamn."

-#: commands.cc:1426 commands.cc:1445
+#: commands.cc:1429 commands.cc:1448
 #, c-format
 msgid "need --branch argument for branch-based checkout"
 msgstr "--branch behövs för att kunna hämta en revision med given gren"

-#: commands.cc:1439
+#: commands.cc:1442
 #, c-format
 msgid "checkout directory '%s' already exists"
 msgstr "arbetskatalogen '%s' finns redan"

-#: commands.cc:1448 commands.cc:1540 commands.cc:3076 commands.cc:3146
-#: commands.cc:3149
+#: commands.cc:1451 commands.cc:1544 commands.cc:3089 commands.cc:3159
+#: commands.cc:3162
 #, c-format
 msgid "branch '%s' is empty\n"
 msgstr "grenen '%s' är tom\n"

-#: commands.cc:1449
+#: commands.cc:1452
 #, c-format
 msgid "branch %s has multiple heads"
 msgstr "grenen %s har flera löv"

-#: commands.cc:1475
+#: commands.cc:1478
 #, c-format
 msgid "revision %s is not a member of branch %s\n"
 msgstr "revisionen %s är inte med i grenen %s\n"

-#: commands.cc:1509
+#: commands.cc:1512
 #, c-format
 msgid "no file %s found in database for %s"
 msgstr "det finns ingen fil %s för %s i databasen"

-#: commands.cc:1527
+#: commands.cc:1531
 msgid "show unmerged head revisions of branch"
 msgstr "visa ej ihopslagna lövrevisioner i grenen"

-#: commands.cc:1535 commands.cc:3072
+#: commands.cc:1539 commands.cc:3085
 #, c-format
 msgid "please specify a branch, with --branch=BRANCH"
 msgstr "var god ange en gren med --branch=GREN"

-#: commands.cc:1542
+#: commands.cc:1546
 #, c-format
 msgid "branch '%s' is currently merged:\n"
 msgstr "grenen '%s' har för tillfället ett löv:\n"

-#: commands.cc:1544
+#: commands.cc:1548
 #, c-format
 msgid "branch '%s' is currently unmerged:\n"
 msgstr "grenen '%s' har för tillfället mer än ett löv:\n"

-#: commands.cc:1583
+#: commands.cc:1587
 #, c-format
 msgid "no epoch for branch %s\n"
 msgstr "ingen epok i grenen %s\n"

-#: commands.cc:1798
+#: commands.cc:1802
 msgid ""
 "certs ID\n"
 "keys [PATTERN]\n"
@@ -815,7 +815,7 @@ msgstr ""
 "missing\n"
 "changed"

-#: commands.cc:1809
+#: commands.cc:1813
 msgid ""
 "show database objects, or the current workspace manifest, or known,\n"
 "unknown, intentionally ignored, missing, or changed state files"
@@ -823,151 +823,151 @@ msgstr ""
 "visa databasobjekten, arbetskopians manifest, okända filer, kända\n"
 "filer, medvetet ignorerade filer, saknade filer eller ändrade filer"

-#: commands.cc:1847 commands.cc:1871 commands.cc:1890 commands.cc:1909
-#: commands.cc:1927 commands.cc:1955 commands.cc:1973
+#: commands.cc:1851 commands.cc:1875 commands.cc:1894 commands.cc:1913
+#: commands.cc:1931 commands.cc:1959 commands.cc:1977
 msgid "packet i/o"
 msgstr "paket-I/O"

-#: commands.cc:1847
+#: commands.cc:1851
 msgid "OLDID NEWID"
 msgstr "GAMMALT-ID NYTT-ID"

-#: commands.cc:1848
+#: commands.cc:1852
 msgid "write file delta packet to stdout"
 msgstr "skriv ut datapaket för fildelta till stdout"

-#: commands.cc:1862 commands.cc:1864 commands.cc:1903
+#: commands.cc:1866 commands.cc:1868 commands.cc:1907
 #, c-format
 msgid "no such file '%s'"
 msgstr "filen '%s' finns inte"

-#: commands.cc:1871 commands.cc:1890 commands.cc:1909 commands.cc:1927
-#: commands.cc:1955
+#: commands.cc:1875 commands.cc:1894 commands.cc:1913 commands.cc:1931
+#: commands.cc:1959
 msgid "ID"
 msgstr "ID"

-#: commands.cc:1871
+#: commands.cc:1875
 msgid "write revision data packet to stdout"
 msgstr "skriv ut datapaket för revision till stdout"

-#: commands.cc:1890
+#: commands.cc:1894
 msgid "write file data packet to stdout"
 msgstr "skriv ut datapaket för fil till stdout"

-#: commands.cc:1909
+#: commands.cc:1913
 msgid "write cert packets to stdout"
 msgstr "skriv ut datapaket för cert till stdout"

-#: commands.cc:1927
+#: commands.cc:1931
 msgid "write public key packet to stdout"
 msgstr "skriv it datapaket för publik nyckel till stdout"

-#: commands.cc:1949
+#: commands.cc:1953
 #, c-format
 msgid "public key '%s' does not exist"
 msgstr "den publika nyckeln '%s' finns inte"

-#: commands.cc:1955
+#: commands.cc:1959
 msgid "write private key packet to stdout"
 msgstr "skriv it datapaket för privat nyckel till stdout"

-#: commands.cc:1963
+#: commands.cc:1967
 #, c-format
 msgid "public and private key '%s' do not exist in keystore"
 msgstr "den publika och privata nyckeln '%s' finns inte i nyckellagret"

-#: commands.cc:1974
+#: commands.cc:1978
 msgid "read packets from files or stdin"
 msgstr "läs paket från filer eller stdin"

-#: commands.cc:1982
+#: commands.cc:1986
 #, c-format
 msgid "no packets found on stdin"
 msgstr "inga paket hittade i stdin"

-#: commands.cc:1993
+#: commands.cc:1997
 #, c-format
 msgid "no packets found in given file"
 msgid_plural "no packets found in given files"
 msgstr[0] "inga paket funna i den angivna filen"
 msgstr[1] "inga paket funna i de angivna filerna"

-#: commands.cc:1997
+#: commands.cc:2001
 #, c-format
 msgid "read %d packet"
 msgid_plural "read %d packets"
 msgstr[0] "läste %d paket"
 msgstr[1] "läste %d paket"

-#: commands.cc:2026
+#: commands.cc:2030
 #, c-format
 msgid "setting default server to %s\n"
 msgstr "sätter standardserver till %s\n"

-#: commands.cc:2032
+#: commands.cc:2036
 #, c-format
 msgid "no hostname given"
 msgstr "inget värdnamn angivet"

-#: commands.cc:2034
+#: commands.cc:2038
 #, c-format
 msgid "no server given and no default server set"
 msgstr "ingen server angiven och ingen standardserver är satt"

-#: commands.cc:2052
+#: commands.cc:2056
 #, c-format
 msgid "setting default branch include pattern to '%s'\n"
 msgstr "sätter standardmönstret för grenar att ta med till '%s'\n"

-#: commands.cc:2058
+#: commands.cc:2062
 #, c-format
 msgid "setting default branch exclude pattern to '%s'\n"
 msgstr "sätter standardmönstret för grenar att INTE ta med till '%s'\n"

-#: commands.cc:2064
+#: commands.cc:2068
 #, c-format
 msgid "no branch pattern given"
 msgstr "inget grenmönster angivet"

-#: commands.cc:2066
+#: commands.cc:2070
 #, c-format
 msgid "no branch pattern given and no default pattern set"
 msgstr "inget grenmönster angivet och inget standardmönster satt"

-#: commands.cc:2082 commands.cc:2097 commands.cc:2111 commands.cc:2126
+#: commands.cc:2086 commands.cc:2101 commands.cc:2115 commands.cc:2130
 msgid "network"
 msgstr "nätverk"

-#: commands.cc:2082 commands.cc:2097 commands.cc:2111
+#: commands.cc:2086 commands.cc:2101 commands.cc:2115
 msgid "[ADDRESS[:PORTNUMBER] [PATTERN]]"
 msgstr "[ADRESS[:PORTNUMMER] [MÖNSTER]]"

-#: commands.cc:2083
+#: commands.cc:2087
 msgid "push branches matching PATTERN to netsync server at ADDRESS"
 msgstr "skicka grenar som matchar MÖNSTER till netsync-server på ADRESS"

-#: commands.cc:2098
+#: commands.cc:2102
 msgid "pull branches matching PATTERN from netsync server at ADDRESS"
 msgstr "hämta grenar som matchar MÖNSTER till netsync-server på ADRESS"

-#: commands.cc:2105
+#: commands.cc:2109
 #, c-format
 msgid "doing anonymous pull; use -kKEYNAME if you need authentication\n"
 msgstr "hämtar anonymt; använd -kNYCKELNAMN om du behöver autentisera\n"

-#: commands.cc:2112
+#: commands.cc:2116
 msgid "sync branches matching PATTERN with netsync server at ADDRESS"
 msgstr "synkronisera grenar som matchar MÖNSTER till netsync-server på ADRESS"

-#: commands.cc:2126
+#: commands.cc:2130
 msgid "PATTERN ..."
 msgstr "MÖNSTER ..."

-#: commands.cc:2127
+#: commands.cc:2131
 msgid "serve the branches specified by PATTERNs to connecting clients"
 msgstr "servera de grenar som matchar MÖNSTER till anslutande klienter"

-#: commands.cc:2140
+#: commands.cc:2144
 #, c-format
 msgid ""
 "need permission to store persistent passphrase (see hook persist_phrase_ok())"
@@ -975,11 +975,11 @@ msgstr ""
 "behöver tillstånd att använda ett permanent lösenord (se lua-rutinen\n"
 "persist_phrase_ok())"

-#: commands.cc:2152
+#: commands.cc:2156
 msgid "database"
 msgstr "databas"

-#: commands.cc:2153
+#: commands.cc:2157
 msgid ""
 "init\n"
 "info\n"
@@ -1011,11 +1011,11 @@ msgstr ""
 "rosterify\n"
 "set_epoch GREN EPOK\n"

-#: commands.cc:2167
+#: commands.cc:2171
 msgid "manipulate database state"
 msgstr "gör ändringar direkt i databasen"

-#: commands.cc:2220
+#: commands.cc:2224
 msgid ""
 "set PATH ATTR VALUE\n"
 "get PATH [ATTR]\n"
@@ -1025,41 +1025,41 @@ msgstr ""
 "get SÖKVÄG [ATTR]\n"
 "drop SÖKVÄG [ATTR]"

-#: commands.cc:2221
+#: commands.cc:2225
 msgid "set, get or drop file attributes"
 msgstr "sätt, hämta eller ta bort attribut"

-#: commands.cc:2237
+#: commands.cc:2241
 #, c-format
 msgid "Unknown path '%s'"
 msgstr "Okänd sökväg '%s'"

-#: commands.cc:2266
+#: commands.cc:2270
 #, c-format
 msgid "Path '%s' does not have attribute '%s'\n"
 msgstr "Sökvägen '%s' har inget attribut '%s'\n"

-#: commands.cc:2320
+#: commands.cc:2324
 #, c-format
 msgid "--message and --message-file are mutually exclusive"
 msgstr "--message och --message-file får inte anges samtidigt"

-#: commands.cc:2340
+#: commands.cc:2343
 #, fuzzy
 msgid "commit workspace to database"
 msgstr "arkivera arbetskopian i databasen"

-#: commands.cc:2358
+#: commands.cc:2361
 #, c-format
 msgid "no changes to commit\n"
 msgstr "inga ändringar att arkivera\n"

-#: commands.cc:2372
+#: commands.cc:2375
 #, c-format
 msgid "beginning commit on branch '%s'\n"
 msgstr "börjar arkivering av ändringar i grenen '%s'\n"

-#: commands.cc:2381
+#: commands.cc:2384
 #, c-format
 msgid ""
 "MT/log is non-empty and log message was specified on command line\n"
@@ -1070,27 +1070,32 @@ msgstr ""
 "kanske ta bort eller flytta på MT/log\n"
 "eller ta bort --message/--message-file från kommandoraden?"

-#: commands.cc:2393
+#: commands.cc:2396
 #, c-format
 msgid "empty log message; commit canceled"
 msgstr "tomt loggmeddelande; arkivering avbryts"

-#: commands.cc:2410
+#: commands.cc:2415
 #, c-format
+msgid "log message rejected: %s\n"
+msgstr "loggmeddelandet förkastas: %s\n"
+
+#: commands.cc:2423
+#, c-format
 msgid "revision %s already in database\n"
 msgstr "revisionen %s finns redan i databasen\n"

-#: commands.cc:2448 commands.cc:2465 commands.cc:2484
+#: commands.cc:2461 commands.cc:2478 commands.cc:2497
 #, c-format
 msgid "file '%s' modified during commit, aborting"
 msgstr "filen '%s' ändrades under arkivering, avbryter"

-#: commands.cc:2510
+#: commands.cc:2523
 #, c-format
 msgid "committed revision %s\n"
 msgstr "arkiverade revisionen %s\n"

-#: commands.cc:2516
+#: commands.cc:2529
 #, c-format
 msgid ""
 "note: this revision creates divergence\n"
@@ -1099,7 +1104,7 @@ msgstr ""
 "obs: den här revisionen skapade divergens\n"
 "obs: du kan tänkas vilja (eller kanske inte) köra 'monotone merge'"

-#: commands.cc:2710
+#: commands.cc:2723
 #, fuzzy
 msgid ""
 "show current diffs on stdout.\n"
@@ -1112,7 +1117,7 @@ msgstr ""
 "revisionen. Om två revisioner anges visas skillnaden mellan dem. Om\n"
 "inget format anges används unified."

-#: commands.cc:2726
+#: commands.cc:2739
 #, c-format
 msgid ""
 "--diff-args requires --external\n"
@@ -1121,16 +1126,16 @@ msgstr ""
 "--diff-args kräver att även --external anges\n"
 "lägg till --external eller ta bort --diff-args?"

-#: commands.cc:2768
+#: commands.cc:2781
 #, c-format
 msgid "current revision has no ancestor"
 msgstr "denna revision har ingen förälder"

-#: commands.cc:2831
+#: commands.cc:2844
 msgid "no changes"
 msgstr "inga ändringar"

-#: commands.cc:2863
+#: commands.cc:2876
 #, fuzzy
 msgid ""
 "update workspace.\n"
@@ -1145,12 +1150,12 @@ msgstr ""
 "Om en revision har angivits så uppdateras arbetskopian till den,\n"
 "i annat fall uppdateras den till lövet i grenen."

-#: commands.cc:2901
+#: commands.cc:2914
 #, fuzzy, c-format
 msgid "this workspace is a new project; cannot update"
 msgstr "denna arbetskatalog är ett nytt projekt; kan inte uppdatera"

-#: commands.cc:2908
+#: commands.cc:2921
 #, c-format
 msgid ""
 "your request matches no descendents of the current revision\n"
@@ -1161,32 +1166,32 @@ msgstr ""
 "faktum är att den inte ens matchar nuvarande revision\n"
 "du kanske vill ange --revision=<revision i annan gren>"

-#: commands.cc:2913
+#: commands.cc:2926
 #, c-format
 msgid "multiple update candidates:\n"
 msgstr "mer än en uppdateringskandidat:\n"

-#: commands.cc:2917
+#: commands.cc:2930
 #, c-format
 msgid "choose one with 'monotone update -r<id>'\n"
 msgstr "välj en med 'monotone update -r<id>'\n"

-#: commands.cc:2918
+#: commands.cc:2931
 #, c-format
 msgid "multiple candidates remain after selection"
 msgstr "mer än en kandidat efter urval"

-#: commands.cc:2933
+#: commands.cc:2946
 #, c-format
 msgid "already up to date at %s\n"
 msgstr "redan uppdaterad till %s\n"

-#: commands.cc:2941
+#: commands.cc:2954
 #, c-format
 msgid "selected update target %s\n"
 msgstr "valt uppdateringsmål är %s\n"

-#: commands.cc:2953
+#: commands.cc:2966
 #, c-format
 msgid ""
 "revision %s is not a member of branch %s\n"
@@ -1195,140 +1200,140 @@ msgstr ""
 "revisionen %s är inte i grenen %s\n"
 "försök igen med en explicit --branch\n"

-#: commands.cc:3053
+#: commands.cc:3066
 #, c-format
 msgid "updated to base revision %s\n"
 msgstr "uppdaterad till revisionen %s\n"

-#: commands.cc:3063
+#: commands.cc:3076
 msgid "merge unmerged heads of branch"
 msgstr "slå ihop ej ihopslagna löv i grenen"

-#: commands.cc:3077
+#: commands.cc:3090
 #, c-format
 msgid "branch '%s' is merged\n"
 msgstr "löven i grenen '%s' är ihopslagna\n"

-#: commands.cc:3083
+#: commands.cc:3096
 #, c-format
 msgid "starting with revision 1 / %d\n"
 msgstr "börjar med revision 1 av %d\n"

-#: commands.cc:3087
+#: commands.cc:3100
 #, c-format
 msgid "merging with revision %d / %d\n"
 msgstr "slår ihop med revision %d av %d\n"

-#: commands.cc:3088 commands.cc:3089 commands.cc:3156 commands.cc:3231
-#: commands.cc:3232
+#: commands.cc:3101 commands.cc:3102 commands.cc:3169 commands.cc:3244
+#: commands.cc:3245
 #, c-format
 msgid "[source] %s\n"
 msgstr "[källa]      %s\n"

-#: commands.cc:3106 commands.cc:3197 commands.cc:3250
+#: commands.cc:3119 commands.cc:3210 commands.cc:3263
 #, c-format
 msgid "[merged] %s\n"
 msgstr "[ihopslagen] %s\n"

-#: commands.cc:3109
+#: commands.cc:3122
 #, fuzzy, c-format
 msgid "note: your workspaces have not been updated\n"
 msgstr "obs: dina arbetskopior har inte uppdaterats\n"

-#: commands.cc:3112
+#: commands.cc:3125
 msgid "SOURCE-BRANCH DEST-BRANCH"
 msgstr "KÄLLGREN MÅLGREN"

-#: commands.cc:3113
+#: commands.cc:3126
 msgid "merge from one branch to another asymmetrically"
 msgstr "slå ihop asymmetriskt från en gren till en annan"

-#: commands.cc:3147 commands.cc:3150
+#: commands.cc:3160 commands.cc:3163
 #, c-format
 msgid "branch '%s' is not merged\n"
 msgstr "löven i grenen '%s' är inte ihopslagna\n"

-#: commands.cc:3155
+#: commands.cc:3168
 #, c-format
 msgid "propagating %s -> %s\n"
 msgstr "propagerar %s -> %s\n"

-#: commands.cc:3157
+#: commands.cc:3170
 #, c-format
 msgid "[target] %s\n"
 msgstr "[mål]        %s\n"

-#: commands.cc:3162
+#: commands.cc:3175
 #, c-format
 msgid "branch '%s' is up-to-date with respect to branch '%s'\n"
 msgstr "grenen '%s' är uppdaterad med avseende på grenen '%s'\n"

-#: commands.cc:3164
+#: commands.cc:3177
 #, c-format
 msgid "no action taken\n"
 msgstr "inget utfördes\n"

-#: commands.cc:3168
+#: commands.cc:3181
 #, c-format
 msgid "no merge necessary; putting %s in branch '%s'\n"
 msgstr "ingen ihopslagning behövs; sätter %s i grenen '%s'\n"

-#: commands.cc:3201
+#: commands.cc:3214
 msgid "refresh the inodeprint cache"
 msgstr "uppdatera inodeprint-cachen"

-#: commands.cc:3209
+#: commands.cc:3222
 msgid "LEFT-REVISION RIGHT-REVISION DEST-BRANCH"
 msgstr "VÄNSTERREVISION HÖGERREVISION MÅLGREN"

-#: commands.cc:3210
+#: commands.cc:3223
 msgid "merge two explicitly given revisions, placing result in given branch"
 msgstr ""
 "slå ihop två explicit angivna revisioner, placera resultatet i angiven gren"

-#: commands.cc:3224
+#: commands.cc:3237
 #, c-format
 msgid "%s and %s are the same revision, aborting"
 msgstr "%s och %s är samma revision, avbryter"

-#: commands.cc:3226 commands.cc:3228
+#: commands.cc:3239 commands.cc:3241
 #, c-format
 msgid "%s is already an ancestor of %s"
 msgstr "%s är redan förfader till %s"

-#: commands.cc:3253
+#: commands.cc:3266
 msgid "(revision|file|key) PARTIAL-ID"
 msgstr "(revision|file|key) PARTIAL-ID"

-#: commands.cc:3254
+#: commands.cc:3267
 msgid "complete partial id"
 msgstr "utöka den partiella identiteten"

-#: commands.cc:3263
+#: commands.cc:3276
 #, c-format
 msgid "non-hex digits in partial id"
 msgstr "något tecken i den partiella identiteten är inte hexadecimalt"

-#: commands.cc:3302
+#: commands.cc:3315
 #, fuzzy
 msgid "revert file(s), dir(s) or entire workspace (\".\")"
 msgstr "återställ fil(er), katalog(er) eller hela arbetskopian (\".\")"

-#: commands.cc:3379
+#: commands.cc:3392
 #, c-format
 msgid "reverting %s"
 msgstr "återställer %s"

-#: commands.cc:3383
+#: commands.cc:3396
 #, c-format
 msgid "no file version %s found in database for %s"
 msgstr "filversionen %s finns inte i databasen för %s"

-#: commands.cc:3404
+#: commands.cc:3417
 msgid "RCSFILE..."
 msgstr "RCSFIL..."

-#: commands.cc:3405
+#: commands.cc:3418
 msgid ""
 "parse versions in RCS files\n"
 "this command doesn't reconstruct or import revisions.you probably want "
@@ -1338,36 +1343,36 @@ msgstr ""
 "detta kommando importerar inte revisioner; du vill antagligen använda\n"
 "cvs_import"

-#: commands.cc:3421
+#: commands.cc:3434
 msgid "rcs"
 msgstr "rcs"

-#: commands.cc:3421
+#: commands.cc:3434
 msgid "CVSROOT"
 msgstr "CVSROOT"

-#: commands.cc:3421
+#: commands.cc:3434
 msgid "import all versions in CVS repository"
 msgstr "importera alla revisioner i ett CVS-arkiv"

-#: commands.cc:3484
+#: commands.cc:3497
 msgid "PATH"
 msgstr "SÖKVÄG"

-#: commands.cc:3485
+#: commands.cc:3498
 msgid "print annotated copy of the file from REVISION"
 msgstr "skriv ut filen ur REVISION med extra detaljer"

-#: commands.cc:3505
+#: commands.cc:3518
 #, c-format
 msgid "no revision for file '%s' in database"
 msgstr "filen '%s' har ingen revision i databasen"

-#: commands.cc:3523
+#: commands.cc:3536
 msgid "[FILE] ..."
 msgstr "[FIL] ..."

-#: commands.cc:3524
+#: commands.cc:3537
 msgid ""
 "print history in reverse order (filtering by 'FILE'). If one or more\n"
 "revisions are given, use them as a starting point."
@@ -1376,35 +1381,35 @@ msgstr ""
 "arbetskatalogen om inga filer angivits. Om en eller flera revisioner\n"
 "har angivits används de som utgångspunkter."

-#: commands.cc:3571
+#: commands.cc:3584
 #, c-format
 msgid "Unknown file '%s' for log command"
 msgstr "Okänd fil '%s'"

-#: commands.cc:3589
+#: commands.cc:3602
 #, c-format
 msgid "only one of --last/--next allowed"
 msgstr "enbart en av --last eller --next tillåten"

-#: commands.cc:3757
+#: commands.cc:3770
 msgid "[DIRECTORY]"
 msgstr "[KATALOG]"

-#: commands.cc:3757
+#: commands.cc:3770
 #, fuzzy
 msgid "setup a new workspace directory, default to current"
 msgstr "initiera en ny arbetskatalog (nuvarande om katalog ej anges)"

-#: commands.cc:3763
+#: commands.cc:3776
 #, c-format
 msgid "need --branch argument for setup"
 msgstr "du måste ange en gren med --branch till kommandot \"setup\""

-#: commands.cc:3777
+#: commands.cc:3790
 msgid "automation"
 msgstr "automatisering"

-#: commands.cc:3778
+#: commands.cc:3791
 msgid ""
 "interface_version\n"
 "heads [BRANCH]\n"
@@ -1448,40 +1453,40 @@ msgstr ""
 "get_revision [REVID]\n"
 "keys\n"

-#: commands.cc:3798
+#: commands.cc:3811
 msgid "automation interface"
 msgstr "automatiseringsgränssnitt"

-#: commands.cc:3812 commands.cc:3828
+#: commands.cc:3825 commands.cc:3841
 msgid "vars"
 msgstr "variabler"

-#: commands.cc:3812
+#: commands.cc:3825
 msgid "DOMAIN NAME VALUE"
 msgstr "DOMÄN NAMN VÄRDE"

-#: commands.cc:3813
+#: commands.cc:3826
 msgid "set the database variable NAME to VALUE, in domain DOMAIN"
 msgstr "sätt databasvariabeln NAMN till VÄRDE i domänen DOMÄN"

-#: commands.cc:3828
+#: commands.cc:3841
 msgid "DOMAIN NAME"
 msgstr "DOMÄN NAMN"

-#: commands.cc:3829
+#: commands.cc:3842
 msgid "remove the database variable NAME in domain DOMAIN"
 msgstr "ta bort databasvariabeln NAMN från domänen DOMÄN"

-#: commands.cc:3840
+#: commands.cc:3853
 #, c-format
 msgid "no var with name %s in domain %s"
 msgstr "det finns inga variabler med namnet %s i domänen %s"

-#: commands.cc:3844
+#: commands.cc:3857
 msgid "REVID"
 msgstr "REVID"

-#: commands.cc:3845
+#: commands.cc:3858
 msgid "dump the roster associated with the given REVID"
 msgstr "skriv ut den roster som hör ihop med angivet REVID"

@@ -1497,7 +1502,7 @@ msgstr "markeringar"
 msgid "markings"
 msgstr "markeringar"

-#: database_check.cc:319 database_check.cc:507 netsync.cc:2707
+#: database_check.cc:319 database_check.cc:507 netsync.cc:2719
 #: rcs_import.cc:1226
 msgid "revisions"
 msgstr "revisioner"
@@ -1506,7 +1511,7 @@ msgstr "föräldraskap"
 msgid "ancestry"
 msgstr "föräldraskap"

-#: database_check.cc:451 netsync.cc:2711
+#: database_check.cc:451 netsync.cc:2723
 msgid "keys"
 msgstr "nycklar"

@@ -1870,7 +1875,7 @@ msgstr "kan inte skapa %s; den finns red
 msgid "cannot create %s; it already exists"
 msgstr "kan inte skapa %s; den finns redan"

-#: database.cc:515
+#: database.cc:511
 #, c-format
 msgid ""
 "schema version    : %s\n"
@@ -1911,52 +1916,52 @@ msgstr ""
 "  cert                : %u\n"
 "  total               : %u\n"

-#: database.cc:569
+#: database.cc:565
 #, c-format
 msgid "database schema version: %s"
 msgstr "databasens schemaversion: %s"

-#: database.cc:646
+#: database.cc:642
 #, c-format
 msgid "multiple statements in query: %s\n"
 msgstr "multipla kommandon i databasfråga: %s\n"

-#: database.cc:652
+#: database.cc:648
 #, c-format
 msgid "wanted %d columns got %d in query: %s\n"
 msgstr "ville ha %d kolumner, fick %d i databasfråga: %s\n"

-#: database.cc:710
+#: database.cc:706
 #, c-format
 msgid "null result in query: %s\n"
 msgstr "inget resultat med databasfråga: %s\n"

-#: database.cc:728
+#: database.cc:724
 #, c-format
 msgid "wanted %d rows got %s in query: %s\n"
 msgstr "ville ha %d rader, fick %s i databasfråga: %s\n"

-#: database.cc:1775
+#: database.cc:1771
 #, c-format
 msgid "another key with name '%s' already exists"
 msgstr "det finns redan en annan nyckel med namnet '%s'"

-#: database.cc:2819
+#: database.cc:2815
 #, c-format
 msgid "no database specified"
 msgstr "ingen databas angiven"

-#: database.cc:2827
+#: database.cc:2823
 #, c-format
 msgid "database %s does not exist"
 msgstr "databasen %s finns inte"

-#: database.cc:2828
+#: database.cc:2824
 #, c-format
 msgid "%s is a directory, not a database"
 msgstr "%s är en katalog, inte en databas"

-#: database.cc:2853
+#: database.cc:2849
 #, c-format
 msgid "could not open database '%s': %s"
 msgstr "kunde inte öppna databasen '%s': %s"
@@ -2180,37 +2185,37 @@ msgstr "lösen för '%s' stämmer inte"
 msgid "passphrase for '%s' is incorrect"
 msgstr "lösen för '%s' stämmer inte"

-#: lua.cc:538 lua.cc:567 lua.cc:582
+#: lua.cc:539 lua.cc:568 lua.cc:583
 #, c-format
 msgid "%s called with an invalid parameter"
 msgstr "%s anropades med inkorrekt parameter"

-#: lua.cc:585
+#: lua.cc:586
 #, c-format
 msgid "Directory '%s' does not exists"
 msgstr "Katalogen '%s' finns inte"

-#: lua.cc:586 rcs_import.cc:1217
+#: lua.cc:587 rcs_import.cc:1217
 #, c-format
 msgid "'%s' is not a directory"
 msgstr "'%s' är inte en katalog"

-#: lua.cc:605 lua.cc:907
+#: lua.cc:606 lua.cc:908
 #, c-format
 msgid "lua error while loading rcfile '%s'"
 msgstr "lua-fel vid läsning av rcfilen '%s'"

-#: lua.cc:704
+#: lua.cc:705
 #, c-format
 msgid "bad input to parse_basic_io"
 msgstr "felaktigt indata till parse_basic_io"

-#: lua.cc:919
+#: lua.cc:920
 #, c-format
 msgid "lua error while loading '%s'"
 msgstr "lua-fel vid läsning av '%s'"

-#: lua.cc:924
+#: lua.cc:925
 #, c-format
 msgid "rcfile '%s' does not exist"
 msgstr "rcfilen '%s' finns inte"
@@ -2618,28 +2623,33 @@ msgstr "nekade försök att ansluta anon
 msgid "rejected attempt at anonymous connection while running as sink\n"
 msgstr "nekade försök att ansluta anonymt under körning som \"sink\"\n"

-#: netsync.cc:1325
+#: netsync.cc:1323 netsync.cc:1420
 #, c-format
+msgid "not serving branch '%s'"
+msgstr "serverar ej grenen %s"
+
+#: netsync.cc:1328
+#, c-format
 msgid "anonymous access to branch '%s' denied by server"
 msgstr "anonym åtkomst av grenen '%s' nekades av servern"

-#: netsync.cc:1330
+#: netsync.cc:1335
 #, c-format
 msgid "allowed anonymous read permission for '%s' excluding '%s'\n"
 msgstr "tillät anonym läsning av alla grenar som matchar '%s' och inte '%s'\n"

-#: netsync.cc:1362
+#: netsync.cc:1367
 #, c-format
 msgid "detected replay attack in auth netcmd\n"
 msgstr "upptäckte \"replay\"-attack i auth netcmd\n"

-#: netsync.cc:1384
+#: netsync.cc:1389
 #, c-format
 msgid "remote public key hash '%s' is unknown\n"
 msgstr ""
 "publik nyckel med kontrollsumman '%s' som kommer från andra sidan är okänd\n"

-#: netsync.cc:1401
+#: netsync.cc:1406
 #, c-format
 msgid ""
 "denied '%s' read permission for '%s' excluding '%s' while running as pure "
@@ -2648,7 +2658,7 @@ msgstr ""
 "nekade läsning för '%s' av alla grenar som matchar '%s' och inte '%s' under "
 "körning som \"pure sink\"\n"

-#: netsync.cc:1417
+#: netsync.cc:1426
 #, c-format
 msgid ""
 "denied '%s' read permission for '%s' excluding '%s' because of branch '%s'\n"
@@ -2656,18 +2666,18 @@ msgstr ""
 "nekade läsning för '%s' av alla grenar som matchar '%s' och inte '%s' på "
 "grund av grenen '%s'\n"

-#: netsync.cc:1419
+#: netsync.cc:1429
 #, c-format
 msgid "access to branch '%s' denied by server"
 msgstr "åtkomst till grenen '%s' nekades av servern"

-#: netsync.cc:1427
+#: netsync.cc:1439
 #, c-format
 msgid "allowed '%s' read permission for '%s' excluding '%s'\n"
 msgstr ""
 "tillät läsning för '%s' av alla grenar som matchar '%s' och inte '%s'\n"

-#: netsync.cc:1436
+#: netsync.cc:1448
 #, c-format
 msgid ""
 "denied '%s' write permission for '%s' excluding '%s' while running as pure "
@@ -2676,165 +2686,165 @@ msgstr ""
 "nekade skrivning för '%s' av alla grenar som matchar '%s' och inte '%s' "
 "under körning som \"pure source\"\n"

-#: netsync.cc:1444
+#: netsync.cc:1456
 #, c-format
 msgid "denied '%s' write permission for '%s' excluding '%s'\n"
 msgstr ""
 "nekade skrivning för '%s' av alla grenar som matchar '%s' och inte '%s'\n"

-#: netsync.cc:1450
+#: netsync.cc:1462
 #, c-format
 msgid "allowed '%s' write permission for '%s' excluding '%s'\n"
 msgstr ""
 "tillät skrivning för '%s' av alla grenar som matchar '%s' och inte '%s'\n"

-#: netsync.cc:1490
+#: netsync.cc:1502
 #, c-format
 msgid "bad client signature\n"
 msgstr "felaktig signatur från klienten\n"

-#: netsync.cc:1506
+#: netsync.cc:1518
 #, c-format
 msgid "Unexpected 'refine' command on non-refined item type\n"
 msgstr "Oväntat kommando \"refine\" på icke-raffinerad typ\n"

-#: netsync.cc:1603
+#: netsync.cc:1615
 #, c-format
 msgid "unknown bye phase %d received"
 msgstr "okänd hejdå-fas %d mottagen"

-#: netsync.cc:1615
+#: netsync.cc:1627
 #, c-format
 msgid "Unexpected 'done' command on non-refined item type\n"
 msgstr "Oväntat kommando \"done\" på icke-raffinerad typ\n"

-#: netsync.cc:1695
+#: netsync.cc:1707
 #, c-format
 msgid "epoch with hash '%s' does not exist in our database"
 msgstr "epoken med kontrollsumman '%s' finns inte i databasen"

-#: netsync.cc:1724
+#: netsync.cc:1736
 #, c-format
 msgid "revision '%s' does not exist in our database"
 msgstr "revisionen '%s' finns inte i databasen"

-#: netsync.cc:1738
+#: netsync.cc:1750
 #, c-format
 msgid "file '%s' does not exist in our database"
 msgstr "filen '%s' finns inte i databasen"

-#: netsync.cc:1752
+#: netsync.cc:1764
 #, c-format
 msgid "cert '%s' does not exist in our database"
 msgstr "certet '%s' finns inte i databasen"

-#: netsync.cc:1804
+#: netsync.cc:1816
 #, c-format
 msgid "Mismatched epoch on branch %s. Server has '%s', client has '%s'."
 msgstr ""
 "I grenen %s har servern epok '%s' medan klienten har '%s'; dessa stämmer "
 "inte överens."

-#: netsync.cc:1825
+#: netsync.cc:1837
 #, c-format
 msgid "hash check failed for public key '%s' (%s); wanted '%s' got '%s'"
 msgstr ""
 "kontrollsummering misslyckades för den publika nyckeln '%s' (%s); ville ha '%"
 "s' men fick '%s'"

-#: netsync.cc:1842
+#: netsync.cc:1854
 #, c-format
 msgid "hash check failed for revision cert '%s'"
 msgstr "kontrollsummering misslyckades för revisionscertet '%s'"

-#: netsync.cc:1917
+#: netsync.cc:1929
 #, c-format
 msgid "Received warning from usher: %s"
 msgstr "Fick varning från usher: %s"

-#: netsync.cc:2004 netsync.cc:2035
+#: netsync.cc:2016 netsync.cc:2047
 msgid "source and sink"
 msgstr "källa och mottagare"

-#: netsync.cc:2005 netsync.cc:2036
+#: netsync.cc:2017 netsync.cc:2048
 msgid "source"
 msgstr "källa"

-#: netsync.cc:2005 netsync.cc:2036
+#: netsync.cc:2017 netsync.cc:2048
 msgid "sink"
 msgstr "mottagare"

-#: netsync.cc:2190
+#: netsync.cc:2202
 #, c-format
 msgid "input buffer for peer %s is overfull after netcmd dispatch\n"
 msgstr "indatabuffert för %s är överfull\n"

-#: netsync.cc:2202 netsync.cc:2259
+#: netsync.cc:2214 netsync.cc:2271
 #, c-format
 msgid "protocol error while processing peer %s: '%s'\n"
 msgstr "protokollfel vid behandling av %s: '%s'\n"

-#: netsync.cc:2208
+#: netsync.cc:2220
 #, c-format
 msgid "error: %s\n"
 msgstr "fel: %s\n"

-#: netsync.cc:2238
+#: netsync.cc:2250
 #, c-format
 msgid "connecting to %s\n"
 msgstr "ansluter till %s\n"

-#: netsync.cc:2274
+#: netsync.cc:2286
 #, c-format
 msgid "timed out waiting for I/O with peer %s, disconnecting\n"
 msgstr "att vänta på I/O från %s tog för lång tid, kopplar ifrån\n"

-#: netsync.cc:2289
+#: netsync.cc:2301
 #, c-format
 msgid "got OOB data from peer %s, disconnecting\n"
 msgstr "fick OOB-data från %s, kopplar ifrån\n"

-#: netsync.cc:2304
+#: netsync.cc:2316
 #, c-format
 msgid "processing failure while talking to peer %s, disconnecting\n"
 msgstr "tar hand om misslyckande i samtal med %s, kopplar ifrån\n"

-#: netsync.cc:2321
+#: netsync.cc:2333
 #, c-format
 msgid "successful exchange with %s\n"
 msgstr "lyckat utbyte med %s\n"

-#: netsync.cc:2327
+#: netsync.cc:2339
 #, c-format
 msgid "peer %s disconnected after we informed them of error\n"
 msgstr "%s kopplade ifrån efter att vi informerade den om ett fel\n"

-#: netsync.cc:2332
+#: netsync.cc:2344
 #, c-format
 msgid "I/O failure while talking to peer %s, disconnecting\n"
 msgstr "I/O-fel i samtal med %s, kopplar ifrån\n"

-#: netsync.cc:2361
+#: netsync.cc:2373
 #, c-format
 msgid "protocol error while processing peer %s: '%s', marking as bad\n"
 msgstr "protokollfel i samtal med %s: '%s', markerar det som felaktigt\n"

-#: netsync.cc:2393
+#: netsync.cc:2405
 #, c-format
 msgid "accepted new client connection from %s : %s\n"
 msgstr "tar emot ny klientanslutning från %s: %s\n"

-#: netsync.cc:2427
+#: netsync.cc:2439
 #, c-format
 msgid "protocol error while processing peer %s: '%s', disconnecting\n"
 msgstr "protokollfel i samtal med %s: '%s', kopplar ifrån\n"

-#: netsync.cc:2438
+#: netsync.cc:2450
 #, c-format
 msgid "peer %s read failed in working state (error)\n"
 msgstr "läsning från %s fallerade i tillståndet \"working\" (fel)\n"

-#: netsync.cc:2443
+#: netsync.cc:2455
 #, c-format
 msgid ""
 "peer %s read failed in shutdown state (possibly client misreported error)\n"
@@ -2842,17 +2852,17 @@ msgstr ""
 "läsning från %s fallerade i tillståndet \"shutdown\" (klienten kan felaktigt "
 "ha rapporterat ett fel)\n"

-#: netsync.cc:2449
+#: netsync.cc:2461
 #, c-format
 msgid "peer %s read failed in confirmed state (success)\n"
 msgstr "läsning från %s fallerade i tillståndet \"confirmed\" (framgång)\n"

-#: netsync.cc:2470
+#: netsync.cc:2482
 #, c-format
 msgid "peer %s write failed in working state (error)\n"
 msgstr "skrivning till %s fallerade i tillståndet \"working\" (fel)\n"

-#: netsync.cc:2475
+#: netsync.cc:2487
 #, c-format
 msgid ""
 "peer %s write failed in shutdown state (possibly client misreported error)\n"
@@ -2860,68 +2870,68 @@ msgstr ""
 "skrivning till %s fallerade i tillståndet \"shutdown\" (klienten kan "
 "felaktigt ha rapporterat ett fel)\n"

-#: netsync.cc:2481
+#: netsync.cc:2493
 #, c-format
 msgid "peer %s write failed in confirmed state (success)\n"
 msgstr "skrivning till %s fallerade i tillståndet \"confirmed\" (framgång)\n"

-#: netsync.cc:2508
+#: netsync.cc:2520
 #, c-format
 msgid "peer %s processing finished, disconnecting\n"
 msgstr "behandling av %s slutförd, kopplar ifrån\n"

-#: netsync.cc:2530
+#: netsync.cc:2542
 #, c-format
 msgid "fd %d (peer %s) has been idle too long, disconnecting\n"
 msgstr "fd %d (%s) har varit inaktiv för länge, kopplar ifrån\n"

-#: netsync.cc:2576
+#: netsync.cc:2588
 #, c-format
 msgid "beginning service on %s : %s\n"
 msgstr "startar tjänst på %s : %s\n"

-#: netsync.cc:2591
+#: netsync.cc:2603
 #, c-format
 msgid "session limit %d reached, some connections will be refused\n"
 msgstr ""
 "gränsen för antalet sessioner, %d, är nådd, en del uppkopplingar kommer att "
 "nekas\n"

-#: netsync.cc:2646
+#: netsync.cc:2658
 #, c-format
 msgid "got OOB from peer %s, disconnecting\n"
 msgstr "fick OOB-data från %s, kopplar ifrån\n"

-#: netsync.cc:2701
+#: netsync.cc:2713
 #, c-format
 msgid "finding items to synchronize:\n"
 msgstr "letar efter saker att synkronisera:\n"

-#: netsync.cc:2709
+#: netsync.cc:2721
 msgid "certificates"
 msgstr "certifikat"

-#: netsync.cc:2818
+#: netsync.cc:2830
 #, c-format
 msgid "Cannot find key '%s'"
 msgstr "Kan inte hitta nyckeln '%s'"

-#: netsync.cc:2858
+#: netsync.cc:2870
 #, c-format
 msgid "include branch pattern contains a quote character:\n"
 msgstr "grenmönstret givet med --include innehåller ett citattecken\n"

-#: netsync.cc:2859 netsync.cc:2865
+#: netsync.cc:2871 netsync.cc:2877
 #, c-format
 msgid "%s\n"
 msgstr "%s\n"

-#: netsync.cc:2864
+#: netsync.cc:2876
 #, c-format
 msgid "exclude branch pattern contains a quote character:\n"
 msgstr "grenmönstret givet med --exclude innehåller ett citattecken\n"

-#: netsync.cc:2887 netsync.cc:2891
+#: netsync.cc:2899 netsync.cc:2903
 #, c-format
 msgid "network error: %s"
 msgstr "nätverksfel: %s"
@@ -3330,125 +3340,129 @@ msgstr "felaktig HMAC-längd, %d byte"
 msgstr "felaktig HMAC-längd, %d byte"

 #: work.cc:117
-#, c-format
-msgid "skipping ignorable file %s\n"
-msgstr "hoppar över ignorerbar fil %s\n"
-
-#: work.cc:125
 #, fuzzy, c-format
-msgid "skipping %s, already accounted for in workspace\n"
-msgstr "hoppar över %s, den finns redan noterad i arbetskopian\n"
+msgid "skipping ignorable file %s"
+msgstr "hoppar över ignorerbar fil %s"

-#: work.cc:129
+#: work.cc:126
 #, fuzzy, c-format
-msgid "adding %s to workspace add set\n"
-msgstr "lägger till %s i mängden tillagda filer i arbetskopian\n"
+msgid "skipping %s, already accounted for in workspace"
+msgstr "hoppar över %s, den finns redan noterad i arbetskopian"

-#: work.cc:202
+#: work.cc:130
 #, c-format
-msgid "skipping %s, not currently tracked\n"
-msgstr "hoppar över %s, ej noterad i arbetskopian\n"
+msgid "adding %s to workspace manifest"
+msgstr "lägger till %s i arbetskopians manifest"

-#: work.cc:210
+#: work.cc:203
+#, fuzzy, c-format
+msgid "skipping %s, not currently tracked"
+msgstr "hoppar över %s, ej noterad i arbetskopian"
+
+#: work.cc:211
 #, c-format
 msgid "cannot remove %s/, it is not empty"
 msgstr "kan inte ta bort %s/, den är inte tom"

-#: work.cc:212
+#: work.cc:213
 #, fuzzy, c-format
-msgid "adding %s to workspace delete set\n"
-msgstr "lägger till %s i mängden borttagna filer i arbetskopian\n"
+msgid "dropping %s from workspace manifest"
+msgstr "tar bort %s från arbetskopians manifest"

-#: work.cc:269
+#: work.cc:270
 #, c-format
 msgid "destination dir %s/ does not exist in current revision"
 msgstr "målkatalogen %s/ finns inte i nuvarande revision"

-#: work.cc:272
+#: work.cc:273
 #, c-format
 msgid "destination %s is an existing file in current revision"
 msgstr "målet %s är en existerande fil i nuvarande revision"

-#: work.cc:282
+#: work.cc:283
 #, c-format
 msgid "empty path %s is not allowed"
 msgstr "tom sökväg %s ej tillåten"

-#: work.cc:296
+#: work.cc:297
 #, c-format
 msgid "%s does not exist in current revision"
 msgstr "%s finns inte i nuvarande revision"

-#: work.cc:299
+#: work.cc:300
 #, c-format
 msgid "destination %s already exists in current revision"
 msgstr "målet %s finns redan i nuvarande revision"

-#: work.cc:308
+#: work.cc:309
 #, fuzzy, c-format
-msgid "adding %s -> %s to workspace rename set"
-msgstr "lägger till %s -> %s i mängden filer med ändrade namn i arbetskopian"
+msgid "renaming %s to %s in workspace manifest"
+msgstr "byter namn från %s till %s i arbetskopians manifest"

-#: work.cc:333
+#: work.cc:334
 #, fuzzy, c-format
 msgid "%s doesn't exist in workspace, skipping"
 msgstr "hoppar över %s, den existerar inte i arbetskopian"

-#: work.cc:337
+#: work.cc:338
 #, fuzzy, c-format
 msgid "destination %s already exists in workspace, skipping"
 msgstr "hoppar över %s, den finns redan noterad i arbetskopian"

-#: work.cc:421
+#: work.cc:422
 #, fuzzy, c-format
 msgid "workspace is corrupt: %s does not exist"
 msgstr "arbetskopian är korrupt: %s finns inte"

-#: work.cc:422
+#: work.cc:423
 #, fuzzy, c-format
 msgid "workspace is corrupt: %s is a directory"
 msgstr "arbetskopian är korrupt: %s är en katalog"

-#: work.cc:432
+#: work.cc:433
 #, fuzzy, c-format
 msgid "Problem with workspace: %s is unreadable"
 msgstr "Problem med arbetskatalogen: %s är oläsbar"

-#: work.cc:458
+#: work.cc:459
 #, c-format
 msgid "base revision %s does not exist in database\n"
 msgstr "grundrevisionen %s finns inte i databasen\n"

-#: work.cc:775 work.cc:786
+#: work.cc:776 work.cc:787
 #, c-format
 msgid "path %s already exists"
 msgstr "sökvägen %s finns redan"

-#: work.cc:829
+#: work.cc:830
 #, c-format
 msgid "renaming '%s' onto existing file: '%s'\n"
 msgstr "byter namn på '%s' till redan existerande fil: '%s'\n"

-#: work.cc:848
+#: work.cc:849
 #, c-format
 msgid "file '%s' does not exist"
 msgstr "filen '%s' finns inte"

-#: work.cc:849
+#: work.cc:850
 #, c-format
 msgid "file '%s' is a directory"
 msgstr "filen '%s' är en katalog"

-#: work.cc:854
+#: work.cc:855
 #, c-format
 msgid "content of file '%s' has changed, not overwriting"
 msgstr "innehållet i filen '%s' har ändrats, skriver inte över"

-#: work.cc:855
+#: work.cc:856
 #, c-format
 msgid "updating %s to %s"
 msgstr "uppdaterar %s till %s"

+#, fuzzy
+#~ msgid "adding %s to workspace delete set\n"
+#~ msgstr "lägger till %s i mängden borttagna filer i arbetskopian\n"
+
 #~ msgid "working copy"
 #~ msgstr "arbetskopia"

============================================================
--- std_hooks.lua	1740ad529749fadac6c115b8373ca26e9f932ad6
+++ std_hooks.lua	259f2956124c69bd0f616943ad64663f67213cd6
@@ -705,3 +705,10 @@ end
    io.close(permfile)
    return matches
 end
+
+function validate_commit_message(message, new_manifest_id)
+    if (message == "") then
+        return false, "empty messages aren't allowed"
+    end
+    return true, ""
+end
============================================================
--- tests/t_database_check_normalized.at	a226dd38826693885d4b9209528dac5fced42d6f
+++ tests/t_database_check_normalized.at	903b3a090390261102a713b0339e99322d728f16
@@ -112,7 +112,6 @@ QN4QTh6umZ1/0+r8qxrkr/xh3YXF+yubLH9Tn7H/
 IY6/Q39m/rs6JxXs5uHhXcsSa1VzxlUXJ7/imsjX/nHm5DOHKdo7lt3Zqsaf
 q4r2pStFl5unvUYjxZOPUKtdWnZ0qxrDriq8M+tnr2Ju942cZpu+//9vEHOD
 QN4QTh6umZ1/0+r8qxrkr/xh3YXF+yubLH9Tn7H/FwEUS+AAzAAA
-====
 ])
 UNGZB64(bad.db.gz.b64, bad.db)

============================================================
--- tests/t_drop_missing.at	b57855a8b89e7f7c8c7cab3ae9fdf660bc4c0111
+++ tests/t_drop_missing.at	7d7b49bf0e6aee2bb8a7bf96202f464367673274
@@ -20,7 +20,7 @@ AT_CHECK(MONOTONE drop maude, [], [ignor
 AT_CHECK(rm maude)

 AT_CHECK(MONOTONE drop maude, [], [ignore], [stderr])
-AT_CHECK(grep 'adding maude to workspace delete set' stderr, [0], [ignore])
+AT_CHECK(grep 'dropping maude from workspace manifest' stderr, [0], [ignore])

 AT_CHECK(MONOTONE status, [], [stdout])
 AT_CHECK(grep maude stdout, [0], [ignore])
@@ -34,8 +34,8 @@ AT_CHECK(MONOTONE drop --missing, [], [i
 AT_CHECK(rm places/cemetery)

 AT_CHECK(MONOTONE drop --missing, [], [ignore], [stderr])
-AT_CHECK(grep 'adding harold to workspace delete set' stderr, [0], [ignore])
-AT_CHECK(grep 'adding places/cemetery to workspace delete set' stderr, [0], [ignore])
+AT_CHECK(grep 'dropping harold from workspace manifest' stderr, [0], [ignore])
+AT_CHECK(grep 'dropping places/cemetery from workspace manifest' stderr, [0], [ignore])

 AT_CHECK(MONOTONE status, [], [stdout])
 AT_CHECK(grep maude stdout, [0], [ignore])
============================================================
--- tests/t_netsync_permissions.at	a02747cf46bece412d85d63694356704a482c8ff
+++ tests/t_netsync_permissions.at	9a8356b76404d50e044f74e5f59d6e055ad64d1e
@@ -21,6 +21,10 @@ AT_DATA(open/write-permissions, [
 *
 ])

+ADD_FILE(badfile, [badfile
+])
+AT_CHECK(MONOTONE --branch=badbranch commit --message badfile, [], [ignore], [ignore])
+
 AT_CHECK(cp test.db clean.db)
 AT_CHECK(cp -r keys/ clean_keys)

@@ -133,6 +137,13 @@ AT_CHECK(MONOTONE2 automate get_revision
 NETSYNC_CLIENT_RUN(pull, testbranch)
 AT_CHECK(MONOTONE2 automate get_revision $BASE, [0], [stdout], [stderr])

+# pull with bad branch fails
+
+AT_CHECK(cp clean.db test2.db)
+AT_CHECK(rm -r keys2 && cp -r clean_keys/ keys2)
+NETSYNC_CLIENT_RUN(pull, badbranch, 1)
+AT_CHECK(MONOTONE2 automate get_revision $BASE, [1], [stdout], [stderr])
+
 # pull with other key fails

 AT_CHECK(cp clean.db test2.db)
============================================================
--- tests/t_rename.at	b95e23675e65c4c3c9bd2b3490d08ce117b11836
+++ tests/t_rename.at	f9830fde9e91d2b2c97e3ec7d4c423d3e12d2726
@@ -53,7 +53,7 @@ AT_CHECK(MONOTONE rename bar barfoo, [],
 AT_CHECK(MONOTONE status, [], [ignore], [ignore])
 AT_CHECK(mv bar barfoo)
 AT_CHECK(MONOTONE rename bar barfoo, [], [ignore], [stderr])
-AT_CHECK(grep 'adding bar -> barfoo to workspace rename set' stderr, [0], [ignore])
+AT_CHECK(grep 'renaming bar to barfoo in workspace manifest' stderr, [0], [ignore])
 AT_CHECK(MONOTONE status, [], [ignore], [ignore])

 # move file to wrong place before renaming it
@@ -62,7 +62,7 @@ AT_CHECK(MONOTONE rename bar barfoo, [],
 AT_CHECK(MONOTONE status, [], [ignore], [ignore])
 AT_CHECK(mv bar barfoofoo)
 AT_CHECK(MONOTONE rename bar barfoo, [], [ignore], [stderr])
-AT_CHECK(grep 'adding bar -> barfoo to workspace rename set' stderr, [0], [ignore])
+AT_CHECK(grep 'renaming bar to barfoo in workspace manifest' stderr, [0], [ignore])
 AT_CHECK(MONOTONE status, [1], [ignore], [ignore])

 AT_CLEANUP
============================================================
--- testsuite.at	2b15c3a7b584370ff89e92002dcac047ff2df357
+++ testsuite.at	24fda35bb35a7e2ddd7a98c55741d919899270e2
@@ -615,6 +615,7 @@ m4_include(tests/t_commit_log_2.at)
 m4_include(tests/t_checkout_creates_log.at)
 m4_include(tests/t_commit_log_1.at)
 m4_include(tests/t_commit_log_2.at)
+m4_include(tests/t_commit_validate.at)
 m4_include(tests/t_dropkey_1.at)
 m4_include(tests/t_dropkey_2.at)
 m4_include(tests/t_rename_attr.at)
============================================================
--- work.cc	974c1d8a5295fd7317898e60abc636fdcc82ba65
+++ work.cc	bc48e2db4924f6b85004818aeb401f14c94a9bfe
@@ -114,7 +114,7 @@ addition_builder::visit_file(file_path c
 {
   if (app.lua.hook_ignore_file(path))
     {
-      P(F("skipping ignorable file %s\n") % path);
+      P(F("skipping ignorable file %s") % path);
       return;
     }

@@ -122,11 +122,12 @@ addition_builder::visit_file(file_path c
   path.split(sp);
   if (ros.has_node(sp))
     {
-      P(F("skipping %s, already accounted for in workspace\n") % path);
+      if (sp.size() > 1)
+        P(F("skipping %s, already accounted for in workspace") % path);
       return;
     }

-  P(F("adding %s to workspace add set\n") % path);
+  P(F("adding %s to workspace manifest") % path);

   split_path dirname, prefix;
   path_component basename;
@@ -199,7 +200,7 @@ perform_deletions(path_set const & paths
       file_path name(*i);

       if (!new_roster.has_node(*i))
-        P(F("skipping %s, not currently tracked\n") % name);
+        P(F("skipping %s, not currently tracked") % name);
       else
         {
           node_t n = new_roster.get_node(*i);
@@ -209,7 +210,7 @@ perform_deletions(path_set const & paths
               N(d->children.empty(),
                 F("cannot remove %s/, it is not empty") % name);
             }
-          P(F("adding %s to workspace delete set\n") % name);
+          P(F("dropping %s from workspace manifest") % name);
           new_roster.drop_detached_node(new_roster.detach_node(*i));
           if (app.execute && path_exists(name))
             delete_file_or_dir_shallow(name);
@@ -305,7 +306,7 @@ perform_rename(set<file_path> const & sr
     {
       node_id nid = new_roster.detach_node(i->first);
       new_roster.attach_node(nid, i->second);
-      P(F("adding %s -> %s to workspace rename set")
+      P(F("renaming %s to %s in workspace manifest")
         % file_path(i->first)
         % file_path(i->second));
     }
@@ -422,7 +423,7 @@ void get_revision_id(revision_id & c)
                        F("workspace is corrupt: %s is a directory") % c_path);

   data c_data;
-  L(FL("loading revision id from %s\n") % c_path);
+  L(FL("loading revision id from %s") % c_path);
   try
     {
       read_data(c_path, c_data);