The unified diff between revisions [24fb0b25..] and [8032bf83..] is displayed below. It can also be downloaded as a raw diff.

#
#
# patch ".mtn-ignore"
#  from [48d461ab5590a8e01a5e5b804813bbbd031cdb44]
#    to [7b7a1ec95d2ba164a48727394dfaa9436ec9eccb]
#
# patch "automate.cc"
#  from [c6e067dec1263e430f22e39fc63e30932d1c02d1]
#    to [b23eced8b6c237fd768369cf7d32ba6119f19fe4]
#
# patch "database.cc"
#  from [7d05335695a344d562e1c81daed3f0bf525259d8]
#    to [9e10e5d55233691379b3c4855ff77de8aced5ada]
#
# patch "database.hh"
#  from [cdb13d34c338f3d6fb2e48840fd9c3a5b698cbcb]
#    to [dd6db1d50f94c66c8b9a4090bd93c92d8885dcc3]
#
# patch "monotone.texi"
#  from [b7ff9206e89299dae8f9dd915fbf7e6f4be502cb]
#    to [4b08a6efa1905ac80420a2167bc874c5b9ed8ca1]
#
# patch "netsync.cc"
#  from [802494ec22ebb2d9c38718680677b9d6bcd5b2ab]
#    to [340e432145bad814c7757dfa04769449745b791f]
#
# patch "options_list.hh"
#  from [5ea48e4362ae53c3cf69b6422f98eb5a33e92086]
#    to [8432925aa61ab0032d712f7a7fbb043b109f7bcb]
#
# patch "refiner.cc"
#  from [506dd6937b1908a81bcefe63cad77293c6a9c62f]
#    to [8b1ad7156df95b243f3e0922871e842a3c82570a]
#
# patch "tests/checkout_validates_target_directory/__driver__.lua"
#  from [bdfd6c99a8ebc76e7959ef79868a6373cfe30f54]
#    to [14039447ff443f0bd7a61a0e25cd76bf995be046]
#
# patch "tests/clone_validates_target_directory/__driver__.lua"
#  from [ca4db9a9677e80a1015f129f8cbaf4face246a58]
#    to [bb4ba95dd27e59251ea97e3e108800223c52874a]
#
# patch "tests/non_workspace_keydir/__driver__.lua"
#  from [d32720e0e63d4429dc590c0849a1eb8794848b06]
#    to [09163eaea1e4184fffae4bf8b8719aa3711a43ec]
#
# patch "ui.cc"
#  from [5c306ceb398f305e5af179008c4bf6165526e87a]
#    to [8544648c4a23b8e79f980da6ed3a4ab81ff0d509]
#
# patch "ui.hh"
#  from [31deb8bf636c6a0518244e3e7d487d6cb08413a3]
#    to [4ed004af61868096881ebcd9688ba6f880359cdf]
#
============================================================
--- .mtn-ignore	48d461ab5590a8e01a5e5b804813bbbd031cdb44
+++ .mtn-ignore	7b7a1ec95d2ba164a48727394dfaa9436ec9eccb
@@ -64,3 +64,4 @@
 ^unit_tester$
 ^unit_tests\.status$
 ^version\.texi$
