This is the RSE patchset for the Monotone VCS. The patchset is entirely enclosed in... #if defined(RSE) /* */ [...] #endif ...and this way can be clearly distinguished. The 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-stat: The workspace top-level directory is shown as "" instead of nothing. 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. o extra-commands: This adds "mtn fuse", "mtn conflicts", "mtn revision" and "mtn base" commands. They are all simple but convenient Lua wrappers. o dot-mtn-message: Support a ".mtn-message" file in the root-directory as a template for the commit messages. Ralf S. Engelschall rse@engelschall.com www.engelschall.com Index: app_state.cc --- app_state.cc.orig 2007-12-12 20:45:21 +0100 +++ app_state.cc 2007-12-13 08:59:14 +0100 @@ -138,13 +138,24 @@ 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(); Index: cmd_diff_log.cc --- cmd_diff_log.cc.orig 2007-12-12 20:45:27 +0100 +++ cmd_diff_log.cc 2007-12-13 08:59:14 +0100 @@ -96,6 +96,27 @@ set const & s, size_t max_cols) { +#if defined(RSE) /* cosmetics-diff-and-log */ + size_t cols = 4; + os << " "; + for (set::const_iterator i = s.begin(); + i != s.end(); i++) + { + const string str = lexical_cast(*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::const_iterator i = s.begin(); @@ -113,6 +134,7 @@ cols += str.size() + 1; } os << '\n'; +#endif } void @@ -131,7 +153,11 @@ for (map::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'; } @@ -232,8 +258,13 @@ set 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::const_iterator i = cs.files_added.begin(); @@ -242,6 +273,9 @@ 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 lines; @@ -288,6 +322,9 @@ 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); @@ -503,6 +540,9 @@ data summary; write_cset(included, summary); +#if defined(RSE) /* cosmetics-diff-and-log */ + if (!app.opts.no_show_header) { +#endif vector lines; split_into_lines(summary(), lines); cout << "#\n"; @@ -518,6 +558,9 @@ cout << "# " << _("no changes") << '\n'; } cout << "#\n"; +#if defined(RSE) /* cosmetics-diff-and-log */ + } +#endif if (app.opts.diff_format == external_diff) { @@ -881,7 +924,11 @@ 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; @@ -896,12 +943,21 @@ for (set::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()) { @@ -911,7 +967,11 @@ } 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) Index: cmd_netsync.cc --- cmd_netsync.cc.orig 2007-12-12 20:45:28 +0100 +++ cmd_netsync.cc 2007-12-13 08:59:14 +0100 @@ -179,7 +179,11 @@ 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 std::list uris; uris.push_back(addr); @@ -277,7 +281,11 @@ 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); @@ -299,7 +307,11 @@ 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) Index: cmd_ws_commit.cc --- cmd_ws_commit.cc.orig 2007-12-12 20:45:28 +0100 +++ cmd_ws_commit.cc 2007-12-13 08:59:14 +0100 @@ -66,7 +66,14 @@ for (set::const_iterator i = cs.dirs_added.begin(); i != cs.dirs_added.end(); ++i) +#if defined(RSE) /* cosmetics-stat */ + if ((*i) == file_path()) + out += (F(" added \"\"")).str() += '\n'; + else + out += (F(" added %s") % *i).str() += '\n'; +#else out += (F(" added %s") % *i).str() += '\n'; +#endif for (map::const_iterator i = cs.files_added.begin(); i != cs.files_added.end(); ++i) @@ -1355,7 +1362,11 @@ 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; } Index: diff_patch.cc --- diff_patch.cc.orig 2007-12-12 20:45:30 +0100 +++ diff_patch.cc 2007-12-13 08:59:14 +0100 @@ -1324,6 +1324,9 @@ { case unified_diff: { +#if defined(RSE) /* diff-index */ + ost << "Index: " << filename2 << '\n'; +#endif ost << "--- " << filename1 << '\t' << id1 << '\n'; ost << "+++ " << filename2 << '\t' << id2 << '\n'; @@ -1333,6 +1336,9 @@ } case context_diff: { +#if defined(RSE) /* diff-index */ + ost << "Index: " << filename2 << '\n'; +#endif ost << "*** " << filename1 << '\t' << id1 << '\n'; ost << "--- " << filename2 << '\t' << id2 << '\n'; Index: file_io.cc --- file_io.cc.orig 2007-12-12 20:45:31 +0100 +++ file_io.cc 2007-12-13 08:59:14 +0100 @@ -398,16 +398,36 @@ 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 Index: lua_hooks.cc --- lua_hooks.cc.orig 2007-12-12 20:45:33 +0100 +++ lua_hooks.cc 2007-12-13 08:59:14 +0100 @@ -162,7 +162,11 @@ 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 } Index: monotone.cc --- monotone.cc.orig 2007-12-12 20:45:33 +0100 +++ monotone.cc 2007-12-13 08:59:14 +0100 @@ -229,12 +229,28 @@ 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 // at this point we allow a workspace (meaning search for it // and if found read _MTN/options, but don't use the data quite Index: options_list.hh --- options_list.hh.orig 2007-12-12 20:45:35 +0100 +++ options_list.hh 2007-12-13 08:59:14 +0100 @@ -178,6 +178,24 @@ 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 Index: paths.cc --- paths.cc.orig 2007-12-12 20:45:35 +0100 +++ paths.cc 2007-12-13 08:59:14 +0100 @@ -226,7 +226,11 @@ 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; @@ -919,6 +923,9 @@ // 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; Index: paths.hh --- paths.hh.orig 2007-12-12 20:45:35 +0100 +++ paths.hh 2007-12-13 08:59:14 +0100 @@ -325,6 +325,15 @@ // for migration #define old_bookkeeping_root_component (path_component("MT")) +#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 { Index: roster_merge.cc --- roster_merge.cc.orig 2007-12-12 20:45:37 +0100 +++ roster_merge.cc 2007-12-13 08:59:14 +0100 @@ -633,6 +633,20 @@ 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 } } Index: std_hooks.lua --- std_hooks.lua.orig 2007-12-12 20:45:39 +0100 +++ std_hooks.lua 2007-12-13 10:12:23 +0100 @@ -284,6 +284,15 @@ if user_log_message == "" or string.sub(user_log_message, -1) ~= "\n" then tmp:write("\n") end + -- #if defined(RSE) /* dot-mtn-message */ + local template_log_message = read_contents_of_file(".mtn-message", "r") + if template_log_message ~= nil then + tmp:write(template_log_message) + if template_log_message == "" or string.sub(template_log_message, -1) ~= "\n" then + tmp:write("\n") + end + end + -- #endif tmp:write(basetext) io.close(tmp) @@ -1220,4 +1229,165 @@ function push_netsync_notifier(notifier) return push_hook_functions(notifier) end -end \ No newline at end of file +end + +-- #if defined(RSE) /* extra-command */ + +-- extra command: "mtn fuse REVISION" +register_command( + "fuse", "REVISION", + "Fuse revision into workspace with conflict markers.", + "Fuse the specified revision into the current workspace by merging " .. + "the revision into the workspace while providing inline conflict " .. + "markers for manually resolving the conflicts in the workspace " .. + "before comitting the conflicts-resolved workspace as the new " .. + "merged revision.", + "command_fuse" +) +function command_fuse(revision) + if revision == nil then + io.stderr:write("mtn: fuse: ERROR: revision not given\n") + return + end + if program_exists_in_path("mtn") == 0 then + io.stderr:write("mtn: fuse: ERROR: require Monotone command \"mtn\" in PATH\n") + return + end + mtn_automate("get_option", "branch") -- make sure we have a valid workspace + local cmd = + "MTN_MERGE=diffutils " .. + "MTN_MERGE_DIFFUTILS=\"partial,diff3opts=-E\" " .. + "mtn " .. "merge_into_workspace " .. revision + local rc = execute("sh", "-c", cmd) + if rc ~= 0 then + io.stderr:write("mtn: fuse: ERROR: failed to execute command \"" .. cmd .. "\"\n") + end +end + +-- extra command: "mtn conflicts" +register_command( + "conflicts", "", + "Lists files in workspace containing conflict markers.", + "Lists all files in the current workspace containing the " .. + "conflict markers produced by GNU diffutils' \"diff3\" " .. + "command. This indicates still unresolved merge conflicts.", + "command_conflicts" +) +function command_conflicts() + if program_exists_in_path("egrep") == 0 then + io.stderr:write("mtn: conflicts: ERROR: require GNU grep command \"egrep\" in PATH\n") + return + end + mtn_automate("get_option", "branch") -- make sure we have a valid workspace + local rc = execute( + "egrep", + "--files-with-matches", + "--recursive", + "^(<<<<<<<|=======|>>>>>>>) ", + "." + ) +end + +-- extra command: "mtn rev[ision] REVISION [ANCESTOR-REVISION]" +register_command( + "revision", "REVISION [ANCESTOR-REVISION]", + "Shows summary information about revision(s)", + "Shows summary information about a particular revision " .. + "(or a range of revisions in case an ancestor revision is also specified). " .. + "This is just a convenience wrapper command around \"mtn log --diffs\".", + "command_revision" +) +alias_command( + "revision", + "rev" +) +function command_revision(revision, ancestor) + if revision == nil then + io.stderr:write("mtn: revision: ERROR: no revision specified\n") + return + end + if ancestor == nil then + ancestor = revision + end + mtn_automate("get_option", "branch") -- make sure we have a valid workspace + execute("mtn", "log", "--diffs", "--no-graph", "--from", ancestor, "--to", revision) + if rc ~= 0 then + io.stderr:write("mtn: revision: ERROR: failed to execute\n") + end +end + +-- extra command: "mtn base {upgrade|diff}" +register_command( + "base", "upgrade|diff", + "Upgrades or compares current branch against base branch", + "Upgrade current branch from base branch or compares current " .. + "branch against base branch. The base branch has to be stored " .. + "either in the \"mtn:base\" attribute of the root directory " .. + "or in a \".mtn-base\" file in the root directory.", + "command_base" +) +function command_base(op) + -- sanity check command line + if op == nil then + io.stderr:write("mtn: base: ERROR: no operation specified\n") + return + end + if op ~= "upgrade" and op ~= "diff" then + io.stderr:write("mtn: base: ERROR: either \"upgrade\" or \"diff\" operation has to be specified\n") + return + end + + -- determine current branch of workspace + local branch_this = nil + local rc, txt = mtn_automate("get_option", "branch") + if txt ~= nil then + branch_this = string.match(txt, "^%s*(%S+)%s*$") + end + if branch_this == nil then + io.stderr:write("mtn: base: ERROR: failed to determine current branch\n") + return + end + + -- determine base branch of workspace + local branch_base = nil + local rc, txt = mtn_automate("get_attributes", ".") + if txt ~= nil then + branch_base = string.match(txt, "attr%s+\"mtn:base\"%s+\"([^\"]+)\"") + end + if branch_base == nil then + local txt = read_contents_of_file(".mtn-base", "r") + if txt ~= nil then + branch_base = string.match(txt, "^%s*(%S+)%s*$") + end + end + if branch_base == nil then + io.stderr:write("mtn: base: ERROR: failed to determine base branch\n") + return + end + + -- dispatch according to operation + if op == "upgrade" then + -- upgrade current branch by merging in revisions of base branch + local rc = execute("mtn", "propagate", branch_base, branch_this) + if rc ~= 0 then + io.stderr:write("mtn: revision: ERROR: failed to execute \"mtn propagate\"\n") + return + end + rc = execute("mtn", "update") + if rc ~= 0 then + io.stderr:write("mtn: revision: ERROR: failed to execute \"mtn update\"\n") + return + end + elseif op == "diff" then + -- upgrade current branch by merging in revisions of base branch + local rc = execute("mtn", "diff", "-r", "h:" .. branch_base, "-r", "h:" .. branch_this) + if rc ~= 0 then + io.stderr:write("mtn: revision: ERROR: failed to execute \"mtn diff\"\n") + return + end + end + return +end + +-- #endif + Index: work.cc --- work.cc.orig 2007-12-12 20:45:48 +0100 +++ work.cc 2007-12-13 08:59:14 +0100 @@ -53,28 +53,44 @@ 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); } @@ -205,7 +221,11 @@ 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); } @@ -387,7 +407,11 @@ 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); } @@ -747,7 +771,11 @@ 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 @@ -1483,9 +1511,15 @@ 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 } { Index: work_migration.cc --- work_migration.cc.orig 2007-12-12 20:45:48 +0100 +++ work_migration.cc 2007-12-13 08:59:14 +0100 @@ -55,9 +55,18 @@ { 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 @@ 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(remove_ws(f_dat())); } catch (exception & e) @@ -80,7 +93,11 @@ 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() { 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 @@ { 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(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 @@ // 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 @@ 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)) {