# # # patch "ChangeLog" # from [4ce17cf890b330654a50dc12c047f67328ca01ed] # to [5644559f6a9fa4bed57f7789dc87503578566c2c] # # patch "annotate.cc" # from [abc86290badfdb97601384d7e8ed9cc5fc012adf] # to [16bf672ffba67bd58faee41c824727779285a1da] # # patch "commands.cc" # from [8743a12d037788901f07148fad730dfd899f125c] # to [415d7add19888434b3a19d810775984767da3454] # # patch "monotone.texi" # from [cbc87b47e45384cb320b2b59c4ebdf0ae82f2867] # to [c98f5b49eb2f3e6c31fc6838983a541f757469de] # ============================================================ --- ChangeLog 4ce17cf890b330654a50dc12c047f67328ca01ed +++ ChangeLog 5644559f6a9fa4bed57f7789dc87503578566c2c @@ -1,3 +1,25 @@ +2006-01-19 Emile Snyder + + Add a --brief mode to the annotate command which prints more + informative annotations rather than just the raw revision ids. + + * commands.cc (CMD(annotate)): Add --brief option to the annotate + command and remove obsolete comment lines. + * annotate.cc (dump): Pass in app_state to allow access to db for + cert lookups on revisions. Honor new --brief + flag by printing .. by : as the + annotation rather than the raw revision id, and only printing the + annotation for the first line of each block of lines from the same + revision. + (cert_string_value): Given a set of certs from a revision, a cert + name, and some detail of what part of the value we want, find and + return that part of the cert. + (build_revisions_to_annotations): After we finish with the + annotations pass, build up a mapping of revision id to annotation + string. + * monotone.texi: Add --brief flag and description to the annotate + section of the command reference. + 2006-01-19 Matt Johnston * HACKING: escape the colon in the cino vim modeline option. ============================================================ --- annotate.cc abc86290badfdb97601384d7e8ed9cc5fc012adf +++ annotate.cc 16bf672ffba67bd58faee41c824727779285a1da @@ -21,6 +21,7 @@ #include "sanity.hh" #include "transforms.hh" #include "vocab.hh" +#include "cert.hh" @@ -46,11 +47,13 @@ /// return true if we have no more unassigned lines bool is_complete() const; - void dump() const; + void dump(app_state & app) const; std::string get_line(int line_index) const { return file_lines[line_index]; } private: + void build_revisions_to_annotations(app_state & app, std::map & revs_to_notations) const; + std::vector file_lines; std::vector annotations; @@ -290,22 +293,112 @@ } +std::string cert_string_value (std::vector< revision > const & certs, + const std::string & name, + bool from_start, bool from_end, + const std::string & sep) +{ + for (std::vector < revision < cert > >::const_iterator i = certs.begin (); + i != certs.end (); ++i) + { + if (i->inner ().name () == name) + { + cert_value tv; + decode_base64 (i->inner ().value, tv); + std::string::size_type f = 0; + std::string::size_type l = std::string::npos; + if (from_start) + l = tv ().find_first_of (sep); + if (from_end) + { + f = tv ().find_last_of (sep); + if (f == std::string::npos) + f = 0; + } + return tv ().substr (f, l); + } + } + + return ""; +} + + void -annotate_context::dump() const +annotate_context::build_revisions_to_annotations(app_state &app, + std::map &revs_to_notations) const { + I(annotations.size() == file_lines.size()); + + // build set of unique revisions present in annotations + std::set seen; + for (std::vector::const_iterator i = annotations.begin(); i != annotations.end(); i++) + { + seen.insert(*i); + } + + size_t max_note_length = 0; + + // build revision -> annotation string mapping + for (std::set::const_iterator i = seen.begin(); i != seen.end(); i++) + { + std::vector< revision > certs; + app.db.get_revision_certs(*i, certs); + erase_bogus_certs(certs, app); + + std::string author(cert_string_value(certs, author_cert_name, true, false, "@< ")); + std::string date(cert_string_value(certs, date_cert_name, true, false, "T")); + + std::string result; + result.append((*i).inner ()().substr(0, 8)); + result.append(".. by "); + result.append(author); + result.append(" "); + result.append(date); + result.append(": "); + + max_note_length = (result.size() > max_note_length) ? result.size() : max_note_length; + revs_to_notations[*i] = result; + } + + // justify annotation strings + for (std::map::iterator i = revs_to_notations.begin(); i != revs_to_notations.end(); i++) + { + size_t l = i->second.size(); + i->second.insert(0, max_note_length - l, ' '); + } +} + + +void +annotate_context::dump(app_state &app) const +{ revision_id nullid; I(annotations.size() == file_lines.size()); - revision_id lastid = nullid; - for (size_t i=0; i revs_to_notations; + std::string empty_note; + if (global_sanity.brief) + { + build_revisions_to_annotations(app, revs_to_notations); + size_t max_note_length = revs_to_notations.begin()->second.size(); + empty_note.insert(0, max_note_length - 2, ' '); + } - lastid = annotations[i]; - } + revision_id lastid = nullid; + for (size_t i=0; iannotate_equivalent_lines(); I(acp->is_complete()); - acp->dump(); + acp->dump(app); } ============================================================ --- commands.cc 8743a12d037788901f07148fad730dfd899f125c +++ commands.cc 415d7add19888434b3a19d810775984767da3454 @@ -3413,10 +3413,8 @@ CMD(annotate, N_("informative"), N_("PATH"), N_("print annotated copy of the file from REVISION"), - OPT_REVISION) + OPT_REVISION % OPT_BRIEF) { - // this function compiles, but the do_annotate() stuff in annotate.cc is - // still in flux, so disabling command here. revision_id rid; if (app.revision_selectors.size() == 0) ============================================================ --- monotone.texi cbc87b47e45384cb320b2b59c4ebdf0ae82f2867 +++ monotone.texi c98f5b49eb2f3e6c31fc6838983a541f757469de @@ -4161,12 +4161,19 @@ where those files are changed. @item monotone annotate @var{file} address@hidden monotone annotate address@hidden @var{file} address@hidden monotone annotate address@hidden [--brief] @var{file} -Dumps an annotated copy of the file to stdout. Each line of the file +Dumps an annotated copy of the file to stdout. In the absence of the address@hidden flag, each line of the file is translated to : in the output, where is the revision in which that line of the file was last edited. +If @code{--brief} is specified, the output is in the form +.. by : +Only the first 8 characters of the revision id are displayed, the +author cert value is truncated at the first @code{@@} or space +character and the date field is truncated to remove the time of day. + @item monotone complete file @var{partial-id} @itemx monotone complete [--brief] key @var{partial-id} @itemx monotone complete [--brief] revision @var{partial-id}