# # # add_dir "tests/automate_log" # # add_file "tests/automate_log/__driver__.lua" # content [05740c3348c3b070276a119cc149130b7699a5c5] # # patch "NEWS" # from [46a45617263cf0cf32cf74fbe2dbc89d01c62c0a] # to [c60f8a8ad9c9f043c0ff615aba3ce48077db85ae] # # patch "cmd_diff_log.cc" # from [19a9ea13bfa486f332ead5ea68de4f1f21b6b2e0] # to [23daffa4cc24771e90a5a000279851ded2882850] # # patch "monotone.texi" # from [3ef4a5ace36d04a753d17cc89893be482ce03d71] # to [55b65ba9c8e7eaf220f8ae2b4026ec318d55ef4c] # # patch "testlib.lua" # from [fe3f2d1e985bdfacd9a4567a5cc04ab8eb2678cb] # to [ab15612fd70395e7f7cb9b74a985c7df874c8c07] # # patch "tests/common/automate_ancestry.lua" # from [e63c51355db5f8979cb41cd5da88c8d577a6f47c] # to [cd099e139b5d6ccf5845b24c6d892b81d1c2ad76] # ============================================================ --- tests/automate_log/__driver__.lua 05740c3348c3b070276a119cc149130b7699a5c5 +++ tests/automate_log/__driver__.lua 05740c3348c3b070276a119cc149130b7699a5c5 @@ -0,0 +1,32 @@ +-- Test 'mtn automate log' + +mtn_setup() + +-- empty branch +check(mtn("automate", "log"), 1, false, true) +check(qgrep("misuse: workspace parent revision '' not found", "stderr")) + +include("/common/automate_ancestry.lua") + +revs = make_graph() +-- A +-- / \ +-- B C +-- |\ +-- D E +-- \/ +-- F +-- workspace is at F + +-- Default 'from' is F +-- '--to' is not inclusive; '--from' is. +revmap("log", {"--to", revs.a}, {revs.f, revs.d, revs.e, revs.c}, false) +revmap("log", {"--to", revs.b, "--from", revs.b}, {revs.b}, false) +revmap("log", {"--to", revs.e}, {revs.f, revs.d}, false) +revmap("log", {"--to", revs.c, "--from", revs.d}, {revs.d}, false) + +-- show missing revisions +revert_to(revs.c) +revmap("log", {"--to", "w:", "--from", "h:"}, {revs.b, revs.f, revs.d, revs.e}, false) + +-- end of file ============================================================ --- NEWS 46a45617263cf0cf32cf74fbe2dbc89d01c62c0a +++ NEWS c60f8a8ad9c9f043c0ff615aba3ce48077db85ae @@ -11,6 +11,10 @@ Xxx Xxx 99 99:99:99 UTC 2010 New Features + - New automation command 'log' which behaves identical to the + normal 'log' command, except that it only outputs the + revision ids. + Bugs Fixed Other ============================================================ --- cmd_diff_log.cc 19a9ea13bfa486f332ead5ea68de4f1f21b6b2e0 +++ cmd_diff_log.cc 23daffa4cc24771e90a5a000279851ded2882850 @@ -1,4 +1,4 @@ -// Copyright (C) 2009 Stephen Leake +// Copyright (C) 2009, 2010 Stephen Leake // Copyright (C) 2002 Graydon Hoare // // This program is made available under the GNU GPL version 2.0 or @@ -144,7 +144,7 @@ dump_diffs(lua_hooks & lua, file_path left_path, right_path; left_roster.get_name(i.left_key(), left_path); // right_path is null - + file_id left_id, right_id; left_id = downcast_to_file_t(i.left_data())->content; // right_id is null @@ -157,7 +157,7 @@ dump_diffs(lua_hooks & lua, if (show_encloser) lua.hook_get_encloser_pattern(left_path, encloser); - dump_diff(lua, + dump_diff(lua, left_path, right_path, left_id, right_id, left_data, right_data, @@ -173,7 +173,7 @@ dump_diffs(lua_hooks & lua, file_path left_path, right_path; // left_path is null right_roster.get_name(i.right_key(), right_path); - + file_id left_id, right_id; // left_id is null right_id = downcast_to_file_t(i.right_data())->content; @@ -186,7 +186,7 @@ dump_diffs(lua_hooks & lua, if (show_encloser) lua.hook_get_encloser_pattern(right_path, encloser); - dump_diff(lua, + dump_diff(lua, left_path, right_path, left_id, right_id, left_data, right_data, @@ -199,7 +199,7 @@ dump_diffs(lua_hooks & lua, // moved/renamed/patched/attribute changes if (is_file_t(i.left_data())) { - + file_id left_id, right_id; left_id = downcast_to_file_t(i.left_data())->content; right_id = downcast_to_file_t(i.right_data())->content; @@ -210,7 +210,7 @@ dump_diffs(lua_hooks & lua, file_path left_path, right_path; left_roster.get_name(i.left_key(), left_path); right_roster.get_name(i.right_key(), right_path); - + data left_data, right_data; get_data(db, left_path, left_id, left_from_db, left_data); get_data(db, right_path, right_id, right_from_db, right_data); @@ -219,7 +219,7 @@ dump_diffs(lua_hooks & lua, if (show_encloser) lua.hook_get_encloser_pattern(right_path, encloser); - dump_diff(lua, + dump_diff(lua, left_path, right_path, left_id, right_id, left_data, right_data, @@ -514,7 +514,7 @@ log_certs(vector const & certs, os I(name == date_cert_name); os << date_t(i->value()).as_formatted_localtime(date_fmt); } - + first = false; } } @@ -545,17 +545,101 @@ typedef priority_queue >, rev_cmp> frontier_t; -CMD(log, "log", "", CMD_REF(informative), N_("[PATH] ..."), - N_("Prints selected history in forward or reverse order"), - N_("This command prints selected history in forward or reverse order, " - "filtering it by PATH if given."), - options::opts::last | options::opts::next | - options::opts::from | options::opts::to | options::opts::revision | - options::opts::brief | options::opts::diffs | - options::opts::depth | options::opts::exclude | - options::opts::no_merges | options::opts::no_files | - options::opts::no_graph) +void +log_print_rev (app_state & app, + database & db, + project_t & project, + revision_id rid, + revision_t & rev, + string date_fmt, + node_restriction mask, + bool automate, + ostream & out) { + if (automate) + { + out << rid << "\n"; + } + else + { + cert_name const author_name(author_cert_name); + cert_name const date_name(date_cert_name); + cert_name const branch_name(branch_cert_name); + cert_name const tag_name(tag_cert_name); + cert_name const changelog_name(changelog_cert_name); + cert_name const comment_name(comment_cert_name); + vector certs; + project.get_revision_certs(rid, certs); + + if (app.opts.brief) + { + out << rid; + log_certs(certs, out, author_name); + if (app.opts.no_graph) + log_certs(certs, out, date_name, date_fmt); + else + { + out << '\n'; + log_certs(certs, out, date_name, date_fmt); + } + log_certs(certs, out, branch_name); + out << '\n'; + } + else + { + utf8 header; + revision_header(rid, rev, certs, date_fmt, header); + + external header_external; + utf8_to_system_best_effort(header, header_external); + out << header_external; + + if (!app.opts.no_files) + { + utf8 summary; + revision_summary(rev, summary); + external summary_external; + utf8_to_system_best_effort(summary, summary_external); + out << summary_external; + } + } + + if (app.opts.diffs) + { + // if the current roster was loaded above this should hit the + // cache and not cost much... logging diffs isn't superfast + // regardless. + roster_t current_roster; + db.get_roster(rid, current_roster); + + for (edge_map::const_iterator e = rev.edges.begin(); + e != rev.edges.end(); ++e) + { + roster_t parent_roster, restricted_roster; + + db.get_roster(edge_old_revision(e), parent_roster); + + // always show forward diffs from the parent roster to + // the current roster regardless of the log direction + make_restricted_roster(parent_roster, current_roster, + restricted_roster, mask); + + dump_diffs(app.lua, db, parent_roster, restricted_roster, + out, app.opts.diff_format, + app.opts.external_diff_args_given, + app.opts.external_diff_args, + true, true, + !app.opts.no_show_encloser); + } + } + } +} + +void +log_common (app_state & app, + args_vector args, + bool automate) +{ database db(app); project_t project(db); @@ -738,12 +822,6 @@ CMD(log, "log", "", CMD_REF(informative) L(FL("log %d starting revisions") % starting_revs.size()); } - cert_name const author_name(author_cert_name); - cert_name const date_name(date_cert_name); - cert_name const branch_name(branch_cert_name); - cert_name const tag_name(tag_cert_name); - cert_name const changelog_name(changelog_cert_name); - cert_name const comment_name(comment_cert_name); // we can use the markings if we walk backwards for a restricted log bool use_markings(direction == log_reverse && !mask.empty()); @@ -842,85 +920,27 @@ CMD(log, "log", "", CMD_REF(informative) if (print_this) { - vector certs; - project.get_revision_certs(rid, certs); - - ostringstream out; - if (app.opts.brief) - { - out << rid; - log_certs(certs, out, author_name); - if (app.opts.no_graph) - log_certs(certs, out, date_name, date_fmt); - else - { - out << '\n'; - log_certs(certs, out, date_name, date_fmt); - } - log_certs(certs, out, branch_name); - out << '\n'; - } + if (automate) + log_print_rev (app, db, project, rid, rev, date_fmt, mask, automate, cout); else { - utf8 header; - revision_header(rid, rev, certs, date_fmt, header); + ostringstream out; + log_print_rev (app, db, project, rid, rev, date_fmt, mask, automate, out); - external header_external; - utf8_to_system_best_effort(header, header_external); - out << header_external; - - if (!app.opts.no_files) - { - utf8 summary; - revision_summary(rev, summary); - external summary_external; - utf8_to_system_best_effort(summary, summary_external); - out << summary_external; - } + string out_system; + utf8_to_system_best_effort(utf8(out.str(), origin::internal), out_system); + if (app.opts.no_graph) + cout << out_system; + else + graph.print(rid, interesting, out_system); } - if (app.opts.diffs) - { - // if the current roster was loaded above this should hit the - // cache and not cost much... logging diffs isn't superfast - // regardless. - roster_t current_roster; - db.get_roster(rid, current_roster); - - for (edge_map::const_iterator e = rev.edges.begin(); - e != rev.edges.end(); ++e) - { - roster_t parent_roster, restricted_roster; - - db.get_roster(edge_old_revision(e), parent_roster); - - // always show forward diffs from the parent roster to - // the current roster regardless of the log direction - make_restricted_roster(parent_roster, current_roster, - restricted_roster, mask); - - dump_diffs(app.lua, db, parent_roster, restricted_roster, - out, app.opts.diff_format, - app.opts.external_diff_args_given, - app.opts.external_diff_args, - true, true, - !app.opts.no_show_encloser); - } - } - if (next > 0) next--; else if (last > 0) last--; - - string out_system; - utf8_to_system_best_effort(utf8(out.str(), origin::internal), out_system); - if (app.opts.no_graph) - cout << out_system; - else - graph.print(rid, interesting, out_system); } - else if (use_markings && !app.opts.no_graph) + else if (!automate && use_markings && !app.opts.no_graph) graph.print(rid, interesting, (F("(Revision: %s)") % rid).str()); @@ -944,6 +964,31 @@ CMD(log, "log", "", CMD_REF(informative) } } +CMD(log, "log", "", CMD_REF(informative), N_("[PATH] ..."), + N_("Prints selected history in forward or reverse order"), + N_("This command prints selected history in forward or reverse order, " + "filtering it by PATH if given."), + options::opts::last | options::opts::next | + options::opts::from | options::opts::to | options::opts::revision | + options::opts::brief | options::opts::diffs | + options::opts::depth | options::opts::exclude | + options::opts::no_merges | options::opts::no_files | + options::opts::no_graph) +{ + log_common (app, args, false); +} + +CMD_AUTOMATE(log, N_("[PATH] ..."), + N_("list selected revision history"), + "", + options::opts::last | options::opts::next | + options::opts::from | options::opts::to | + options::opts::depth | options::opts::exclude | + options::opts::no_merges | options::opts::no_files) +{ + log_common (app, args, true); +} + // Local Variables: // mode: C++ // fill-column: 76 ============================================================ --- monotone.texi 3ef4a5ace36d04a753d17cc89893be482ce03d71 +++ monotone.texi 55b65ba9c8e7eaf220f8ae2b4026ec318d55ef4c @@ -10147,6 +10147,48 @@ @section Automation @end table address@hidden mtn automate log + address@hidden @strong address@hidden Arguments: + address@hidden address@hidden address@hidden [...]] address@hidden [...]] [--no-merges] [--no-files] address@hidden + +Same as @command{mtn log}, but without the output control options; see address@hidden + address@hidden Added in: + +12.2 + address@hidden Purpose: + +Print the selected revisions on stdout, in topological order. The user +can then use other automate commands to retrieve additional +information about each revision. + address@hidden Sample output: + address@hidden +233afb8c4832bf33d5f5734225164de5f5a6278c +4a368a6b217c40b2ff3b12bb7cfa00987e0f191c +233afb8c4832bf33d5f5734225164de5f5a6278c address@hidden verbatim + +These messages are in the 'm' stream in automate stdio. + address@hidden Output format: + +One revision per line. + address@hidden Error conditions: + +see @command{mtn log} in @ref{Informative}. + address@hidden table + @item mtn automate update @table @strong ============================================================ --- testlib.lua fe3f2d1e985bdfacd9a4567a5cc04ab8eb2678cb +++ testlib.lua ab15612fd70395e7f7cb9b74a985c7df874c8c07 @@ -414,7 +414,7 @@ function runcmd(cmd, prefix, bgnd) else prepare_redirect(prefix.."stdin", prefix.."stdout", prefix.."stderr") end - + local result if cmd.logline ~= nil then L(locheader(), cmd.logline, "\n") @@ -436,7 +436,7 @@ function runcmd(cmd, prefix, bgnd) "(first entry is a " .. type(cmd[1]) ..")") end execute = oldexec - + if local_redir then files.stdin:close() files.stdout:close() @@ -446,8 +446,8 @@ function samefile(left, right) end function samefile(left, right) - if left == "-" or right == "-" then - err("tests may not rely on standard input") + if left == "-" or right == "-" then + err("tests may not rely on standard input") end if fsize(left) ~= fsize(right) then return false @@ -473,8 +473,8 @@ function samelines(f, t) for i=1,table.getn(t) do if fl[i] ~= t[i] then if fl[i] then - L(locheader(), string.format("file[i] = '%s'; table[i] = '%s'\n", - fl[i], t[i])) + L(locheader(), string.format("file[%d] = '%s'; table[%d] = '%s'\n", + i, fl[i], i, t[i])) else L(locheader(), string.format("file[i] = ''; table[i] = '%s'\n", t[i])) @@ -705,7 +705,7 @@ function bg(torun, ret, stdout, stderr, mt.__index = mt mt.finish = function(obj, timeout) if obj.retval ~= nil then return end - + if timeout == nil then timeout = 0 end if type(timeout) ~= "number" then err("Bad timeout of type "..type(timeout)) @@ -723,7 +723,7 @@ function bg(torun, ret, stdout, stderr, obj.retval, res = timed_wait(obj.pid, 2) end end - + test.bglist[obj.id] = nil L(locheader(), "checking background command from ", out.locstr, cmd_as_str(out.cmd), "\n") @@ -962,7 +962,7 @@ function run_tests(debugging, list_only, local s = prepare_to_run_tests(P) if s ~= 0 then P("Test suite preparation failed.\n") - return s + return s end P("Running tests...\n") @@ -1161,7 +1161,7 @@ function run_one_test(tname) test.log:write("\n") end test.log:close() - + -- record the short status where report_one_test can find it local s = io.open(test.root .. "/STATUS", "w") if r then ============================================================ --- tests/common/automate_ancestry.lua e63c51355db5f8979cb41cd5da88c8d577a6f47c +++ tests/common/automate_ancestry.lua cd099e139b5d6ccf5845b24c6d892b81d1c2ad76 @@ -2,30 +2,30 @@ function make_graph() function make_graph() local revs = {} addfile("testfile", "A") - commit() + commit("testbranch", "revs.a") revs.a = base_revision() writefile("testfile", "B") - commit() + commit("testbranch", "revs.b") revs.b = base_revision() revert_to(revs.a) writefile("testfile", "C") - commit() + commit("testbranch", "revs.c") revs.c = base_revision() writefile("testfile", "D") - commit() + commit("testbranch", "revs.d") revs.d = base_revision() revert_to(revs.c) addfile("otherfile", "E") - commit() + commit("testbranch", "revs.e") revs.e = base_revision() - check(mtn("explicit_merge", revs.d, revs.e, "testbranch"), 0, false, false) + check(mtn("explicit_merge", revs.d, revs.e, "testbranch", "--message", "revs.f"), 0, false, false) check(mtn("update"), 0, false, false) revs.f = base_revision()