+^monotone\.html$
============================================================
--- automate.cc	c6e067dec1263e430f22e39fc63e30932d1c02d1
+++ automate.cc	b23eced8b6c237fd768369cf7d32ba6119f19fe4
@@ -1555,50 +1555,19 @@ CMD_AUTOMATE(common_ancestors, N_("REV1

   database db(app);

-  set<revision_id> ancestors, common_ancestors;
-  vector<revision_id> frontier;
+  set<revision_id> revs, common_ancestors;
   for (args_vector::const_iterator i = args.begin(); i != args.end(); ++i)
     {
       revision_id rid(decode_hexenc((*i)()));
-      N(db.revision_exists(rid), F("no such revision '%s'") % rid);
-      ancestors.clear();
-      ancestors.insert(rid);
-      frontier.push_back(rid);
-      while (!frontier.empty())
-        {
-          revision_id rid = frontier.back();
-          frontier.pop_back();
-          if(!null_id(rid))
-            {
-              set<revision_id> parents;
-              db.get_revision_parents(rid, parents);
-              for (set<revision_id>::const_iterator i = parents.begin();
-                   i != parents.end(); ++i)
-                {
-                  if (ancestors.find(*i) == ancestors.end())
-                    {
-                      frontier.push_back(*i);
-                      ancestors.insert(*i);
-                    }
-                }
-            }
-        }
-      if (common_ancestors.empty())
-        common_ancestors = ancestors;
-      else
-        {
-          set<revision_id> common;
-          set_intersection(ancestors.begin(), ancestors.end(),
-                         common_ancestors.begin(), common_ancestors.end(),
-                         inserter(common, common.begin()));
-          common_ancestors = common;
-        }
+      N(db.revision_exists(rid), F("No such revision %s") % rid);
+      revs.insert(rid);
     }

+  db.get_common_ancestors(revs, common_ancestors);
+
   for (set<revision_id>::const_iterator i = common_ancestors.begin();
        i != common_ancestors.end(); ++i)
-    if (!null_id(*i))
-      output << *i << '\n';
+      output << *i << "\n";
 }

 // Name: branches
============================================================
--- database.cc	7d05335695a344d562e1c81daed3f0bf525259d8
+++ database.cc	9e10e5d55233691379b3c4855ff77de8aced5ada
@@ -2157,6 +2157,59 @@ void
 }

 void
