#
# add_file "tests/t_bad_packets.at"
#
# add_file "tests/t_inodeprints_hook.at"
#
# patch "ChangeLog"
# from [ad815709db8896a9323a4ffd2f1ee711529bf5b0]
# to [fa1d4b7e493828ddd605f870b1a85588d644a1ea]
#
# patch "app_state.cc"
# from [715d0beb6780ce3ea77b0934ceb4f5a4fbc0293b]
# to [a7ed8e649668aca70e915e9071469219ecf9db75]
#
# patch "commands.cc"
# from [588e56b9de4a9ff6e0146177ed642787db7b64a2]
# to [6536a5fec8f4c742203ff8b03081b958c2b44be3]
#
# patch "lua.cc"
# from [ee8e38e41928d17b8903309f71265e859443c43e]
# to [324daba07afed4fccaa12d4c7bab4f02d744e705]
#
# patch "lua.hh"
# from [9e6604ebd9285f905820bd95e92fb68c402807ce]
# to [5e22c1d5555fc59e29b639fdec14696f3804feca]
#
# patch "monotone.texi"
# from [66422aaa133c5bdab836f44a592cee17421004aa]
# to [7eeb1754841491852c6101dddadee3d1435a85d6]
#
# patch "std_hooks.lua"
# from [245cf5ff0a0858e6436cc1d44bbba982f0afbc6f]
# to [d9f8c4acffb845da040ee403b42bf4d1dad79d5b]
#
# patch "tests/t_bad_packets.at"
# from []
# to [2f4b3f6509ae0d401eff37a7d6a6fae327779a21]
#
# patch "tests/t_inodeprints_hook.at"
# from []
# to [7a63f3be8cd9f0f003ffe3b0372e9c4d33fcc034]
#
# patch "testsuite.at"
# from [9caba90d174e7b550907e836847f65dca5ee502e]
# to [4e74e752f40c74925d7279cf87626cfbc66cb726]
#
# patch "work.cc"
# from [1b1687d4db3d2daf7748b642d52c5fa844c251a9]
# to [168c7482e944a7fc1c8b70b72615f8312a3a31bd]
#
# patch "work.hh"
# from [1e96bd36f787031f743d29cc033bfd1cc1a9c8e2]
# to [41939ab23e00e777cc07da3df1b31a74082c0ae8]
#
--- ChangeLog
+++ ChangeLog
@@ -1,5 +1,23 @@
2005-04-20 Nathaniel Smith
+ * commands.cc (mdelta, mdata, fdelta, fdata, rdata): Check for
+ existence of command line arguments.
+
+ * lua.{cc,hh} (hook_use_inodeprints): New hook.
+ * std_hooks.lua (use_inodeprints): Default definition.
+ * monotone.texi (Inodeprints): New section.
+ (Reserved Files): Document MT/inodeprints.
+ (Hook Reference): Document use_inodeprints.
+ * work.{cc,hh} (enable_inodeprints): New function.
+ * app_state.cc (create_working_copy): Maybe call
+ enable_inodeprints.
+
+ * tests/t_inodeprints_hook.at: New test.
+ * tests/t_bad_packets.at: New test.
+ * testsuite.at: Add them.
+
+2005-04-20 Nathaniel Smith
+
* AUTHORS: Actually add Joel Reed (oops).
2005-04-20 Nathaniel Smith
--- app_state.cc
+++ app_state.cc
@@ -139,6 +139,9 @@
blank_user_log();
+ if (lua.hook_use_inodeprints())
+ enable_inodeprints();
+
load_rcfiles();
}
--- commands.cc
+++ commands.cc
@@ -2126,7 +2126,9 @@
complete(app, idx(args, 0)(), m_old_id);
complete(app, idx(args, 1)(), m_new_id);
+ N(app.db.manifest_version_exists(m_old_id), F("no such manifest %s") % m_old_id);
app.db.get_manifest(m_old_id, m_old);
+ N(app.db.manifest_version_exists(m_new_id), F("no such manifest %s") % m_new_id);
app.db.get_manifest(m_new_id, m_new);
delta del;
@@ -2148,7 +2150,9 @@
complete(app, idx(args, 0)(), f_old_id);
complete(app, idx(args, 1)(), f_new_id);
+ N(app.db.file_version_exists(f_old_id), F("no such file %s") % f_old_id);
app.db.get_file_version(f_old_id, f_old_data);
+ N(app.db.file_version_exists(f_new_id), F("no such file %s") % f_new_id);
app.db.get_file_version(f_new_id, f_new_data);
delta del;
diff(f_old_data.inner(), f_new_data.inner(), del);
@@ -2167,6 +2171,7 @@
complete(app, idx(args, 0)(), r_id);
+ N(app.db.revision_exists(r_id), F("no such revision %s") % r_id);
app.db.get_revision(r_id, r_data);
pw.consume_revision_data(r_id, r_data);
}
@@ -2183,6 +2188,7 @@
complete(app, idx(args, 0)(), m_id);
+ N(app.db.manifest_version_exists(m_id), F("no such manifest %s") % m_id);
app.db.get_manifest_version(m_id, m_data);
pw.consume_manifest_data(m_id, m_data);
}
@@ -2200,6 +2206,7 @@
complete(app, idx(args, 0)(), f_id);
+ N(app.db.file_version_exists(f_id), F("no such file %s") % f_id);
app.db.get_file_version(f_id, f_data);
pw.consume_file_data(f_id, f_data);
}
--- lua.cc
+++ lua.cc
@@ -883,6 +883,20 @@
}
+bool
+lua_hooks::hook_use_inodeprints()
+{
+ bool use = false, exec_ok = false;
+
+ exec_ok = Lua(st)
+ .push_str("use_inodeprints")
+ .get_fn()
+ .call(0, 1)
+ .extract_bool(use)
+ .ok();
+ return use && exec_ok;
+}
+
bool
lua_hooks::hook_get_netsync_read_permitted(std::string const & collection,
rsa_keypair_id const & identity)
--- lua.hh
+++ lua.hh
@@ -94,6 +94,9 @@
file_path const & b,
file_path & res);
+ // working copy hooks
+ bool hook_use_inodeprints();
+
// attribute hooks
bool hook_init_attributes(file_path const & filename,
std::map & attrs);
--- monotone.texi
+++ monotone.texi
@@ -2220,6 +2220,7 @@
* Selectors:: Selecting revisions by certificate.
* Restrictions:: Limit working copy changes to specified files.
* Scripting:: Running monotone from other programs.
+* Inodeprints:: Trading off safety for speed in your working copy.
* Quality Assurance:: Integrating testing and review with development.
* Vars:: Simple per-database configuration information.
* Reserved Files:: File names with special meanings.
@@ -2445,6 +2446,43 @@
For details of this interface, see @ref{Automation}.
@page
address@hidden Inodeprints
address@hidden Inodeprints
+
+Fairly often, in order to accomplish its job, monotone has to look at
+your working copy and figure out what has been changed in it since your
+last commit. Commands that do this include @command{status},
address@hidden, @command{update}, @command{commit}, and others. There
+are two different techniques it can use to do this. The default, which
+is sufficient for most projects, is to simply read every file in the
+working copy, compute their @sc{sha1} hash, and compare them to the
+hashes monotone has stored. This is very safe and reliable, and turns
+out to be fast enough for most projects. However, on very large
+projects, ones whose source trees are many megabytes in size, it can
+become unacceptably slow.
+
+The other technique, known as @emph{inodeprints}, is designed for this
+situation. When running in inodeprints mode, monotone does not read the
+whole working copy; rather, it keeps a cache of interesting information
+about each file (its size, its last modification time, and so on), and
+skips reading any file for which these values have not changed. This is
+inherently somewhat less safe, and, as mentioned above, unnecessary for
+most projects, so it is disabled by default.
+
+If you do determine that it is necessary to use inodeprints with your
+project, it is simple to enable them. A working copy is in inodeprints
+mode if a file @file{MT/inodeprints} exist. You can simply create an
+empty file with this name, and the next time you commit or update,
+monotone will automatically populate it with cache information. You can
+at any point delete this file or truncate it; monotone uses it only as a
+cache and will operate correctly if it is removed.
+
+Normally, instead of enabling this up on a per-working-copy basis, you
+will want to simply define the @code{use_inodeprints} hook to return
address@hidden; this will automatically enable inodeprints mode in any new
+working copies you create. See @ref{Hook Reference} for details.
+
address@hidden
@node Quality Assurance
@section Quality Assurance
@@ -2628,6 +2666,9 @@
commit. The user may add content to this file while they work. Upon a
successful commit monotone will empty the file making it ready for the
next edit/commit cycle.
address@hidden MT/inodeprints
+If this file exists, monotone considers the directory to be in
address@hidden mode, and uses this file to cache the inodeprints.
@item MT/debug
If monotone detects a bug in itself or crashes, then before exiting it
dumps a log of its recent activity to this file, to aid in debugging.
@@ -4661,6 +4702,22 @@
@end smallexample
address@hidden use_inodeprints ()
+
+Returns @code{true} if you want monotone to automatically enable
address@hidden support in all working copies. Only affects working
+copies created after you modify the hook.
+
+The default definition of this hook is:
address@hidden
address@hidden
+function use_inodeprints()
+ return false
+end
address@hidden group
address@hidden smallexample
+
+
@item get_netsync_read_permitted (@var{collection}, @var{identity})
Returns @code{true} if a peer authenticated as key @var{identity}
--- std_hooks.lua
+++ std_hooks.lua
@@ -433,3 +433,7 @@
return nil
end
+
+function use_inodeprints()
+ return false
+end
--- tests/t_bad_packets.at
+++ tests/t_bad_packets.at
@@ -0,0 +1,15 @@
+AT_SETUP([bad packet args])
+MONOTONE_SETUP
+
+AT_CHECK(MONOTONE mdelta 73070030f7b0d0f3d4ee02545d45ca4bbe5e189f 6c704fbd4ef58f2447fd1a3e76911b2ebe97dc77, [1], [ignore], [ignore])
+AT_CHECK(MONOTONE mdata 73070030f7b0d0f3d4ee02545d45ca4bbe5e189f, [1], [ignore], [ignore])
+AT_CHECK(MONOTONE fdelta 73070030f7b0d0f3d4ee02545d45ca4bbe5e189f 6c704fbd4ef58f2447fd1a3e76911b2ebe97dc77, [1], [ignore], [ignore])
+AT_CHECK(MONOTONE fdata 73070030f7b0d0f3d4ee02545d45ca4bbe5e189f, [1], [ignore], [ignore])
+AT_CHECK(MONOTONE rdata 73070030f7b0d0f3d4ee02545d45ca4bbe5e189f, [1], [ignore], [ignore])
+AT_CHECK(MONOTONE pubkey address@hidden, [1], [ignore], [ignore])
+AT_CHECK(MONOTONE privkey address@hidden, [1], [ignore], [ignore])
+
+# This one should succeed, but print nothing.
+AT_CHECK(MONOTONE certs 73070030f7b0d0f3d4ee02545d45ca4bbe5e189f, [], [], [ignore])
+
+AT_CLEANUP
--- tests/t_inodeprints_hook.at
+++ tests/t_inodeprints_hook.at
@@ -0,0 +1,38 @@
+AT_SETUP([use_inodeprints hook])
+MONOTONE_SETUP
+
+AT_DATA(on.lua, [
+function use_inodeprints()
+ return true
+end
+])
+
+AT_DATA(off.lua, [
+function use_inodeprints()
+ return false
+end
+])
+
+AT_CHECK(test ! -e MT/inodeprints)
+ADD_FILE(testfile, [blah blah
+])
+COMMIT(testbranch)
+REV=`BASE_REVISION`
+
+AT_CHECK(MONOTONE setup setup_default, [], [ignore], [ignore])
+AT_CHECK(test ! -e setup_default/MT/inodeprints)
+AT_CHECK(MONOTONE checkout $REV co_default, [], [ignore], [ignore])
+AT_CHECK(test ! -e co_default/MT/inodeprints)
+
+AT_CHECK(MONOTONE --rcfile=off.lua setup setup_off, [], [ignore], [ignore])
+AT_CHECK(test ! -e setup_off/MT/inodeprints)
+AT_CHECK(MONOTONE --rcfile=off.lua checkout $REV co_off, [], [ignore], [ignore])
+AT_CHECK(test ! -e co_off/MT/inodeprints)
+
+AT_CHECK(MONOTONE --rcfile=on.lua setup setup_on, [], [ignore], [ignore])
+AT_CHECK(test -e setup_on/MT/inodeprints)
+AT_CHECK(MONOTONE --rcfile=on.lua checkout $REV co_on, [], [ignore], [ignore])
+AT_CHECK(test -e co_on/MT/inodeprints)
+AT_CHECK(test -s co_on/MT/inodeprints)
+
+AT_CLEANUP
--- testsuite.at
+++ testsuite.at
@@ -572,3 +572,5 @@
m4_include(tests/t_log_depth_single.at)
m4_include(tests/t_attr_init.at)
m4_include(tests/t_add_executable.at)
+m4_include(tests/t_inodeprints_hook.at)
+m4_include(tests/t_bad_packets.at)
--- work.cc
+++ work.cc
@@ -378,6 +378,15 @@
write_data(ip_path, dat);
}
+void
+enable_inodeprints()
+{
+ local_path ip_path;
+ get_inodeprints_path(ip_path);
+ data dat;
+ write_data(ip_path, dat);
+}
+
// attribute map file
string const attr_file_name(".mt-attrs");
--- work.hh
+++ work.hh
@@ -114,6 +114,8 @@
void write_inodeprints(data const & dat);
+void enable_inodeprints();
+
// the "attribute map" is part of a working copy. it is *not* stored in MT,
// because its contents are considered part of the "content" of a tree of
// files. it is therefore stored in .mt-attrs, in the root of your