# # add_file "tests/t_override_author_date.at" # # patch "ChangeLog" # from [00be67da78804afd4d1a75955b9b951e37c3ea2a] # to [18832c4da0480c01da3b130d2537b40de361f782] # # patch "app_state.cc" # from [63120a266ad19ebd72022cf172ccbd0c299aa413] # to [b821fb66100e7626444a2f1e4bc2af4d572880b1] # # patch "app_state.hh" # from [9cfdb7a5976dc31edda11e99ee74046fdc318469] # to [27b58d6683bc026b41c07308738952067bf82926] # # patch "cert.cc" # from [451241f5ac6f41b70211dc92aa500e36688579af] # to [07be077e4c0d53abd9cac0bbdf201e808cf221a5] # # patch "cert.hh" # from [4b8178c3e7303d3465932f7d44039e8315f850a6] # to [e2b1d86c8f2610e854afed7ab661c4c2554e7004] # # patch "commands.cc" # from [5c5ffeb1c705633a442c8abe9d14ffd03db99869] # to [e24b9d3f4cf1db10ea68ce3733c1a8bdafb5371d] # # patch "monotone.1" # from [9a00ecadd333fe803fe4788d579afb75f3a8aa51] # to [33e5e256e415dd185535ac1331d44a9de3f243cc] # # patch "monotone.cc" # from [0139d2c71dbb12198e6206749b71ecb1e6286459] # to [daff288cbe075dc65c3dfd45e89ea3e71d438ed8] # # patch "monotone.texi" # from [31fabd3d2cdf017dfc5af29af363dbd9e6f74c21] # to [412d8c60e2a7e06ae07a6b8350393421d7f87b2b] # # patch "tests/t_override_author_date.at" # from [] # to [0f0499f19e887a4dbe83663f5e704110ca270bb3] # # patch "testsuite.at" # from [43031d5d196cfda4496ed11d9f46f448bc973697] # to [63f222bf1549f1b5ea773c38860809fd131a88e4] # --- ChangeLog +++ ChangeLog @@ -1,5 +1,23 @@ 2005-04-16 Nathaniel Smith + * app_state.{cc,hh} (set_author, set_date): New methods. + * cert.cc (cert_revision_date): Rename to... + (cert_revision_date_time): ...an overloaded version of this. + (cert_revision_author_default): Check app.date. + * cert.hh: Expose cert_revision_date_time. + * commands.cc (commit): Handle --date. + * main.cc: Parse --date and --author options. + * monotone.1: Document --date, --author. + * monotone.texi (Working Copy, OPTIONS): Likewise. + + * tests/t_override_author_date.at: New test. + * testsuite.at: Add it. + + This commit heavily based on a patch by Markus Schiltknecht + . + +2005-04-16 Nathaniel Smith + * ChangeLog: Fixup after merge. 2005-04-17 Matthew Gregan --- app_state.cc +++ app_state.cc @@ -273,6 +273,18 @@ } void +app_state::set_date(utf8 const & d) +{ + date = d; +} + +void +app_state::set_author(utf8 const & a) +{ + author = a; +} + +void app_state::set_depth(long d) { N(d > 0, --- app_state.hh +++ app_state.hh @@ -33,6 +33,8 @@ bool rcfiles; options_map options; utf8 message; + utf8 date; + utf8 author; utf8 search_root; std::vector revision_selectors; std::vector extra_rcfiles; @@ -62,6 +64,8 @@ void set_signing_key(utf8 const & key); void set_root(utf8 const & root); void set_message(utf8 const & message); + void set_date(utf8 const & date); + void set_author(utf8 const & author); void set_depth(long depth); void add_revision(utf8 const & selector); --- cert.cc +++ cert.cc @@ -566,11 +566,11 @@ string const testresult_cert_name = "testresult"; -static void -cert_revision_date(revision_id const & m, - boost::posix_time::ptime t, - app_state & app, - packet_consumer & pc) +void +cert_revision_date_time(revision_id const & m, + boost::posix_time::ptime t, + app_state & app, + packet_consumer & pc) { string val = boost::posix_time::to_iso_extended_string(t); put_simple_revision_cert(m, date_cert_name, val, app, pc); @@ -585,7 +585,7 @@ // make sure you do all your CVS conversions by 2038! boost::posix_time::ptime tmp(boost::gregorian::date(1970,1,1), boost::posix_time::seconds(static_cast(t))); - cert_revision_date(m, tmp, app, pc); + cert_revision_date_time(m, tmp, app, pc); } void @@ -593,7 +593,7 @@ app_state & app, packet_consumer & pc) { - cert_revision_date(m, boost::posix_time::second_clock::universal_time(), app, pc); + cert_revision_date_time(m, boost::posix_time::second_clock::universal_time(), app, pc); } void @@ -620,8 +620,7 @@ % app.branch_name); author = key(); } - put_simple_revision_cert(m, author_cert_name, - author, app, pc); + cert_revision_author(m, author, app, pc); } void --- cert.hh +++ cert.hh @@ -12,6 +12,7 @@ #include #include #include +#include // certs associate an opaque name/value pair with a particular identifier in // the system (eg. a manifest or file id) and are accompanied by an RSA @@ -119,6 +120,12 @@ void cert_revision_date_time(revision_id const & m, + boost::posix_time::ptime t, + app_state & app, + packet_consumer & pc); + +void +cert_revision_date_time(revision_id const & m, time_t time, app_state & app, packet_consumer & pc); --- commands.cc +++ commands.cc @@ -17,6 +17,7 @@ #include #include #include +#include #include "commands.hh" #include "constants.hh" @@ -2541,6 +2542,33 @@ else throw usage(name); } + +static boost::posix_time::ptime +string_to_datetime(std::string const & s) +{ + try + { + // boost::posix_time is lame: it can parse "basic" ISO times, of the + // form 20000101T120000, but not "extended" ISO times, of the form + // 2000-01-01T12:00:00. So do something stupid to convert one to the + // other. + std::string tmp = s; + std::string::size_type pos = 0; + while ((pos = tmp.find_first_of("-:")) != string::npos) + tmp.erase(pos, 1); + return boost::posix_time::from_iso_string(tmp); + } + catch (std::out_of_range &e) + { + N(false, F("failed to parse date string '%s': %s") % s % e.what()); + } + catch (std::exception &) + { + N(false, F("failed to parse date string '%s'") % s); + } + I(false); +} + CMD(commit, "working copy", "[--message=STRING] [PATH]...", "commit working copy to database") { @@ -2677,8 +2705,14 @@ dbw.consume_revision_data(rid, rdat); cert_revision_in_branch(rid, branchname, app, dbw); - cert_revision_date_now(rid, app, dbw); - cert_revision_author_default(rid, app, dbw); + if (app.date().length() > 0) + cert_revision_date_time(rid, string_to_datetime(app.date()), app, dbw); + else + cert_revision_date_now(rid, app, dbw); + if (app.author().length() > 0) + cert_revision_author(rid, app.author(), app, dbw); + else + cert_revision_author_default(rid, app, dbw); cert_revision_changelog(rid, log_message, app, dbw); } --- monotone.1 +++ monotone.1 @@ -260,6 +260,17 @@ \fB-m \fI\fP An alias for \fB--message=\fI\fP .TP +\fB--author=\fI\fP +Use the given author as the value of the "author" cert when committing +a new revision, rather than the default author. Useful when +committing a patch on behalf of someone else, or when importing +history from another version control system. +.TP +\fB--date=\fI\fP +Use the given given date and time as value of the "date" cert when +committing a new revision, rather than the current time. Useful when +importing history from another version control system. +.TP \fB--root=\fI\fP Stop the search for a working copy (containing the @file{MT} directory) at the specified root directory rather than at the physical root of the --- monotone.cc +++ monotone.cc @@ -45,6 +45,8 @@ #define OPT_ROOT 16 #define OPT_DEPTH 17 #define OPT_ARGFILE 18 +#define OPT_DATE 19 +#define OPT_AUTHOR 20 // main option processing and exception handling code @@ -70,6 +72,8 @@ {"ticker", 0, POPT_ARG_STRING, &argstr, OPT_TICKER, "set ticker style (count|dot|none) [count]", NULL}, {"revision", 'r', POPT_ARG_STRING, &argstr, OPT_REVISION, "select revision id for operation", NULL}, {"message", 'm', POPT_ARG_STRING, &argstr, OPT_MESSAGE, "set commit changelog message", NULL}, + {"date", 0, POPT_ARG_STRING, &argstr, OPT_DATE, "override date/time for commit", NULL}, + {"author", 0, POPT_ARG_STRING, &argstr, OPT_AUTHOR, "override author for commit", NULL}, {"root", 0, POPT_ARG_STRING, &argstr, OPT_ROOT, "limit search for working copy to specified root", NULL}, {"depth", 0, POPT_ARG_LONG, &arglong, OPT_DEPTH, "limit the log output to the given number of entries", NULL}, {"xargs", '@', POPT_ARG_STRING, &argstr, OPT_ARGFILE, "insert command line arguments taken from the given file", NULL}, @@ -185,8 +189,8 @@ // the argv array be null-terminated. I(argv[argc] == NULL); N((rc = poptStuffArgs(con, argv)) >= 0, - F("weird error when stuffing arguments read from %s: %s\n") - % filename % poptStrerror(rc)); + F("weird error when stuffing arguments read from %s: %s\n") + % filename % poptStrerror(rc)); } else { @@ -324,6 +328,14 @@ app.set_message(string(argstr)); break; + case OPT_DATE: + app.set_date(string(argstr)); + break; + + case OPT_AUTHOR: + app.set_author(string(argstr)); + break; + case OPT_ROOT: app.set_root(string(argstr)); break; @@ -334,7 +346,7 @@ case OPT_ARGFILE: sub_argvs.push_back(my_poptStuffArgFile(ctx(), - utf8(string(argstr)))); + utf8(string(argstr)))); break; case OPT_HELP: --- monotone.texi +++ monotone.texi @@ -3374,12 +3374,19 @@ @itemize @item An @code{author} cert, indicating the person responsible for the changes -leading to the new revision. +leading to the new revision. Normally this defaults to your signing key +or the return value of the @code{get_author} hook; you may override this +by passing the @option{--author} option to commit. This is useful when +committing a patch on behalf of someone else, or when importing ``by +hand'' from another version control system. @item A @code{branch} cert, indicating the branch the committed revision belongs to. @item A @code{date} cert, indicating when the new revision was created. +Normally this defaults to the current time; you may override this by +passing the @option{--date} option to commit. This is useful when +importing ``by hand'' from another version control system. @item A @code{changelog} cert, containing the ``log message'' for these changes. If you provided @var{logmsg} on the command line, this text @@ -6022,6 +6029,17 @@ applies to the commit command but it may also apply to the comment command in the future. address@hidden @address@hidden} +Use the given author as the value of the "author" cert when committing +a new revision, rather than the default author. Useful when +committing a patch on behalf of someone else, or when importing +history from another version control system. + address@hidden @address@hidden} +Use the given given date and time as value of the "date" cert when +committing a new revision, rather than the current time. Useful when +importing history from another version control system. + @item @address@hidden} Stop the search for a working copy (containing the @file{MT} directory) at the specified root directory rather than at the physical root of the --- tests/t_override_author_date.at +++ tests/t_override_author_date.at @@ -0,0 +1,17 @@ +AT_SETUP([--author, --date]) +MONOTONE_SETUP + +ADD_FILE(testfile, [floooooo +]) +AT_CHECK(MONOTONE commit --author=the_author --date=1999-12-31T12:00:00 --branch=foo --message=foo, [], [ignore], [ignore]) +REV=`BASE_REVISION` +AT_CHECK(MONOTONE log $REV, [], [stdout], [ignore]) + +AT_CHECK(grep -q '^Author: the_author' stdout) +AT_CHECK(grep -q '^Date: 1999-12-31T12:00:00' stdout) + +SET_FILE(testfile, [oovel +]) +AT_CHECK(MONOTONE commit --date=1999-12-31T12:00foo --branch=foo --message=foo, [1], [ignore], [ignore]) + +AT_CLEANUP --- testsuite.at +++ testsuite.at @@ -561,3 +561,4 @@ m4_include(tests/t_lf_crlf.at) m4_include(tests/t_add_vs_commit.at) m4_include(tests/t_update_nonexistent.at) +m4_include(tests/t_override_author_date.at)