+database::get_common_ancestors(std::set<revision_id> const & revs,
+                               std::set<revision_id> & common_ancestors)
+{
+  set<revision_id> ancestors, all_common_ancestors;
+  vector<revision_id> frontier;
+  for (set<revision_id>::const_iterator i = revs.begin();
+       i != revs.end(); ++i)
+    {
+      I(revision_exists(*i));
+      ancestors.clear();
+      ancestors.insert(*i);
+      frontier.push_back(*i);
+      while (!frontier.empty())
+        {
+          revision_id rid = frontier.back();
+          frontier.pop_back();
+          if(!null_id(rid))
+            {
+              set<revision_id> parents;
+              get_revision_parents(rid, parents);
+              for (set<revision_id>::const_iterator i = parents.begin();
+                   i != parents.end(); ++i)
+                {
+                  if (ancestors.find(*i) == ancestors.end())
+                    {
+                      frontier.push_back(*i);
+                      ancestors.insert(*i);
+                    }
+                }
+            }
+        }
+      if (all_common_ancestors.empty())
+        all_common_ancestors = ancestors;
+      else
+        {
+          set<revision_id> common;
+          set_intersection(ancestors.begin(), ancestors.end(),
+                         all_common_ancestors.begin(), all_common_ancestors.end(),
+                         inserter(common, common.begin()));
+          all_common_ancestors = common;
+        }
+    }
+
+  for (set<revision_id>::const_iterator i = all_common_ancestors.begin();
+       i != all_common_ancestors.end(); ++i)
+    {
+      // FIXME: where do these null'ed IDs come from?
+      if (null_id(*i)) continue;
+      common_ancestors.insert(*i);
+    }
+}
+
+void
 database::get_revision(revision_id const & id,
                        revision_t & rev)
 {
============================================================
--- database.hh	cdb13d34c338f3d6fb2e48840fd9c3a5b698cbcb
+++ database.hh	dd6db1d50f94c66c8b9a4090bd93c92d8885dcc3
@@ -156,6 +156,10 @@ public:

   void get_revision_manifest(revision_id const & cid,
                              manifest_id & mid);
+
+  void get_common_ancestors(std::set<revision_id> const & revs,
+                            std::set<revision_id> & common_ancestors);
+
   void get_revision_ids(std::set<revision_id> & ids);
   // this is exposed for 'db check':
   void get_file_ids(std::set<file_id> & ids);
============================================================
--- monotone.texi	b7ff9206e89299dae8f9dd915fbf7e6f4be502cb
+++ monotone.texi	4b08a6efa1905ac80420a2167bc874c5b9ed8ca1
@@ -4432,6 +4432,7 @@ @chapter Command Reference
 * Database::                    Manipulation of your database as a whole
 * Automation::                  Running monotone from other programs
 * RCS::                         Importing legacy version control files
+* Global Options::              Options which can be applied on every command
 @end menu


@@ -8658,7 +8659,7 @@ @section Automation
 @end ftable

 @page
-@node    RCS,  , Automation, Command Reference
+@node    RCS, Global Options , Automation, Command Reference
 @section RCS

 @ftable @command
@@ -8688,6 +8689,101 @@ @section RCS
 @end ftable


+@page
+@node    Global Options,  , RCS, Command Reference
+@section Global Options
+
+Global options can be set for every command at any possible position in the
+command string.
+
+@ftable @option
+
+@item --help
+@itemx -h
+Display a help message. This can be applied on single commands as well as
+command groups.
+
+@item --confdir <arg>
+Set the location of the configuration directory.
+
+@item --no-default-confdir
+Forbid use of the default configuration directory.
+
+@item --db <arg>
+@itemx -d <arg>
+Set the name of the database.
+
+@item --log <arg>
+Write any output of the command (stdout and stderr) to the specified file.
+
+@item --debug
+Print a debug log to stderr while running the command.
+
+@item --dump <arg>
+File to dump debugging log to, in case of a failure. This is only used in
+conjunction with @option{--debug}.
+
+@item --ignore-suspend-certs
+Do not ignore revisions marked as suspended. See also @command{mtn suspend}.
+
+@item --key <arg>
+@itemx -k <arg>
+Set the key used for signatures.
+
+@item --keydir <arg>
+Set the location of the key store.
+
+@item --norc
+Do not load ~/.monotone/monotonerc or _MTN/monotonerc lua files.
+
+@item --rcfile <arg>
+Load an extra configuration file.
+
+@item --nostd
+Do not load the standard lua hooks.
+
+@item --quiet
+Suppress verbose, informational and progress messages.
+
+@item --reallyquiet
+Suppress warning, verbose, informational and progress messages.
+
+@item --root <arg>
+Limit the search for a workspace to the specified root directory.
+
+@item --ssh-sign <arg>
+Controls the use of ssh-agent.
+Valid arguments are:
+@itemize
+@item 'yes': use ssh-agent to make signatures if possible (default)
+@item 'no': force use of monotone's internal code
+@item 'only': force use of ssh-agent
+@item 'check' sign with both, ssh-agent and monotone's internal code, and compare the result
+@end itemize
+
+@item --ticker <arg>
+Set the ticker style.
+Valid arguments are:
+@itemize
+@item 'count': print counts (default)
+@item 'dot': print single chars for every tick
+@item 'none': no ticker output
+@end itemize
+The 'count' ticker type may not show the progress of all tickers which run
+at the same time because of space reasons in the terminal. This is not a problem
+for the 'dot' ticker type or the ticker which is supplied in @command{mtn automate stdio}.
+
+@item --version
+Print the version number and exits afterwards. See also @command{mtn version}.
+
+@item --xargs <arg>
+@itemx -@@ <arg>
+Insert command line arguments taken from the given file. The file may be stdin
+(-@@-).
+
+@end ftable
+
+
 @node    Hook Reference, Special Topics, Command Reference, Top
 @chapter Hook Reference

============================================================
--- netsync.cc	802494ec22ebb2d9c38718680677b9d6bcd5b2ab
+++ netsync.cc	340e432145bad814c7757dfa04769449745b791f
@@ -795,6 +795,10 @@ session::setup_client_tickers()
     {
       I(role == source_and_sink_role);
       // xgettext: please use short message and try to avoid multibytes chars
+      cert_in_ticker.reset(new ticker(N_("certs in"), "c", 3, false, true));
+      // xgettext: please use short message and try to avoid multibytes chars
+      cert_out_ticker.reset(new ticker(N_("certs out"), "C", 3, false, true));
+      // xgettext: please use short message and try to avoid multibytes chars
       revision_in_ticker.reset(new ticker(N_("revs in"), "r", 1));
       // xgettext: please use short message and try to avoid multibytes chars
       revision_out_ticker.reset(new ticker(N_("revs out"), "R", 1));
============================================================
--- options_list.hh	5ea48e4362ae53c3cf69b6422f98eb5a33e92086
+++ options_list.hh	8432925aa61ab0032d712f7a7fbb043b109f7bcb
@@ -295,11 +295,7 @@ GOPT(ssh_sign, "ssh-sign", std::string,
 #endif

 GOPT(ssh_sign, "ssh-sign", std::string, "yes",
-     gettext_noop("controls use of ssh-agent.  valid arguments are: "
-                  "'yes' to use ssh-agent to make signatures if possible, "
-                  "'no' to force use of monotone's internal code, "
-                  "'only' to force use of ssh-agent, "
-                  "'check' to sign with both and compare"))
+     gettext_noop("controls use of ssh-agent (yes|no|only|check)"))
 #ifdef option_bodies
 {
   if (arg.empty())
@@ -308,7 +304,7 @@ GOPT(ssh_sign, "ssh-sign", std::string,
   if (arg != "yes"
       && arg != "no"
       && arg != "check"
-      && arg != "only") // XXX what does "only" do? not documented
+      && arg != "only")
     throw bad_arg_internal(F("--ssh-sign must be set to 'yes', 'no', "
                              "'only', or 'check'").str());

============================================================
--- refiner.cc	506dd6937b1908a81bcefe63cad77293c6a9c62f
+++ refiner.cc	8b1ad7156df95b243f3e0922871e842a3c82570a
@@ -103,7 +103,7 @@ refiner::calculate_items_to_send()
   string typestr;
   netcmd_item_type_to_string(type, typestr);

-  //   L(FL("%s determined %d %s items to send")
+  //   L(FL("%s determined %d %s items to send")
   //     % voicestr() % items_to_send.size() % typestr);
   calculated_items_to_send = true;
 }
@@ -205,7 +205,7 @@ refiner::begin_refinement()
   netcmd_item_type_to_string(type, typestr);
   L(FL("Beginning %s refinement on %s.") % typestr % voicestr());
 }
-
+
 void
 refiner::process_done_command(size_t n_items)
 {
@@ -219,11 +219,11 @@ refiner::process_done_command(size_t n_i
     % voicestr() % typestr % items_to_send.size() % items_to_receive);

   /*
-  if (local_items.size() < 25)
+  if (local_items.size() < 25)
     {
       // Debugging aid.
       L(FL("+++ %d items in %s") % local_items.size() % voicestr());
-      for (set<id>::const_iterator i = local_items.begin();
+      for (set<id>::const_iterator i = local_items.begin();
            i != local_items.end(); ++i)
         {
           L(FL("%s item %s") % voicestr() % *i);
@@ -232,7 +232,7 @@ refiner::process_done_command(size_t n_i
     }
   */

-  if (voice == server_voice)
+  if (voice == server_voice)
     {
       //       L(FL("server responding to [done %s %d] with [done %s %d]")
       //         % typestr % n_items % typestr % items_to_send.size());
@@ -240,7 +240,7 @@ refiner::process_done_command(size_t n_i
     }

   done = true;
-
+
   // we can clear up the merkle trie's memory now
   table.clear();
 }
@@ -309,7 +309,7 @@ refiner::process_refinement_command(refi
                 {
                   cb.queue_refine_cmd(refinement_query, *mp);
                   ++queries_in_flight;
-                }
+                }

             }

@@ -374,7 +374,7 @@ refiner::process_refinement_command(refi
       // Possibly this signals the end of refinement.
       if (voice == client_voice && queries_in_flight == 0)
         {
-          string typestr;
+          string typestr;
           netcmd_item_type_to_string(their_node.type, typestr);
           calculate_items_to_send();
           // L(FL("client sending [done %s %d]") % typestr % items_to_send.size());
@@ -400,20 +400,20 @@ using boost::shared_ptr;
 using std::deque;
 using boost::shared_ptr;

-struct
+struct
 refiner_pair
 {
   // This structure acts as a mock netsync session. It's only purpose is to
   // construct two refiners that are connected to one another, and route
   // refinement calls back and forth between them.

-  struct
+  struct
   refiner_pair_callbacks : refiner_callbacks
   {
     refiner_pair & p;
     bool is_client;
-    refiner_pair_callbacks(refiner_pair & p, bool is_client)
-      : p(p), is_client(is_client)
+    refiner_pair_callbacks(refiner_pair & p, bool is_client)
+      : p(p), is_client(is_client)
     {}

     virtual void queue_refine_cmd(refinement_type ty,
@@ -434,7 +434,7 @@ refiner_pair
   refiner_pair_callbacks server_cb;
   refiner client;
   refiner server;
-
+
   struct msg
   {
     msg(bool is_client, refinement_type ty, merkle_node const & node)
@@ -444,10 +444,10 @@ refiner_pair
         node(node)
     {}

-    msg(bool is_client, size_t items)
+    msg(bool is_client, size_t items)
       : op(done),
         send_to_client(!is_client),
-        n_items(items)
+        n_items(items)
     {}

     enum { refine, done } op;
@@ -460,14 +460,14 @@ refiner_pair
   deque<shared_ptr<msg> > events;
   size_t n_msgs;

-  void crank()
+  void crank()
   {
-
+
     shared_ptr<msg> m = events.front();
     events.pop_front();
     ++n_msgs;

-    switch (m->op)
+    switch (m->op)
       {

       case msg::refine:
@@ -487,7 +487,7 @@ refiner_pair
   }

   refiner_pair(set<id> const & client_items,
-               set<id> const & server_items) :
+               set<id> const & server_items) :
     client_cb(*this, true),
     server_cb(*this, false),
     // The item type here really doesn't matter.
@@ -509,22 +509,22 @@ refiner_pair

     while (! events.empty())
       crank();
-
+
     // Refinement should have completed by here.
     UNIT_TEST_CHECK(client.done);
     UNIT_TEST_CHECK(server.done);

     check_set_differences("client", client);
     check_set_differences("server", server);
-    check_no_redundant_sends("client->server",
-                             client.items_to_send,
+    check_no_redundant_sends("client->server",
+                             client.items_to_send,
                              server.get_local_items());
-    check_no_redundant_sends("server->client",
-                             server.items_to_send,
+    check_no_redundant_sends("server->client",
+                             server.items_to_send,
                              client.get_local_items());
     UNIT_TEST_CHECK(client.items_to_send.size() == server.items_to_receive);
     UNIT_TEST_CHECK(server.items_to_send.size() == client.items_to_receive);
-    L(FL("stats: %d total, %d cs, %d sc, %d msgs")
+    L(FL("stats: %d total, %d cs, %d sc, %d msgs")
       % (server.items_to_send.size() + client.get_local_items().size())
       % client.items_to_send.size()
       % server.items_to_send.size()
@@ -553,14 +553,14 @@ refiner_pair
       }
   }

-  void check_no_redundant_sends(char const * context,
+  void check_no_redundant_sends(char const * context,
                                 set<id> const & src,
                                 set<id> const & dst)
   {
     for (set<id>::const_iterator i = src.begin(); i != src.end(); ++i)
       {
         set<id>::const_iterator j = dst.find(*i);
-        if (j != dst.end())
+        if (j != dst.end())
           {
             L(FL("WARNING: %s transmission will send redundant item %s")
               % context % *i);
@@ -576,7 +576,7 @@ refiner_pair
                    r.get_peer_items().begin(), r.get_peer_items().end(),
                    inserter(tmp, tmp.begin()));
     print_if_unequal(context,
-                     "diff(local,peer)", tmp,
+                     "diff(local,peer)", tmp,
                      "items_to_send", r.items_to_send);

     UNIT_TEST_CHECK(tmp == r.items_to_send);
@@ -585,7 +585,7 @@ void


 void
-check_combinations_of_sets(set<id> const & s0,
+check_combinations_of_sets(set<id> const & s0,
                            set<id> const & a,
                            set<id> const & b)
 {
@@ -614,7 +614,7 @@ check_combinations_of_sets(set<id> const
 }


-void
+void
 build_random_set(set<id> & s, size_t sz, bool clumpy, randomizer & rng)
 {
   while (s.size() < sz)
@@ -635,12 +635,12 @@ build_random_set(set<id> & s, size_t sz,
               ++c;
               str[pos] = c;
               s.insert(id(str));
-            }
+            }
         }
     }
 }

-size_t
+size_t
 perturbed(size_t n, randomizer & rng)
 {
   // we sometimes perturb sizes to deviate a bit from natural word-multiple sizes
@@ -660,17 +660,17 @@ modulated_size(size_t base_set_size, siz
 }


-void
+void
 check_with_count(size_t base_set_size, randomizer & rng)
 {
-  if (base_set_size == 0)
+  if (base_set_size == 0)
     return;

   L(FL("running refinement check with base set size %d") % base_set_size);

   // Our goal here is to construct a base set of a given size, and two
   // secondary sets which will be combined with the base set in various
-  // ways.
+  // ways.
   //
   // The secondary sets will be built at the following sizes:
   //
@@ -683,10 +683,10 @@ check_with_count(size_t base_set_size, r
   //
   // The base set is constructed in both clumpy and non-clumpy forms,
   // making 6 * 6 * 2 = 72 variations.
-  //
+  //
   // Since each group of sets creates 9 sync scenarios, each "size" creates
   // 648 sync scenarios.
-
+
   for (size_t c = 0; c < 2; ++c)
     {
       set<id> s0;
@@ -696,7 +696,7 @@ check_with_count(size_t base_set_size, r
         {
           set<id> sa;
           build_random_set(sa, modulated_size(perturbed(base_set_size, rng), a), false, rng);
-
+
           for (size_t b = 0; b < 6; ++b)
             {
               set<id> sb;
@@ -704,15 +704,15 @@ check_with_count(size_t base_set_size, r
               check_combinations_of_sets(s0, sa, sb);
             }
         }
-    }
+    }
 }

 UNIT_TEST(refiner, various_counts)
 {
-  {
+  {
     // Once with zero-zero, for good measure.
     set<id> s0;
-    refiner_pair x(s0, s0);
+    refiner_pair x(s0, s0);
   }

   // We run 3 primary counts, giving 1944 tests. Note that there is some
@@ -720,9 +720,15 @@ UNIT_TEST(refiner, various_counts)
   // of landing on such pleasant round numbers.

   randomizer rng;
-  check_with_count(1, rng);
-  check_with_count(128, rng);
-  check_with_count(1024, rng);
+  check_with_count(1, rng);
+  check_with_count(128, rng);
+
+#if not defined(__CYGWIN__)
+  // Something in this test is very slow on Cygwin; so slow that the
+  // buildbot master thinks the slave is hung and terminates it. So we don't
+  // run this test on Cygwin.
+  check_with_count(1024, rng);
+#endif
 }

 #endif
============================================================
--- tests/checkout_validates_target_directory/__driver__.lua	bdfd6c99a8ebc76e7959ef79868a6373cfe30f54
+++ tests/checkout_validates_target_directory/__driver__.lua	14039447ff443f0bd7a61a0e25cd76bf995be046
@@ -14,9 +14,10 @@ if existsonpath("chmod") and existsonpat

 if existsonpath("chmod") and existsonpath("test") then
   -- Skip this part if run as root (hi Gentoo!)
-  -- Also skip if on Windows, since these permissions are not enforced there
+  -- Also skip if on Windows or Cygwin, since these permissions are not enforced there
   if check({"test", "-O", "/"}, false, false, false) == 0 or
-     ostype == "Windows"
+     ostype == "Windows" or
+     string.find (ostype, "CYGWIN")
   then
     partial_skip = true
   else
============================================================
--- tests/clone_validates_target_directory/__driver__.lua	ca4db9a9677e80a1015f129f8cbaf4face246a58
+++ tests/clone_validates_target_directory/__driver__.lua	bb4ba95dd27e59251ea97e3e108800223c52874a
@@ -17,9 +17,10 @@ if existsonpath("chmod") and existsonpat

 if existsonpath("chmod") and existsonpath("test") then
   -- skip this part if run as root (hi Gentoo!)
-  -- Also skip if on Windows, since these permissions are not enforced there
+  -- Also skip if on Windows and Cygwin, since these permissions are not enforced there
   if check({"test", "-O", "/"}, false, false, false) == 0 or
-     ostype == "Windows"
+     ostype == "Windows" or
+     string.find (ostype, "CYGWIN")
   then
     partial_skip = true
   else
============================================================
--- tests/non_workspace_keydir/__driver__.lua	d32720e0e63d4429dc590c0849a1eb8794848b06
+++ tests/non_workspace_keydir/__driver__.lua	09163eaea1e4184fffae4bf8b8719aa3711a43ec
@@ -27,17 +27,17 @@ end
 expected_ret = -15
 end

--- srv = bg(pure_mtn("serve", "--confdir="..test.root, "--keydir="..test.root.."/keys"), expected_ret, false, true)
--- sleep(2)
--- srv:finish()
--- check(qgrep("beginning service", "stderr"))
+srv = bg(pure_mtn("serve", "--confdir="..test.root, "--keydir="..test.root.."/keys"), expected_ret, false, true)
+sleep(2)
+srv:finish()
+check(qgrep("beginning service", "stderr"))

 -- this should find a private key in the keys directory under the specified confdir

--- srv = bg(pure_mtn("serve", "--confdir="..test.root), expected_ret, false, true)
--- sleep(2)
--- srv:finish()
--- check(qgrep("beginning service", "stderr"))
+srv = bg(pure_mtn("serve", "--confdir="..test.root), expected_ret, false, true)
+sleep(2)
+srv:finish()
+check(qgrep("beginning service", "stderr"))

 -- this should fail to decrypt the private key found in ~/.monotone/keys

@@ -50,7 +50,11 @@ mkdir(test.root.."/empty")
 mkdir(test.root.."/empty")
 -- FIXME: this should probably be set globally in lua-testsuite.lua for
 --        all tests.
+if ostype == "Windows" then
+set_env("APPDATA", test.root.."/empty")
+else
 set_env("HOME", test.root.."/empty")
+end
 srv = bg(pure_mtn("serve"), 1, false, true)
 sleep(2)
 srv:finish()
============================================================
--- ui.cc	5c306ceb398f305e5af179008c4bf6165526e87a
+++ ui.cc	8544648c4a23b8e79f980da6ed3a4ab81ff0d509
@@ -65,13 +65,14 @@ ticker::ticker(string const & tickname,
 };

 ticker::ticker(string const & tickname, string const & s, size_t mod,
-    bool kilocount) :
+    bool kilocount, bool skip_display) :
   ticks(0),
   mod(mod),
   total(0),
   previous_total(0),
   kilocount(kilocount),
   use_total(false),
+  may_skip_display(skip_display),
   keyname(tickname),
   name(_(tickname.c_str())),
   shortname(s),
@@ -246,6 +247,12 @@ void tick_write_count::write_ticks()
     {
       ticker * tick = i->second;

+      // if the display of this ticker has no great importance, i.e. multiple
+      // other tickers should be displayed at the same time, skip its display
+      // to save space on terminals
+      if (tick->may_skip_display)
+        continue;
+
       if ((tick->count_size == 0 && tick->kilocount)
           ||
           (tick->use_total && tick->previous_total != tick->total))
============================================================
--- ui.hh	31deb8bf636c6a0518244e3e7d487d6cb08413a3
+++ ui.hh	4ed004af61868096881ebcd9688ba6f880359cdf
@@ -25,12 +25,13 @@ struct ticker
   size_t previous_total;
   bool kilocount;
   bool use_total;
+  bool may_skip_display;
   std::string keyname;
   std::string name; // translated name
   std::string shortname;
   size_t count_size;
   ticker(std::string const & n, std::string const & s, size_t mod = 64,
-      bool kilocount=false);
+      bool kilocount=false, bool skip_display=false);
   void set_total(size_t tot) { use_total = true; total = tot; }
   void set_count_size(size_t csiz) { count_size = csiz; }
   void operator++();