Forráskód Böngészése

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 éve
szülő
commit
a06d0ad73c
2 módosított fájl, 704 hozzáadás és 1 törlés
  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} \