فهرست منبع

provide the first cut for my RSE patchset for Monotone VCS. See the top of the monotone.patch.rse for details

Ralf S. Engelschall 18 سال پیش
والد
کامیت
a06d0ad73c
2فایلهای تغییر یافته به همراه704 افزوده شده و 1 حذف شده
  1. 692 0
      monotone/monotone.patch.rse
  2. 12 1
      monotone/monotone.spec

+ 692 - 0
monotone/monotone.patch.rse

@@ -0,0 +1,692 @@
+
+  This is the RSE patchset for the Monotone VCS.
+
+  The patchset is entirely enclosed in...
+  
+    #if defined(RSE) /* <tag> */
+    [...]
+    #endif
+
+  ...and this way can be clearly distinguished. The <tag> corresponds
+  the following major changes it includes:
+
+  o environment-variables:
+    This adds the two environment variables MTN_DBFILE and MTN_KEYDIR as
+    defaults for the (bootstrapping) mtn(1) command line options --db
+    and --keydir. This allows you to provide values for them without
+    having to pass the options all the time.
+
+  o alt-book-keeping-root:
+    This allows mtn(1) to accept an alternative book-keeping directory.
+    The default still is "_MTN", but alternatively one can rename this
+    to ".mtn". If one sets the environment variable "MTN_BKROOT" one can
+    change ".mtn" to an arbitrary sub-directory name and additionally
+    even force its use on workspace creation operations.
+
+  o cosmetics-netsync:
+    This is just a small cosmetics change. It reduces the annoying
+    "doing anonymous pull; use -kKEYNAME if you need authentication" to
+    just "doing anonymous pull" as mtn(1) doesn't have to teach people.
+    That's for what the documentation is for.
+    
+  o cosmetics-diff-and-log:
+    This cosmetically "improves" the output of "mtn diff" and "mtn
+    log". For "mtn diff" The output of "mtn diff" now uses a separator
+    line consisting of 67 (instead of 60) "=" characters to align
+    with cvs(1)'s well known output. Additionally, two new command
+    line options for "mtn diff" allow one to disable some outputs:
+    "--no-show-header" disables the output of the redundant "#..."
+    header lines at the top of the output and "--no-show-separator"
+    disables the output of the separator line at all. The output of "mtn
+    log" is improved by aligning the single-line certificate values and
+    by indenting the file change information by just 4 instead of 8
+    characters.
+
+  o diff-index:
+    This adds "Index:" lines to the output of "mtn diff" in order to
+    align with the "svn diff" and "cvs diff" outputs. This also helps
+    patch(1) to clearly identify the file to patch.
+
+                                       Ralf S. Engelschall
+                                       rse@engelschall.com
+                                       www.engelschall.com
+
+============================================================
+--- app_state.cc	74425b52934112d6f23c222e36516a69aee2bb29
++++ app_state.cc	cc9111317d701076b496c80734ae89ab7c6e3741
+@@ -141,13 +141,24 @@ app_state::create_workspace(system_path 
+   go_to_workspace(new_dir);
+   mark_std_paths_used();
+ 
++#if defined(RSE) /* alt-book-keeping-root */
++  N(!(directory_exists(bookkeeping_root) || directory_exists(alt_bookkeeping_root)),
++    F("monotone bookkeeping directory '%s' or '%s' already exists in '%s'")
++    % bookkeeping_root % alt_bookkeeping_root % new_dir);
++#else
+   N(!directory_exists(bookkeeping_root),
+     F("monotone bookkeeping directory '%s' already exists in '%s'")
+     % bookkeeping_root % new_dir);
++#endif
+ 
+   L(FL("creating bookkeeping directory '%s' for workspace in '%s'")
+     % bookkeeping_root % new_dir);
+ 
++#if defined(RSE) /* alt-book-keeping-root */
++  if (getenv("MTN_BKROOT") != NULL)
++    mkdir_p(bookkeeping_path(getenv("MTN_BKROOT")));
++  else
++#endif
+   mkdir_p(bookkeeping_root);
+ 
+   make_branch_sticky();
+============================================================
+--- cmd_diff_log.cc	b95267396272bf66f1c4c17b19659cc4e734213a
++++ cmd_diff_log.cc	070f04c88e5a724545d48c3669d78fa2394987f3
+@@ -96,6 +96,27 @@ print_indented_set(ostream & os,
+                    set<file_path> const & s,
+                    size_t max_cols)
+ {
++#if defined(RSE) /* cosmetics-diff-and-log */
++  size_t cols = 4;
++  os << "    ";
++  for (set<file_path>::const_iterator i = s.begin();
++       i != s.end(); i++)
++    {
++      const string str = lexical_cast<string>(*i);
++      if (cols > 4 && cols + str.size() + 1 >= max_cols)
++        {
++          cols = 4;
++          os << "\n    ";
++        }
++      else if (cols > 4) {
++        os << ' ';
++        cols += 1;
++      }
++      os << str;
++      cols += str.size();
++    }
++  os << '\n';
++#else
+   size_t cols = 8;
+   os << "       ";
+   for (set<file_path>::const_iterator i = s.begin();
+@@ -111,6 +132,7 @@ print_indented_set(ostream & os,
+       cols += str.size() + 1;
+     }
+   os << '\n';
++#endif
+ }
+ 
+ void
+@@ -129,7 +151,11 @@ changes_summary::print(ostream & os, siz
+       for (map<file_path, file_path>::const_iterator
+            i = cs.nodes_renamed.begin();
+            i != cs.nodes_renamed.end(); i++)
++#if defined(RSE) /* cosmetics-diff-and-log */
++        os << "    " << i->first
++#else
+         os << "        " << i->first
++#endif
+            << " to " << i->second << '\n';
+     }
+ 
+@@ -230,8 +256,13 @@ dump_diffs(cset const & cs,
+            set<file_path> const & paths,
+            bool limit_paths = false)
+ {
++#if defined(RSE) /* cosmetics-diff-and-log */
++  // 67 is somewhat arbitrary (CVS uses this), but less than 80
++  string patch_sep = string(67, '=');
++#else
+   // 60 is somewhat arbitrary, but less than 80
+   string patch_sep = string(60, '=');
++#endif
+ 
+   for (map<file_path, file_id>::const_iterator
+          i = cs.files_added.begin();
+@@ -240,6 +271,9 @@ dump_diffs(cset const & cs,
+       if (limit_paths && paths.find(i->first) == paths.end())
+         continue;
+ 
++#if defined(RSE) /* cosmetics-diff-and-log */
++      if (!app.opts.no_show_separator)
++#endif
+       output << patch_sep << '\n';
+       data unpacked;
+       vector<string> lines;
+@@ -286,6 +320,9 @@ dump_diffs(cset const & cs,
+       file_data f_old;
+       data data_old, data_new;
+ 
++#if defined(RSE) /* cosmetics-diff-and-log */
++      if (!app.opts.no_show_separator)
++#endif
+       output << patch_sep << '\n';
+ 
+       app.db.get_file_version(delta_entry_src(i), f_old);
+@@ -493,6 +530,9 @@ CMD(diff, "diff", "", CMD_REF(informativ
+   data summary;
+   write_cset(included, summary);
+ 
++#if defined(RSE) /* cosmetics-diff-and-log */
++  if (!app.opts.no_show_header) {
++#endif
+   vector<string> lines;
+   split_into_lines(summary(), lines);
+   cout << "#\n";
+@@ -508,6 +548,9 @@ CMD(diff, "diff", "", CMD_REF(informativ
+       cout << "# " << _("no changes") << '\n';
+     }
+   cout << "#\n";
++#if defined(RSE) /* cosmetics-diff-and-log */
++  }
++#endif
+ 
+   if (app.opts.diff_format == external_diff)
+     {
+@@ -871,7 +914,11 @@ CMD(log, "log", "", CMD_REF(informative)
+           else
+             {
+               out << string(65, '-') << '\n';
++#if defined(RSE) /* cosmetics-diff-and-log */
++              out << "Revision:  " << rid << '\n';
++#else
+               out << "Revision: " << rid << '\n';
++#endif
+ 
+               changes_summary csum;
+ 
+@@ -886,12 +933,21 @@ CMD(log, "log", "", CMD_REF(informative)
+ 
+               for (set<revision_id>::const_iterator anc = ancestors.begin();
+                    anc != ancestors.end(); ++anc)
++#if defined(RSE) /* cosmetics-diff-and-log */
++                out << "Ancestor:  " << *anc << '\n';
++
++              log_certs(out, app, rid, author_name, "Author:    ", false);
++              log_certs(out, app, rid, date_name,   "Date:      ", false);
++              log_certs(out, app, rid, branch_name, "Branch:    ", false);
++              log_certs(out, app, rid, tag_name,    "Tag:       ", false);
++#else
+                 out << "Ancestor: " << *anc << '\n';
+ 
+               log_certs(out, app, rid, author_name, "Author: ", false);
+               log_certs(out, app, rid, date_name,   "Date: ",   false);
+               log_certs(out, app, rid, branch_name, "Branch: ", false);
+               log_certs(out, app, rid, tag_name,    "Tag: ",    false);
++#endif
+ 
+               if (!app.opts.no_files && !csum.cs.empty())
+                 {
+@@ -901,7 +957,11 @@ CMD(log, "log", "", CMD_REF(informative)
+                 }
+ 
+               log_certs(out, app, rid, changelog_name, "ChangeLog: ", true);
++#if defined(RSE) /* cosmetics-diff-and-log */
++              log_certs(out, app, rid, comment_name,   "Comments:  ", true);
++#else
+               log_certs(out, app, rid, comment_name,   "Comments: ",  true);
++#endif
+             }
+ 
+           if (app.opts.diffs)
+============================================================
+--- cmd_netsync.cc	ba4c038a24ffe3ba8951da91b859c426c5876571
++++ cmd_netsync.cc	53c66eef7a2cf3c72f235095f960e0add60c8911
+@@ -180,7 +180,11 @@ CMD(pull, "pull", "", CMD_REF(network),
+   find_key_if_needed(addr, include_pattern, exclude_pattern, app, false);
+ 
+   if (app.opts.signing_key() == "")
++#if defined(RSE) /* cosmetics-netsync */
++    P(F("doing anonymous pull"));
++#else
+     P(F("doing anonymous pull; use -kKEYNAME if you need authentication"));
++#endif
+ 
+   run_netsync_protocol(client_voice, sink_role, addr,
+                        include_pattern, exclude_pattern, app);
+@@ -272,7 +276,11 @@ CMD(clone, "clone", "", CMD_REF(network)
+   app.create_workspace(workspace_dir);
+ 
+   if (internal_db)
++#if defined(RSE) /* alt-book-keeping-root */
++    app.set_database(system_path((directory_exists(alt_bookkeeping_root) ? alt_bookkeeping_root : bookkeeping_root) / ws_internal_db_file_name));
++#else
+     app.set_database(system_path(bookkeeping_root / ws_internal_db_file_name));
++#endif
+   else
+     app.set_database(app.opts.dbname);
+ 
+@@ -300,7 +308,11 @@ CMD(clone, "clone", "", CMD_REF(network)
+                      app, false);
+ 
+   if (app.opts.signing_key() == "")
++#if defined(RSE) /* cosmetics-netsync */
++    P(F("doing anonymous pull"));
++#else
+     P(F("doing anonymous pull; use -kKEYNAME if you need authentication"));
++#endif
+ 
+   if (!app.db.var_exists(default_include_pattern_key)
+       || app.opts.set_default)
+============================================================
+--- cmd_ws_commit.cc	b29545c7fd88a94d14d3b6955505e7e179c70d73
++++ cmd_ws_commit.cc	4c9aa3fac75398d68f9f23838ee5559614694df5
+@@ -1337,7 +1337,11 @@ CMD_NO_WORKSPACE(import, "import", "", C
+   catch (...)
+     {
+       // clean up before rethrowing
++#if defined(RSE) /* alt-book-keeping-root */
++      delete_dir_recursive(directory_exists(alt_bookkeeping_root) ? bookkeeping_root : bookkeeping_root);
++#else
+       delete_dir_recursive(bookkeeping_root);
++#endif
+       throw;
+     }
+ 
+============================================================
+--- diff_patch.cc	943b5d68699b7ae6e06c5f335d8445cb961dabff
++++ diff_patch.cc	318048c061524bb07d579c863722aa8bdd95b159
+@@ -1319,6 +1319,9 @@ make_diff(string const & filename1,
+     {
+       case unified_diff:
+       {
++#if defined(RSE) /* diff-index */
++        ost << "Index: " << filename2 << '\n';
++#endif
+         ost << "--- " << filename1 << '\t' << id1 << '\n';
+         ost << "+++ " << filename2 << '\t' << id2 << '\n';
+ 
+@@ -1328,6 +1331,9 @@ make_diff(string const & filename1,
+       }
+       case context_diff:
+       {
++#if defined(RSE) /* diff-index */
++        ost << "Index: " << filename2 << '\n';
++#endif
+         ost << "*** " << filename1 << '\t' << id1 << '\n';
+         ost << "--- " << filename2 << '\t' << id2 << '\n';
+ 
+============================================================
+--- file_io.cc	358fb964dc42e7f936a136342b93bb3a4744d1b3
++++ file_io.cc	6b452acaa58ca24fa5611ea3e6e82e83a7cf7552
+@@ -398,16 +398,36 @@ write_data(file_path const & path, data 
+ write_data(file_path const & path, data const & dat)
+ {
+   // use the bookkeeping root as the temporary directory.
++#if defined(RSE) /* alt-book-keeping-root */
++  if (directory_exists(alt_bookkeeping_root)) {
++      assert_path_is_directory(alt_bookkeeping_root);
++      write_data_impl(path, dat, alt_bookkeeping_root, false);
++  }
++  else {
++#endif
+   assert_path_is_directory(bookkeeping_root);
+   write_data_impl(path, dat, bookkeeping_root, false);
++#if defined(RSE) /* alt-book-keeping-root */
++  }
++#endif
+ }
+ 
+ void
+ write_data(bookkeeping_path const & path, data const & dat)
+ {
+   // use the bookkeeping root as the temporary directory.
++#if defined(RSE) /* alt-book-keeping-root */
++  if (directory_exists(alt_bookkeeping_root)) {
++    assert_path_is_directory(alt_bookkeeping_root);
++    write_data_impl(path, dat, alt_bookkeeping_root, false);
++  }
++  else {
++#endif
+   assert_path_is_directory(bookkeeping_root);
+   write_data_impl(path, dat, bookkeeping_root, false);
++#if defined(RSE) /* alt-book-keeping-root */
++  }
++#endif
+ }
+ 
+ void
+============================================================
+--- lua_hooks.cc	1d95c581d5880c74fd9c941fd69e2564d624d2e2
++++ lua_hooks.cc	cf4f72def48ec7c7a4847342365971ed356376ac
+@@ -144,7 +144,11 @@ lua_hooks::workspace_rcfilename(bookkeep
+ void
+ lua_hooks::workspace_rcfilename(bookkeeping_path & file)
+ {
++#if defined(RSE) /* alt-book-keeping-root */
++  file = (directory_exists(alt_bookkeeping_root) ? alt_bookkeeping_root : bookkeeping_root) / "monotonerc";
++#else
+   file = bookkeeping_root / "monotonerc";
++#endif
+ }
+ 
+ 
+============================================================
+--- monotone.cc	424f3537c4ae32633fe643e0e82bbb3b252722c7
++++ monotone.cc	c4cd82fb52df543069cdfe4ff574ae74ac8f3efa
+@@ -220,12 +220,28 @@ cpp_main(int argc, char ** argv)
+               if (!app.opts.dbname.empty())
+                 app.db.set_filename(app.opts.dbname);
+             }
++#if defined(RSE) /* environment-variables */
++          else
++            {
++              char *cp;
++              if ((cp = getenv("MTN_DBFILE")) != NULL)
++                app.db.set_filename(system_path(cp));
++            }
++#endif
+ 
+           if (app.opts.key_dir_given || app.opts.conf_dir_given)
+             {
+               if (!app.opts.key_dir.empty())
+                 app.keys.set_key_dir(app.opts.key_dir);
+             }
++#if defined(RSE) /* environment-variables */
++          else
++            {
++              char *cp;
++              if ((cp = getenv("MTN_KEYDIR")) != NULL)
++                app.keys.set_key_dir(system_path(cp));
++            }
++#endif
+ 
+           // stop here if they asked for help
+           if (app.opts.help)
+============================================================
+--- options_list.hh	54ee12e3dfb608ca3a4b9a64cc51a845fc4a0501
++++ options_list.hh	b451bb8d5c5614e3ceb9b597267f7faab287e1fc
+@@ -200,6 +200,24 @@ OPTION(diff_options, no_show_encloser, f
+   no_show_encloser = true;
+ }
+ #endif
++#if defined(RSE) /* cosmetics-diff-and-log */
++OPTVAR(diff_options, bool, no_show_header, false)
++OPTION(diff_options, no_show_header, false, "no-show-header",
++     gettext_noop("do not show the summary header"))
++#ifdef option_bodies
++{
++  no_show_header = true;
++}
++#endif
++OPTVAR(diff_options, bool, no_show_separator, false)
++OPTION(diff_options, no_show_separator, false, "no-show-separator",
++     gettext_noop("do not show the separator line"))
++#ifdef option_bodies
++{
++  no_show_separator = true;
++}
++#endif
++#endif
+ 
+ OPT(diffs, "diffs", bool, false, gettext_noop("print diffs along with logs"))
+ #ifdef option_bodies
+============================================================
+--- paths.cc	9be0b0ca30c8a3bb03e47ee4bf021f807bf2edef
++++ paths.cc	ef10a0dff0f701fee6a9eb1b94fc2767882fe1b5
+@@ -230,7 +230,11 @@ in_bookkeeping_dir(string const & path)
+ static inline bool
+ in_bookkeeping_dir(string const & path)
+ {
++#if defined(RSE) /* alt-book-keeping-root */
++  if (path.size() == 0 || (path[0] != '_' && path[0] != '.'))
++#else
+   if (path.size() == 0 || (path[0] != '_'))
++#endif
+     return false;
+   if (path.size() == 1 || (path[1] != 'M' && path[1] != 'm'))
+     return false;
+@@ -916,6 +920,9 @@ find_and_go_to_workspace(string const & 
+   // first look for the current name of the bookkeeping directory.
+   // if we don't find it, look for it under the old name, so that
+   // migration has a chance to work.
++#if defined(RSE) /* alt-book-keeping-root */
++  if (!find_bookdir(root, alt_bookkeeping_root_component, current, removed))
++#endif
+   if (!find_bookdir(root, bookkeeping_root_component, current, removed))
+     if (!find_bookdir(root, old_bookkeeping_root_component, current, removed))
+       return false;
+============================================================
+--- paths.hh	adf4ce1cbc60b1f05fb4555178f985648d0bf2c5
++++ paths.hh	05e238ff3f0a98d90402bf5124f5d591bb0cf56a
+@@ -320,6 +320,15 @@ extern path_component const old_bookkeep
+ // for migration
+ extern path_component const old_bookkeeping_root_component;
+ 
++#if defined(RSE) /* alt-book-keeping-root */
++#ifndef MTN_ALT_BKROOT
++#define MTN_ALT_BKROOT ".mtn"
++#endif
++#define MTN_ALT_BKROOT_ARG (getenv("MTN_BKROOT") != NULL ? getenv("MTN_BKROOT") : MTN_ALT_BKROOT)
++#define alt_bookkeeping_root           (bookkeeping_path(MTN_ALT_BKROOT_ARG))
++#define alt_bookkeeping_root_component (path_component(MTN_ALT_BKROOT_ARG))
++#endif
++
+ // this will always be an absolute path
+ class system_path : public any_path
+ {
+============================================================
+--- roster_merge.cc	5cbf793f50cf62a073ce837d337569d4ddb9475b
++++ roster_merge.cc	2a0fa3fcf1d7fb60f0fdca0238d9bdbfc34cb1a1
+@@ -607,6 +607,20 @@ roster_merge(roster_t const & left_paren
+           result.roster.detach_node(n->self);
+           result.illegal_name_conflicts.push_back(conflict);
+         }
++#if defined(RSE) /* alt-book-keeping-root */
++      if (result_root->has_child(alt_bookkeeping_root_component))
++        {
++          illegal_name_conflict conflict;
++          node_t n = result_root->get_child(alt_bookkeeping_root_component);
++          conflict.nid = n->self;
++          conflict.parent_name.first = n->parent;
++          conflict.parent_name.second = n->name;
++          I(n->name == alt_bookkeeping_root_component);
++
++          result.roster.detach_node(n->self);
++          result.illegal_name_conflicts.push_back(conflict);
++        }
++#endif
+     }
+ }
+ 
+============================================================
+--- work.cc	d602424dc046f080220d23b5dc663b93b573284a
++++ work.cc	59a421adeac627d5e3591c39e2334c95be62ccff
+@@ -53,28 +53,44 @@ get_revision_path(bookkeeping_path & m_p
+ static void
+ get_revision_path(bookkeeping_path & m_path)
+ {
++#if defined(RSE) /* alt-book-keeping-root */
++  m_path = (directory_exists(alt_bookkeeping_root) ? alt_bookkeeping_root : bookkeeping_root) / revision_file_name;
++#else
+   m_path = bookkeeping_root / revision_file_name;
++#endif
+   L(FL("revision path is %s") % m_path);
+ }
+ 
+ static void
+ get_options_path(bookkeeping_path & o_path)
+ {
++#if defined(RSE) /* alt-book-keeping-root */
++  o_path = (directory_exists(alt_bookkeeping_root) ? alt_bookkeeping_root : bookkeeping_root) / options_file_name;
++#else
+   o_path = bookkeeping_root / options_file_name;
++#endif
+   L(FL("options path is %s") % o_path);
+ }
+ 
+ static void
+ get_options_path(system_path const & workspace, system_path & o_path)
+ {
++#if defined(RSE) /* alt-book-keeping-root */
++  o_path = (directory_exists(workspace / alt_bookkeeping_root_component) ? (workspace / alt_bookkeeping_root_component) : (workspace / bookkeeping_root_component)) / options_file_name;
++#else
+   o_path = workspace / bookkeeping_root_component / options_file_name;
++#endif
+   L(FL("options path is %s") % o_path);
+ }
+ 
+ static void
+ get_inodeprints_path(bookkeeping_path & ip_path)
+ {
++#if defined(RSE) /* alt-book-keeping-root */
++  ip_path = (directory_exists(alt_bookkeeping_root) ? alt_bookkeeping_root : bookkeeping_root) / inodeprints_file_name;
++#else
+   ip_path = bookkeeping_root / inodeprints_file_name;
++#endif
+   L(FL("inodeprints path is %s") % ip_path);
+ }
+ 
+@@ -185,7 +201,11 @@ workspace::get_user_log_path(bookkeeping
+ void
+ workspace::get_user_log_path(bookkeeping_path & ul_path)
+ {
++#if defined(RSE) /* alt-book-keeping-root */
++  ul_path = (directory_exists(alt_bookkeeping_root) ? alt_bookkeeping_root : bookkeeping_root) / user_log_file_name;
++#else
+   ul_path = bookkeeping_root / user_log_file_name;
++#endif
+   L(FL("user log path is %s") % ul_path);
+ }
+ 
+@@ -367,7 +387,11 @@ workspace::get_local_dump_path(bookkeepi
+ void
+ workspace::get_local_dump_path(bookkeeping_path & d_path)
+ {
++#if defined(RSE) /* alt-book-keeping-root */
++  d_path = (directory_exists(alt_bookkeeping_root) ? alt_bookkeeping_root : bookkeeping_root) / local_dump_file_name;
++#else
+   d_path = bookkeeping_root / local_dump_file_name;
++#endif
+   L(FL("local dump path is %s") % d_path);
+ }
+ 
+@@ -727,7 +751,11 @@ path_for_detached_nids()
+ static inline bookkeeping_path
+ path_for_detached_nids()
+ {
++#if defined(RSE) /* alt-book-keeping-root */
++  return (directory_exists(alt_bookkeeping_root) ? alt_bookkeeping_root : bookkeeping_root) / "detached";
++#else
+   return bookkeeping_root / "detached";
++#endif
+ }
+ 
+ static inline bookkeeping_path
+@@ -1542,9 +1570,15 @@ workspace::perform_pivot_root(file_path 
+   N(is_dir_t(new_roster.get_node(new_root)),
+     F("proposed new root directory '%s' is not a directory") % new_root);
+   {
++#if defined(RSE) /* alt-book-keeping-root */
++    N(!(new_roster.has_node(new_root / bookkeeping_root_component) || new_roster.has_node(new_root / alt_bookkeeping_root_component)),
++      F("proposed new root directory '%s' contains illegal path %s or %s")
++      % new_root % bookkeeping_root % alt_bookkeeping_root);
++#else
+     N(!new_roster.has_node(new_root / bookkeeping_root_component),
+       F("proposed new root directory '%s' contains illegal path %s")
+       % new_root % bookkeeping_root);
++#endif
+   }
+ 
+   {
+============================================================
+--- work_migration.cc	3d58c3332cd195309eacf5cc52d4e88ad66a6c81
++++ work_migration.cc	f044e25cc757899f97d413f3fe109a9bafe73553
+@@ -55,9 +55,18 @@ get_ws_format()
+ {
+   unsigned int format;
+   bookkeeping_path f_path = bookkeeping_root / "format";
++#if defined(RSE) /* alt-book-keeping-root */
++  bookkeeping_path alt_f_path = alt_bookkeeping_root / "format";
++  if (!file_exists(f_path) && !file_exists(alt_f_path))
++#else
+   if (!file_exists(f_path))
++#endif
+     {
++#if defined(RSE) /* alt-book-keeping-root */
++      if (directory_exists(bookkeeping_root) || directory_exists(alt_bookkeeping_root))
++#else
+       if (directory_exists(bookkeeping_root))
++#endif
+         format = 1;
+       else if (directory_exists(file_path() / old_bookkeeping_root_component))
+         format = 0;
+@@ -69,7 +78,11 @@ get_ws_format()
+       data f_dat;
+       try
+         {
++#if defined(RSE) /* alt-book-keeping-root */
++          read_data(file_exists(alt_f_path) ? alt_f_path : f_path, f_dat);
++#else
+           read_data(f_path, f_dat);
++#endif
+           format = lexical_cast<unsigned int>(remove_ws(f_dat()));
+         }
+       catch (exception & e)
+@@ -80,7 +93,11 @@ get_ws_format()
+       if (format == 1)
+         {
+           W(F("_MTN/format should not exist in a format 1 workspace; corrected"));
++#if defined(RSE) /* alt-book-keeping-root */
++          delete_file(file_exists(alt_f_path) ? alt_f_path : f_path);
++#else
+           delete_file(f_path);
++#endif
+         }
+     }
+   return format;
+@@ -90,6 +107,9 @@ workspace::write_ws_format()
+ workspace::write_ws_format()
+ {
+   bookkeeping_path f_path = bookkeeping_root / "format";
++#if defined(RSE) /* alt-book-keeping-root */
++  bookkeeping_path alt_f_path = alt_bookkeeping_root / "format";
++#endif
+   // one or other side of this conditional will always be dead code, but
+   // both sides should be preserved, to document all historical formats.
+   // N.B. this will _not_ do the right thing for format 0.  Which is fine.
+@@ -97,10 +117,19 @@ workspace::write_ws_format()
+     {
+       if (file_exists(f_path))
+         delete_file(f_path);
++#if defined(RSE) /* alt-book-keeping-root */
++      if (file_exists(alt_f_path))
++        delete_file(alt_f_path);
++#endif
+     }
+   else
+     {
+       data f_dat(lexical_cast<string>(current_workspace_format) + "\n");
++#if defined(RSE) /* alt-book-keeping-root */
++      if (directory_exists(alt_bookkeeping_root))
++        write_data(alt_f_path, f_dat);
++      else
++#endif
+       write_data(f_path, f_dat);
+     }
+ }
+@@ -180,7 +209,11 @@ migrate_1_to_2()
+   // information, and _MTN/work does not exist; also, there may be more than
+   // one parent revision, but we do not have to worry about that here.
+ 
++#if defined(RSE) /* alt-book-keeping-root */
++  bookkeeping_path rev_path = (directory_exists(alt_bookkeeping_root) ? alt_bookkeeping_root : bookkeeping_root) / "revision";
++#else
+   bookkeeping_path rev_path = bookkeeping_root / "revision";
++#endif
+   data base_rev_data; MM(base_rev_data);
+   try 
+     {
+@@ -196,7 +229,11 @@ migrate_1_to_2()
+ 
+   cset workcs; 
+   MM(workcs);
++#if defined(RSE) /* alt-book-keeping-root */
++  bookkeeping_path workcs_path = (directory_exists(alt_bookkeeping_root) ? alt_bookkeeping_root : bookkeeping_root) / "work";
++#else
+   bookkeeping_path workcs_path = bookkeeping_root / "work";
++#endif
+   bool delete_workcs = false;
+   if (file_exists(workcs_path))
+     {

+ 12 - 1
monotone/monotone.spec

@@ -33,13 +33,17 @@ Class:        EVAL
 Group:        SCM
 License:      GPL
 Version:      0.36
-Release:      20070808
+Release:      20070909
+
+#   package options
+%option       with_rse  no
 
 #   list of sources
 Source0:      http://monotone.ca/downloads/%{version}/monotone-%{version}.tar.gz
 Source1:      rc.monotone
 Source3:      monotone-setup.sh
 Patch0:       monotone.patch
+Patch1:       monotone.patch.rse
 
 #   build information
 Prefix:       %{l_prefix}
@@ -72,6 +76,9 @@ AutoReqProv:  no
 %prep
     %setup -q
     %patch -p0
+%if "%{with_rse}" == "yes"
+    %patch -p0 -P 1
+%endif
 
 %build
     #   configure program
@@ -79,7 +86,11 @@ AutoReqProv:  no
     CXX="%{l_cxx}" \
     CFLAGS="%{l_cflags -O}" \
     CXXFLAGS="%{l_cxxflags -O}" \
+%if "%{with_rse}" == "yes"
+    CPPFLAGS="%{l_cppflags} -DRSE" \
+%else
     CPPFLAGS="%{l_cppflags}" \
+%endif
     LDFLAGS="%{l_ldflags}" \
     ./configure \
         --prefix=%{l_prefix} \