# # # add_dir "tests/unchanged_options_preserves_mtime" # # add_file "tests/unchanged_options_preserves_mtime/__driver__.lua" # content [468ac9c7ee9b602a21e0dfa4e35432da6acba0b4] # # patch "paths.hh" # from [e92b013f510afba1da74ab8f47a8f2fa799b3b5c] # to [16f68fd413cd8c13bcb7756bdfbccfddb181215f] # # patch "work.cc" # from [4a27d0c0133f6cc04b06944afe080400095676e2] # to [910fd95c745f3ffb0b5f337571e07c84f00a7ef8] # ============================================================ --- tests/unchanged_options_preserves_mtime/__driver__.lua 468ac9c7ee9b602a21e0dfa4e35432da6acba0b4 +++ tests/unchanged_options_preserves_mtime/__driver__.lua 468ac9c7ee9b602a21e0dfa4e35432da6acba0b4 @@ -0,0 +1,67 @@ +mtn_setup() + +-- the sleep calls here are to ensure a change is visible even if +-- the resolution of mtime is one second or more + +time1 = mtime("_MTN/options") + +-- commit doesn't change mtime + +sleep(1) +writefile("foo", "foo") +check(mtn("add", "foo"), 0, false, false) +commit() +check(time1 == mtime("_MTN/options")) + +r1 = base_revision() + +-- commit doesn't change mtime + +sleep(1) +writefile("foo", "bar") +commit() +check(time1 == mtime("_MTN/options")) + +r2 = base_revision() + +-- status doesn't change mtime + +sleep(1) +check(mtn("status"), 0, false, false) +check(time1 == mtime("_MTN/options")) + +-- update on same branch doesn't change mtime + +sleep(1) +check(mtn("update", "--revision", r1), 0, false, false) +check(time1 == mtime("_MTN/options")) + +-- changing branch updates mtime of cached options + +sleep(1) +writefile("foo", "baz") +check(mtn("commit", "--branch", "baz", "--message", "baz"), 0, false, false) +time2 = mtime("_MTN/options") +check(time1 < time2) + +r3 = base_revision() + +-- update to different branch changes mtime + +sleep(1) +check(mtn("update", "--revision", r1), 0, false, false) +time3 = mtime("_MTN/options") +check(time2 < time3) + +-- update to same branch doesn't change mtime + +sleep(1) +check(mtn("update", "--revision", r2), 0, false, false) +check(time3 == mtime("_MTN/options")) + +-- update to different branch changes mtime + +sleep(1) +check(mtn("update", "--revision", r3), 0, false, false) +time4 = mtime("_MTN/options") +check(time3 < time4) ============================================================ --- paths.hh e92b013f510afba1da74ab8f47a8f2fa799b3b5c +++ paths.hh 16f68fd413cd8c13bcb7756bdfbccfddb181215f @@ -378,8 +378,9 @@ public: explicit system_path(utf8 const & path); bool operator==(const system_path & other) const - { return data== other.data; } - + { return data == other.data; } + bool operator!=(const system_path & other) const + { return data != other.data; } bool operator <(const system_path & other) const { return data < other.data; } ============================================================ --- work.cc 4a27d0c0133f6cc04b06944afe080400095676e2 +++ work.cc 910fd95c745f3ffb0b5f337571e07c84f00a7ef8 @@ -577,21 +577,43 @@ workspace::set_options(options const & o // file and if it contains the correct identifier, but these checks would // duplicate those in database.cc. At the time it is checked there, however, // the options file for the workspace is already written out... + bool options_changed = false; + if (!opts.dbname.as_internal().empty() && - get_path_status(opts.dbname.as_internal()) == path::file) - workspace_database = opts.dbname; + get_path_status(opts.dbname.as_internal()) == path::file && + workspace_database != opts.dbname) + { + workspace_database = opts.dbname; + options_changed = true; + } + if (!opts.key_dir.as_internal().empty() && - get_path_status(opts.key_dir.as_internal()) == path::directory) - workspace_keydir = opts.key_dir; - if ((branch_is_sticky || workspace::branch_is_sticky) - && !opts.branch().empty()) - workspace_branch = opts.branch; - if (opts.key_given) - workspace_key = opts.signing_key; + get_path_status(opts.key_dir.as_internal()) == path::directory && + workspace_keydir != opts.key_dir) + { + workspace_keydir = opts.key_dir; + options_changed = true; + } - write_options_file(o_path, - workspace_database, workspace_branch, - workspace_key, workspace_keydir); + if ((branch_is_sticky || workspace::branch_is_sticky) && + !opts.branch().empty() && + workspace_branch != opts.branch) + { + workspace_branch = opts.branch; + options_changed = true; + } + + if (opts.key_given && workspace_key != opts.signing_key) + { + workspace_key = opts.signing_key; + options_changed = true; + } + + // only rewrite the options file if there are actual changes + if (options_changed) + write_options_file(o_path, + workspace_database, workspace_branch, + workspace_key, workspace_keydir); } void