You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1200 lines
43 KiB
1200 lines
43 KiB
|
|
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-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. |
|
|
|
o lua-rel-path: |
|
Support for additional Lua function workspace_relpath() for |
|
receiving the "initial relative path" within the workspace (which |
|
is important to know because in a Lua hook the current working |
|
directory was changed to the workspace root). |
|
|
|
Ralf S. Engelschall |
|
rse@engelschall.com |
|
www.engelschall.com |
|
|
|
=================================================================== |
|
Index: cmd_diff_log.cc |
|
--- cmd_diff_log.cc 37b1cfffa001ccc5b813fe6f0e84dc6a5dc3996e |
|
+++ cmd_diff_log.cc 4d6a26b3146f903df899a4777f8f556c7e5704e4 |
|
@@ -99,6 +99,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(); |
|
@@ -116,6 +137,7 @@ print_indented_set(ostream & os, |
|
cols += str.size() + 1; |
|
} |
|
os << '\n'; |
|
+#endif |
|
} |
|
|
|
void |
|
@@ -134,7 +156,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'; |
|
} |
|
|
|
@@ -229,7 +255,12 @@ static void |
|
} |
|
|
|
static void |
|
+#if defined(RSE) /* cosmetics-diff-and-log */ |
|
+dump_diffs(app_state & app, |
|
+ lua_hooks & lua, |
|
+#else |
|
dump_diffs(lua_hooks & lua, |
|
+#endif |
|
database & db, |
|
cset const & cs, |
|
set<file_path> const & paths, |
|
@@ -240,8 +271,13 @@ dump_diffs(lua_hooks & lua, |
|
bool show_encloser, |
|
bool limit_paths) |
|
{ |
|
+#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(); |
|
@@ -250,6 +286,9 @@ dump_diffs(lua_hooks & lua, |
|
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; |
|
@@ -296,6 +335,9 @@ dump_diffs(lua_hooks & lua, |
|
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'; |
|
|
|
if (old_is_archived) |
|
@@ -342,7 +384,12 @@ static void |
|
} |
|
|
|
static void |
|
+#if defined(RSE) /* cosmetics-diff-and-log */ |
|
+dump_diffs(app_state & app, |
|
+ lua_hooks & lua, |
|
+#else |
|
dump_diffs(lua_hooks & lua, |
|
+#endif |
|
database & db, |
|
cset const & cs, |
|
std::ostream & output, |
|
@@ -352,8 +399,13 @@ dump_diffs(lua_hooks & lua, |
|
bool show_encloser) |
|
{ |
|
set<file_path> dummy; |
|
+#if defined(RSE) /* cosmetics-diff-and-log */ |
|
+ dump_diffs(app, lua, db, cs, dummy, output, |
|
+ diff_format, new_is_archived, old_is_archived, show_encloser, false); |
|
+#else |
|
dump_diffs(lua, db, cs, dummy, output, |
|
diff_format, new_is_archived, old_is_archived, show_encloser, false); |
|
+#endif |
|
} |
|
|
|
// common functionality for diff and automate content_diff to determine |
|
@@ -569,9 +621,15 @@ CMD(diff, "diff", "di", CMD_REF(informat |
|
} |
|
else |
|
{ |
|
+#if defined(RSE) /* cosmetics-diff-and-log */ |
|
+ dump_diffs(app, app.lua, db, included, cout, |
|
+ app.opts.diff_format, new_is_archived, old_is_archived, |
|
+ !app.opts.no_show_encloser); |
|
+#else |
|
dump_diffs(app.lua, db, included, cout, |
|
app.opts.diff_format, new_is_archived, old_is_archived, |
|
!app.opts.no_show_encloser); |
|
+#endif |
|
} |
|
} |
|
|
|
@@ -606,8 +664,13 @@ CMD_AUTOMATE(content_diff, N_("[FILE [.. |
|
dump_header(dummy_header, included, output, false); |
|
} |
|
|
|
+#if defined(RSE) /* cosmetics-diff-and-log */ |
|
+ dump_diffs(app, app.lua, db, included, output, |
|
+ app.opts.diff_format, new_is_archived, old_is_archived, !app.opts.no_show_encloser); |
|
+#else |
|
dump_diffs(app.lua, db, included, output, |
|
app.opts.diff_format, new_is_archived, old_is_archived, !app.opts.no_show_encloser); |
|
+#endif |
|
} |
|
|
|
|
|
@@ -1048,7 +1111,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; |
|
|
|
@@ -1063,12 +1130,23 @@ 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'; |
|
+#else |
|
out << _("Ancestor: ") << *anc << '\n'; |
|
+#endif |
|
|
|
+#if defined(RSE) /* cosmetics-diff-and-log */ |
|
+ log_certs(certs, out, author_name, _("Author: "), false); |
|
+ log_date_certs(certs, out, date_fmt, _("Date: "), false); |
|
+ log_certs(certs, out, branch_name, _("Branch: "), false); |
|
+ log_certs(certs, out, tag_name, _("Tag: "), false); |
|
+#else |
|
log_certs(certs, out, author_name, _("Author: "), false); |
|
log_date_certs(certs, out, date_fmt, _("Date: "), false); |
|
log_certs(certs, out, branch_name, _("Branch: "), false); |
|
log_certs(certs, out, tag_name, _("Tag: "), false); |
|
+#endif |
|
|
|
if (!app.opts.no_files && !csum.cs.empty()) |
|
{ |
|
@@ -1078,16 +1156,26 @@ CMD(log, "log", "", CMD_REF(informative) |
|
} |
|
|
|
log_certs(certs, out, changelog_name, _("ChangeLog: "), true); |
|
+#if defined(RSE) /* cosmetics-diff-and-log */ |
|
+ log_certs(certs, out, comment_name, _("Comments: "), true); |
|
+#else |
|
log_certs(certs, out, comment_name, _("Comments: "), true); |
|
+#endif |
|
} |
|
|
|
if (app.opts.diffs) |
|
{ |
|
for (edge_map::const_iterator e = rev.edges.begin(); |
|
e != rev.edges.end(); ++e) |
|
+#if defined(RSE) /* cosmetics-diff-and-log */ |
|
+ dump_diffs(app, app.lua, db, edge_changes(e), diff_paths, out, |
|
+ app.opts.diff_format, true, true, |
|
+ !app.opts.no_show_encloser, !mask.empty()); |
|
+#else |
|
dump_diffs(app.lua, db, edge_changes(e), diff_paths, out, |
|
app.opts.diff_format, true, true, |
|
!app.opts.no_show_encloser, !mask.empty()); |
|
+#endif |
|
} |
|
|
|
if (next > 0) |
|
=================================================================== |
|
Index: cmd_netsync.cc |
|
--- cmd_netsync.cc e70435eb00dcd606984f40ca8b4a53996985fc72 |
|
+++ cmd_netsync.cc 182df7fa258a5858106a8eb038fe4f84083e813b |
|
@@ -519,7 +519,11 @@ CMD(pull, "pull", "", CMD_REF(network), |
|
args, info, false); |
|
|
|
if (!keys.have_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(app, app.opts, app.lua, project, keys, |
|
client_voice, sink_role, info); |
|
@@ -698,9 +702,16 @@ CMD(clone, "clone", "", CMD_REF(network) |
|
|
|
// paths.cc's idea of the current workspace root is wrong at this point |
|
if (internal_db) |
|
+#if defined(RSE) /* alt-book-keeping-root */ |
|
+ app.opts.dbname = system_path((directory_exists(workspace_dir / alt_bookkeeping_root_component) ? |
|
+ (workspace_dir / alt_bookkeeping_root_component) : |
|
+ (workspace_dir / bookkeeping_root_component)) |
|
+ / ws_internal_db_file_name); |
|
+#else |
|
app.opts.dbname = system_path(workspace_dir |
|
/ bookkeeping_root_component |
|
/ ws_internal_db_file_name); |
|
+#endif |
|
|
|
// this is actually stupid, but app.opts.branch must be set here |
|
// otherwise it will not be written into _MTN/options, in case |
|
@@ -725,7 +736,11 @@ CMD(clone, "clone", "", CMD_REF(network) |
|
info, true, true, false); |
|
|
|
if (!keys.have_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 |
|
|
|
// make sure we're back in the original dir so that file: URIs work |
|
change_current_working_dir(start_dir); |
|
=================================================================== |
|
Index: cmd_ws_commit.cc |
|
--- cmd_ws_commit.cc 8f12395a73d4c2fbd19e4eac883b719e581d0ae7 |
|
+++ cmd_ws_commit.cc 490bc6a101d7de1b85203d5c3a135fafbbff59a4 |
|
@@ -94,7 +94,14 @@ revision_summary(revision_t const & rev, |
|
|
|
for (set<file_path>::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<file_path, file_id>::const_iterator i = cs.files_added.begin(); |
|
i != cs.files_added.end(); ++i) |
|
@@ -1493,12 +1500,20 @@ 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) ? alt_bookkeeping_root : bookkeeping_root); |
|
+#else |
|
delete_dir_recursive(bookkeeping_root); |
|
+#endif |
|
throw; |
|
} |
|
|
|
// clean up |
|
+#if defined(RSE) /* alt-book-keeping-root */ |
|
+ delete_dir_recursive(directory_exists(alt_bookkeeping_root) ? alt_bookkeeping_root : bookkeeping_root); |
|
+#else |
|
delete_dir_recursive(bookkeeping_root); |
|
+#endif |
|
} |
|
|
|
CMD_NO_WORKSPACE(migrate_workspace, "migrate_workspace", "", CMD_REF(tree), |
|
=================================================================== |
|
Index: diff_output.cc |
|
--- diff_output.cc 746af1eeaa7fee943bf1264dc88ddd6e218c7866 |
|
+++ diff_output.cc a2e01d5f3517b7393711c3bfca7e7eb5a8b9772b |
|
@@ -566,6 +566,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' |
|
@@ -577,6 +580,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' |
|
=================================================================== |
|
Index: file_io.cc |
|
--- file_io.cc 6683cf8d459a89597caf1eb3ce01800fe4404643 |
|
+++ file_io.cc 4faf0094870242fac6a9d1543e2239448453f407 |
|
@@ -342,16 +342,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 |
|
=================================================================== |
|
Index: lua_hooks.cc |
|
--- lua_hooks.cc d4f06492ebfd19893156cf0021b7afef29009332 |
|
+++ lua_hooks.cc 1041f875567d43f4afd0c5e68c10f96ebecfd219 |
|
@@ -224,7 +224,11 @@ lua_hooks::load_rcfiles(options & opts) |
|
{ |
|
load_rcfile(opts.conf_dir / "monotonerc", false); |
|
} |
|
+#if defined(RSE) /* alt-book-keeping-root */ |
|
+ load_rcfile((directory_exists(alt_bookkeeping_root) ? alt_bookkeeping_root : bookkeeping_root) / "monotonerc", false); |
|
+#else |
|
load_rcfile(bookkeeping_root / "monotonerc", false); |
|
+#endif |
|
} |
|
|
|
// Command-line rcfiles override even that. |
|
=================================================================== |
|
Index: luaext_platform.cc |
|
--- luaext_platform.cc b22b5f7fa127055e909280379694c1635f4923ff |
|
+++ luaext_platform.cc 24765cd8252f31a829d450ef92e002e615c98f9d |
|
@@ -14,6 +14,9 @@ |
|
#include <cstdlib> |
|
|
|
#include "platform.hh" |
|
+#if defined(RSE) /* lua-rel-path */ |
|
+#include "paths.hh" |
|
+#endif |
|
|
|
using std::malloc; |
|
using std::free; |
|
@@ -185,6 +188,15 @@ LUAEXT(get_pid, ) |
|
return 1; |
|
} |
|
|
|
+#if defined(RSE) /* lua-rel-path */ |
|
+LUAEXT(workspace_relpath, ) |
|
+{ |
|
+ std::string str = workspace_initial_relative_path(); |
|
+ lua_pushlstring(LS, str.c_str(), str.size()); |
|
+ return 1; |
|
+} |
|
+#endif |
|
+ |
|
// Local Variables: |
|
// mode: C++ |
|
// fill-column: 76 |
|
=================================================================== |
|
Index: merge_roster.cc |
|
--- merge_roster.cc 9c8e34b5521bde6f9a38f2996ce0edf51273e98d |
|
+++ merge_roster.cc e653e463f7351026b9c90f32962e44f6f316a77c |
|
@@ -724,6 +724,20 @@ roster_merge(roster_t const & left_paren |
|
result.roster.detach_node(n->self); |
|
result.invalid_name_conflicts.push_back(conflict); |
|
} |
|
+#if defined(RSE) /* alt-book-keeping-root */ |
|
+ if (result_root->has_child(alt_bookkeeping_root_component)) |
|
+ { |
|
+ invalid_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.invalid_name_conflicts.push_back(conflict); |
|
+ } |
|
+#endif |
|
} |
|
} |
|
|
|
=================================================================== |
|
Index: migrate_work.cc |
|
--- migrate_work.cc 2a8658dad954b975e65d3ceaf5df608007bfe841 |
|
+++ migrate_work.cc dc14b6fd1d3f80df37ae42f9df1be1253f085724 |
|
@@ -56,9 +56,18 @@ get_workspace_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; |
|
@@ -70,7 +79,11 @@ get_workspace_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) |
|
@@ -82,7 +95,11 @@ get_workspace_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; |
|
@@ -92,6 +109,9 @@ workspace::write_format() |
|
workspace::write_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. |
|
@@ -99,11 +119,20 @@ workspace::write_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", |
|
origin::workspace); |
|
+#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); |
|
} |
|
} |
|
@@ -186,7 +215,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 |
|
{ |
|
@@ -203,7 +236,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)) |
|
{ |
|
=================================================================== |
|
Index: options_list.hh |
|
--- options_list.hh 521e90001833b8023276b7cedd0ed4b3253c1fd4 |
|
+++ options_list.hh e58b1dbae2c4089d3fbfed73f5a9981b9fd02b1e |
|
@@ -331,6 +331,24 @@ OPTION(diff_options, with_header, false, |
|
without_header = false; |
|
} |
|
#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 defa5bd893d6db66107e50122713ee2769ce8d15 |
|
+++ paths.cc ca77119868c66526ccb6c6e024f9c242075774ff |
|
@@ -231,7 +231,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.empty() || (path[0] != '_' && path[0] != '.')) |
|
+#else |
|
if (path.empty() || (path[0] != '_')) |
|
+#endif |
|
return false; |
|
if (path.size() == 1 || (path[1] != 'M' && path[1] != 'm')) |
|
return false; |
|
@@ -1024,6 +1028,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; |
|
@@ -1054,6 +1061,13 @@ mark_std_paths_used(void) |
|
initial_rel_path.get(); |
|
} |
|
|
|
+#if defined(RSE) /* lua-rel-path */ |
|
+string workspace_initial_relative_path(void) |
|
+{ |
|
+ return initial_rel_path.get(); |
|
+} |
|
+#endif |
|
+ |
|
/////////////////////////////////////////////////////////////////////////// |
|
// utility used by migrate_ancestry |
|
/////////////////////////////////////////////////////////////////////////// |
|
=================================================================== |
|
Index: paths.hh |
|
--- paths.hh e92b013f510afba1da74ab8f47a8f2fa799b3b5c |
|
+++ paths.hh 38da34092ece2d3f80317b97197630711c05e393 |
|
@@ -351,6 +351,15 @@ private: |
|
// 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 |
|
{ |
|
@@ -473,8 +482,12 @@ find_new_path_for(std::map<file_path, fi |
|
find_new_path_for(std::map<file_path, file_path> const & renames, |
|
file_path const & old_path); |
|
|
|
+#if defined(RSE) /* lua-rel-path */ |
|
+std::string workspace_initial_relative_path(void); |
|
#endif |
|
|
|
+#endif |
|
+ |
|
// Local Variables: |
|
// mode: C++ |
|
// fill-column: 76 |
|
=================================================================== |
|
Index: std_hooks.lua |
|
--- std_hooks.lua 8d713fef5bf9921b78ac24e07f6d837524e35e9a |
|
+++ std_hooks.lua 1c5fe914add9d8608b50cab633592ad5165688f3 |
|
@@ -304,6 +304,15 @@ function edit_comment(basetext, user_log |
|
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) |
|
|
|
@@ -1442,3 +1451,267 @@ end |
|
|
|
return false |
|
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|integrate}" |
|
+register_command( |
|
+ "base", "fork|upgrade|diff|integrate [BRANCHNAME|FILENAME]", |
|
+ "Forks, upgrades, compares or integrates current branch from/against/into base branch", |
|
+ "Forks a new branch from the current branch, " .. |
|
+ "upgrade current branch from base branch, " .. |
|
+ "or compares current branch against base branch, " .. |
|
+ "or integrates current branch into 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, arg) |
|
+ -- sanity check command line |
|
+ if op == nil then |
|
+ io.stderr:write("mtn: base: ERROR: no operation specified\n") |
|
+ return |
|
+ end |
|
+ if op ~= "fork" and op ~= "upgrade" and op ~= "diff" and op ~= "integrate" then |
|
+ io.stderr:write("mtn: base: ERROR: either \"fork\", \"upgrade\", or \"diff\" or \"integrate\" operation has to be specified\n") |
|
+ return |
|
+ end |
|
+ if op == "fork" and arg == nil then |
|
+ io.stderr:write("mtn: base: ERROR: BRANCHNAME argument missing for \"fork\" operation\n") |
|
+ return |
|
+ end |
|
+ if op == "upgrade" and arg ~= nil then |
|
+ io.stderr:write("mtn: base: ERROR: argument not valid for \"upgrade\" operation\n") |
|
+ return |
|
+ end |
|
+ if op == "integrate" and arg ~= nil then |
|
+ io.stderr:write("mtn: base: ERROR: argument not valid for \"integrate\" operation\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 |
|
+ if op == "upgrade" or op == "diff" or op == "integrate" then |
|
+ 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 |
|
+ end |
|
+ |
|
+ -- dispatch according to operation |
|
+ if op == "fork" then |
|
+ -- fork new branch from current branch |
|
+ io.stderr:write("mtn: base: fork current branch \"" .. branch_this .. "\" into new branch \"" .. arg .. "\"\n") |
|
+ fh = io.open(".mtn-base", "w") |
|
+ fh:write(branch_this) |
|
+ io.close(fh) |
|
+ local rc, txt = mtn_automate("get_attributes", ".mtn-base") |
|
+ if rc ~= 0 then |
|
+ -- .mtn-base still not existing in current branch |
|
+ local rc = execute("mtn", "add", ".mtn-base") |
|
+ if rc ~= 0 then |
|
+ io.stderr:write("mtn: base: ERROR: failed to execute \"mtn add\"\n") |
|
+ return |
|
+ end |
|
+ end |
|
+ rc = execute("mtn", "commit", "-m", "[auto-commit] add hint-file \".mtn-base\" to branch \"" .. arg .. "\"", "-b", arg, ".mtn-base") |
|
+ if rc ~= 0 then |
|
+ io.stderr:write("mtn: base: ERROR: failed to execute \"mtn commit\"\n") |
|
+ return |
|
+ end |
|
+ elseif op == "upgrade" then |
|
+ -- upgrade current branch by merging in revisions of base branch |
|
+ io.stderr:write("mtn: base: upgrade current branch \"" .. branch_this .. "\" from base branch \"" .. branch_base .. "\"\n") |
|
+ local rc = execute("mtn", "propagate", branch_base, branch_this) |
|
+ if rc ~= 0 then |
|
+ io.stderr:write("mtn: base: ERROR: failed to execute \"mtn propagate\"\n") |
|
+ return |
|
+ end |
|
+ rc = execute("mtn", "update") |
|
+ if rc ~= 0 then |
|
+ io.stderr:write("mtn: base: ERROR: failed to execute \"mtn update\"\n") |
|
+ return |
|
+ end |
|
+ elseif op == "diff" then |
|
+ -- upgrade current branch by merging in revisions of base branch |
|
+ io.stderr:write("mtn: base: diff current branch \"" .. branch_this .. "\" against base branch \"" .. branch_base .. "\"\n") |
|
+ local rc |
|
+ if arg ~= nil then |
|
+ if not string.sub(arg, 1, 1) ~= "/" then |
|
+ arg = workspace_relpath() .. "/" .. arg |
|
+ end |
|
+ rc = execute("mtn", "diff", "-r", "h:" .. branch_base, "-r", "h:" .. branch_this, arg) |
|
+ else |
|
+ rc = execute("mtn", "diff", "-r", "h:" .. branch_base, "-r", "h:" .. branch_this) |
|
+ end |
|
+ if rc ~= 0 then |
|
+ io.stderr:write("mtn: base: ERROR: failed to execute \"mtn diff\"\n") |
|
+ return |
|
+ end |
|
+ elseif op == "integrate" then |
|
+ -- integrate back current branch by merging its revision into the base branch |
|
+ io.stderr:write("mtn: base: integrate current branch \"" .. branch_this .. "\" into base branch \"" .. branch_base .. "\"\n") |
|
+ rc = execute("mtn", "rm", ".mtn-base") |
|
+ rc = execute("mtn", "commit", "-m", "[auto-commit] remove hint-file \".mtn-base\" from branch \"" .. branch_this .. "\"", ".mtn-base") |
|
+ if rc ~= 0 then |
|
+ io.stderr:write("mtn: base: ERROR: failed to execute \"mtn commit\"\n") |
|
+ return |
|
+ end |
|
+ local rc = execute("mtn", "propagate", branch_this, branch_base) |
|
+ if rc ~= 0 then |
|
+ io.stderr:write("mtn: base: ERROR: failed to execute \"mtn propagate\"\n") |
|
+ return |
|
+ end |
|
+ local rc = execute("mtn", "update", "-b", branch_base, "-r", "h:" .. branch_base) |
|
+ if rc ~= 0 then |
|
+ io.stderr:write("mtn: base: ERROR: failed to execute \"mtn update\"\n") |
|
+ return |
|
+ end |
|
+ end |
|
+ return |
|
+end |
|
+ |
|
+-- extra command: "mtn init" |
|
+register_command( |
|
+ "init", "BRANCH", |
|
+ "Place local directory under local version control.", |
|
+ "Creates a new _MTN/mtn.db database and places the local " .. |
|
+ "directory tree under version control using this database.", |
|
+ "command_init" |
|
+) |
|
+function command_init(branch) |
|
+ -- sanity check command line |
|
+ if branch == nil then |
|
+ io.stderr:write("mtn: init: ERROR: no branch specified\n") |
|
+ return |
|
+ end |
|
+ |
|
+ -- create new database |
|
+ execute("mtn", "--db=mtn.db", "db", "init") |
|
+ |
|
+ -- place current directory under version control |
|
+ execute("mtn", "--db=mtn.db", "setup", "-b", branch) |
|
+ |
|
+ -- use alternative book-keeping directory name |
|
+ execute("mv", "_MTN", ".mtn") |
|
+ |
|
+ -- place database into book-keeping directory |
|
+ execute("mv", "mtn.db", ".mtn/mtn.db") |
|
+ local txt = read_contents_of_file(".mtn/options") |
|
+ txt = string.gsub(txt, "database \"[^\"]*\"", "database \".mtn/mtn.db\"") |
|
+ options = io.open(".mtn/options", "w") |
|
+ options:write(txt) |
|
+ io.close(options) |
|
+ |
|
+ -- perform a simple operation so that Monotone |
|
+ -- updates the book-keeping directory |
|
+ execute("sh", "-c", "mtn stat >/dev/null 2>&1") |
|
+end |
|
+ |
|
+-- #endif |
|
+ |
|
=================================================================== |
|
Index: unit-tests/merge_roster.cc |
|
--- unit-tests/merge_roster.cc fd6d157c77b4f168bdc1ed29940beea69707e1a3 |
|
+++ unit-tests/merge_roster.cc 8ff5b6ffeab2c6b0f3a00e89e2f6c05c6de7f2ce |
|
@@ -945,7 +945,12 @@ struct simple_invalid_name_conflict : pu |
|
I(!result.is_clean()); |
|
invalid_name_conflict const & c = idx(result.invalid_name_conflicts, 0); |
|
I(c.nid == bad_dir_nid); |
|
+#if defined(RSE) /* alt-book-keeping-root */ |
|
+ I( c.parent_name == make_pair(new_root_nid, bookkeeping_root_component) |
|
+ || c.parent_name == make_pair(new_root_nid, alt_bookkeeping_root_component)); |
|
+#else |
|
I(c.parent_name == make_pair(new_root_nid, bookkeeping_root_component)); |
|
+#endif |
|
// this tests it was detached, implicitly |
|
result.roster.attach_node(bad_dir_nid, file_path_internal("dir_formerly_known_as__MTN")); |
|
result.invalid_name_conflicts.pop_back(); |
|
=================================================================== |
|
Index: unit-tests/paths.cc |
|
--- unit-tests/paths.cc f443111b016125fb2b00af638586853a68369ad9 |
|
+++ unit-tests/paths.cc c14f0b1d89ba65c86af3b3f1591aa7eb694ce126 |
|
@@ -531,7 +531,11 @@ static void check_bk_normalizes_to(char |
|
|
|
static void check_bk_normalizes_to(char const * before, char const * after) |
|
{ |
|
+#if defined(RSE) /* alt-book-keeping-root */ |
|
+ bookkeeping_path bp((directory_exists(alt_bookkeeping_root) ? alt_bookkeeping_root : bookkeeping_root) / before); |
|
+#else |
|
bookkeeping_path bp(bookkeeping_root / before); |
|
+#endif |
|
L(FL("normalizing %s to %s (got %s)") % before % after % bp); |
|
UNIT_TEST_CHECK(bp.as_external() == after); |
|
UNIT_TEST_CHECK(bookkeeping_path(bp.as_internal(), |
|
=================================================================== |
|
Index: work.cc |
|
--- work.cc 4a27d0c0133f6cc04b06944afe080400095676e2 |
|
+++ work.cc b7d8a57ea2935bc09f2e2358fa96685dee44737b |
|
@@ -60,42 +60,66 @@ 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); |
|
} |
|
|
|
static void |
|
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); |
|
} |
|
|
|
static void |
|
get_update_path(bookkeeping_path & update_path) |
|
{ |
|
+#if defined(RSE) /* alt-book-keeping-root */ |
|
+ update_path = (directory_exists(alt_bookkeeping_root) ? alt_bookkeeping_root : bookkeeping_root) / update_file_name; |
|
+#else |
|
update_path = bookkeeping_root / update_file_name; |
|
+#endif |
|
L(FL("update path is %s") % update_path); |
|
} |
|
|
|
@@ -113,7 +137,11 @@ directory_is_workspace(system_path const |
|
{ |
|
// as far as the users of this function are concerned, a version 0 |
|
// workspace (MT directory instead of _MTN) does not count. |
|
+#if defined(RSE) /* alt-book-keeping-root */ |
|
+ return (directory_exists(dir / alt_bookkeeping_root_component) || directory_exists(dir / bookkeeping_root_component)); |
|
+#else |
|
return directory_exists(dir / bookkeeping_root_component); |
|
+#endif |
|
} |
|
|
|
bool workspace::found; |
|
@@ -146,13 +174,24 @@ workspace::create_workspace(options cons |
|
go_to_workspace(new_dir); |
|
mark_std_paths_used(); |
|
|
|
+#if defined(RSE) /* alt-book-keeping-root */ |
|
+ E(!(directory_exists(bookkeeping_root) || directory_exists(alt_bookkeeping_root)), origin::user, |
|
+ F("monotone bookkeeping directory '%s' or '%s' already exists in '%s'") |
|
+ % bookkeeping_root % alt_bookkeeping_root % new_dir); |
|
+#else |
|
E(!directory_exists(bookkeeping_root), origin::user, |
|
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); |
|
|
|
workspace::found = true; |
|
@@ -545,9 +584,16 @@ workspace::get_database_option(system_pa |
|
external_key_name workspace_key; |
|
system_path workspace_keydir; |
|
|
|
+#if defined(RSE) /* alt-book-keeping-root */ |
|
+ system_path o_path = (( directory_exists(workspace / alt_bookkeeping_root_component) |
|
+ ? (workspace / alt_bookkeeping_root_component) |
|
+ : (workspace / bookkeeping_root_component)) |
|
+ / options_file_name); |
|
+#else |
|
system_path o_path = (workspace |
|
/ bookkeeping_root_component |
|
/ options_file_name); |
|
+#endif |
|
read_options_file(o_path, |
|
workspace_database, workspace_branch, |
|
workspace_key, workspace_keydir); |
|
@@ -745,7 +791,11 @@ workspace::get_local_dump_path(bookkeepi |
|
{ |
|
E(workspace::found, origin::user, F("workspace required but not found")); |
|
|
|
+#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); |
|
} |
|
|
|
@@ -1170,7 +1220,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 |
|
@@ -1974,9 +2028,15 @@ workspace::perform_pivot_root(database & |
|
E(is_dir_t(old_roster.get_node(new_root)), origin::user, |
|
F("proposed new root directory '%s' is not a directory") % new_root); |
|
{ |
|
+#if defined(RSE) /* alt-book-keeping-root */ |
|
+ E(!(new_roster.has_node(new_root / bookkeeping_root_component) || new_roster.has_node(new_root / alt_bookkeeping_root_component)), origin::user, |
|
+ F("proposed new root directory '%s' contains illegal path %s or %s") |
|
+ % new_root % bookkeeping_root % alt_bookkeeping_root); |
|
+#else |
|
E(!old_roster.has_node(new_root / bookkeeping_root_component), origin::user, |
|
F("proposed new root directory '%s' contains illegal path %s") |
|
% new_root % bookkeeping_root); |
|
+#endif |
|
} |
|
|
|
{
|
|
|