On Wed, Jun 12, 2013 at 2:06 PM, i...@apache.org <i...@apache.org> wrote: > Author: ivan > Date: Wed Jun 12 12:06:03 2013 > New Revision: 1492168 > > URL: http://svn.apache.org/r1492168 > Log: > Implement '--log' option for 'svn mergeinfo --show-revs' subcommand to print > revisions log message, author and date.
Thank you! The one remark I have on the feature (I didn't review the code), is that the revisions are logged oldest-first, whereas the 'svn log' output prints from most recent to oldest. I think we should be consistent here and reorder svn merge info --log output most recent first. > Suggested by: lgo > > * subversion/svn/cl.h > (svn_cl__opt_state_t): Add mergeinfo_log member. > > * subversion/svn/mergeinfo-cmd.c > (): Include svn_compat.h and svn_props.h. > (SEP_STRING, print_log_details): New. > (mergeinfo_log): New, mostly extracted from svn_cl__mergeinfo(). > (svn_cl__mergeinfo): Call mergeinfo_log(). > > * subversion/svn/svn.c > (svn_cl__longopt_t): Add opt_mergeinfo_log. > (svn_cl__options): Add description for '--log' option. > (svn_cl__cmd_table): Add opt_mergeinfo_log to mergeinfo subcommand. > (sub_main): Handle '--log' option. > > * subversion/tests/cmdline/mergeinfo_tests.py > (mergeinfo_log): New test. > (test_list): Add mergeinfo_log. > > Modified: > subversion/trunk/subversion/svn/cl.h > subversion/trunk/subversion/svn/mergeinfo-cmd.c > subversion/trunk/subversion/svn/svn.c > subversion/trunk/subversion/tests/cmdline/mergeinfo_tests.py > > Modified: subversion/trunk/subversion/svn/cl.h > URL: > http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/cl.h?rev=1492168&r1=1492167&r2=1492168&view=diff > ============================================================================== > --- subversion/trunk/subversion/svn/cl.h (original) > +++ subversion/trunk/subversion/svn/cl.h Wed Jun 12 12:06:03 2013 > @@ -239,6 +239,7 @@ typedef struct svn_cl__opt_state_t > svn_boolean_t include_externals; /* Recurses (in)to file & dir externals */ > svn_boolean_t show_inherited_props; /* get inherited properties */ > apr_array_header_t* search_patterns; /* pattern arguments for --search */ > + svn_boolean_t mergeinfo_log; /* show log message in mergeinfo command > */ > } svn_cl__opt_state_t; > > > > Modified: subversion/trunk/subversion/svn/mergeinfo-cmd.c > URL: > http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/mergeinfo-cmd.c?rev=1492168&r1=1492167&r2=1492168&view=diff > ============================================================================== > --- subversion/trunk/subversion/svn/mergeinfo-cmd.c (original) > +++ subversion/trunk/subversion/svn/mergeinfo-cmd.c Wed Jun 12 12:06:03 2013 > @@ -27,7 +27,9 @@ > > /*** Includes. ***/ > > +#include "svn_compat.h" > #include "svn_pools.h" > +#include "svn_props.h" > #include "svn_client.h" > #include "svn_cmdline.h" > #include "svn_path.h" > @@ -55,6 +57,61 @@ print_log_rev(void *baton, > return SVN_NO_ERROR; > } > > +/* The separator between log messages. */ > +#define SEP_STRING \ > + > "------------------------------------------------------------------------\n" > + > +/* Implements the svn_log_entry_receiver_t interface. */ > +static svn_error_t * > +print_log_details(void *baton, > + svn_log_entry_t *log_entry, > + apr_pool_t *pool) > +{ > + const char *author; > + const char *date; > + const char *message; > + > + svn_compat_log_revprops_out(&author, &date, &message, log_entry->revprops); > + > + if (author == NULL) > + author = _("(no author)"); > + > + if (date && date[0]) > + /* Convert date to a format for humans. */ > + SVN_ERR(svn_cl__time_cstring_to_human_cstring(&date, date, pool)); > + else > + date = _("(no date)"); > + > + if (log_entry->non_inheritable) > + SVN_ERR(svn_cmdline_printf(pool, > + SEP_STRING "r%ld* | %s | %s", > + log_entry->revision, author, date)); > + else > + SVN_ERR(svn_cmdline_printf(pool, > + SEP_STRING "r%ld | %s | %s", > + log_entry->revision, author, date)); > + > + if (message != NULL) > + { > + /* Number of lines in the msg. */ > + int lines = svn_cstring_count_newlines(message) + 1; > + > + SVN_ERR(svn_cmdline_printf(pool, > + Q_(" | %d line", " | %d lines", lines), > + lines)); > + } > + > + SVN_ERR(svn_cmdline_printf(pool, "\n")); > + > + if (message != NULL) > + { > + /* A blank line always precedes the log message. */ > + SVN_ERR(svn_cmdline_printf(pool, "\n%s\n", message)); > + } > + > + return SVN_NO_ERROR; > +} > + > /* Draw a diagram (by printing text to the console) summarizing the state > * of merging between two branches, given the merge description > * indicated by YCA, BASE, RIGHT, TARGET, REINTEGRATE_LIKE. */ > @@ -238,6 +295,50 @@ mergeinfo_summary( > return SVN_NO_ERROR; > } > > +static svn_error_t * > +mergeinfo_log(svn_boolean_t finding_merged, > + const char *target, > + const svn_opt_revision_t *tgt_peg_revision, > + const char *source, > + const svn_opt_revision_t *src_peg_revision, > + const svn_opt_revision_t *src_start_revision, > + const svn_opt_revision_t *src_end_revision, > + svn_depth_t depth, > + svn_boolean_t include_log_details, > + svn_client_ctx_t *ctx, > + apr_pool_t *pool) > +{ > + apr_array_header_t *revprops; > + svn_log_entry_receiver_t log_reciever; > + > + if (include_log_details) > + { > + revprops = apr_array_make(pool, 3, sizeof(const char *)); > + APR_ARRAY_PUSH(revprops, const char *) = SVN_PROP_REVISION_AUTHOR; > + APR_ARRAY_PUSH(revprops, const char *) = SVN_PROP_REVISION_DATE; > + APR_ARRAY_PUSH(revprops, const char *) = SVN_PROP_REVISION_LOG; > + > + log_reciever = print_log_details; > + } > + else > + { > + /* We need only revisions number, not revision properties. */ > + revprops = apr_array_make(pool, 0, sizeof(const char *)); > + log_reciever = print_log_rev; > + } > + > + SVN_ERR(svn_client_mergeinfo_log2(finding_merged, target, > + tgt_peg_revision, > + source, src_peg_revision, > + src_start_revision, > + src_end_revision, > + log_reciever, NULL, > + TRUE, depth, revprops, ctx, > + pool)); > + > + return SVN_NO_ERROR; > +} > + > /* This implements the `svn_opt_subcommand_t' interface. */ > svn_error_t * > svn_cl__mergeinfo(apr_getopt_t *os, > @@ -311,33 +412,21 @@ svn_cl__mergeinfo(apr_getopt_t *os, > /* Do the real work, depending on the requested data flavor. */ > if (opt_state->show_revs == svn_cl__show_revs_merged) > { > - apr_array_header_t *revprops; > - > - /* We need only revisions number, not revision properties. */ > - revprops = apr_array_make(pool, 0, sizeof(const char *)); > - > - SVN_ERR(svn_client_mergeinfo_log2(TRUE, target, &tgt_peg_revision, > - source, &src_peg_revision, > - src_start_revision, > - src_end_revision, > - print_log_rev, NULL, > - TRUE, depth, revprops, ctx, > - pool)); > + SVN_ERR(mergeinfo_log(TRUE, target, &tgt_peg_revision, > + source, &src_peg_revision, > + src_start_revision, > + src_end_revision, > + depth, opt_state->mergeinfo_log, > + ctx, pool)); > } > else if (opt_state->show_revs == svn_cl__show_revs_eligible) > { > - apr_array_header_t *revprops; > - > - /* We need only revisions number, not revision properties. */ > - revprops = apr_array_make(pool, 0, sizeof(const char *)); > - > - SVN_ERR(svn_client_mergeinfo_log2(FALSE, target, &tgt_peg_revision, > - source, &src_peg_revision, > - src_start_revision, > - src_end_revision, > - print_log_rev, NULL, > - TRUE, depth, revprops, ctx, > - pool)); > + SVN_ERR(mergeinfo_log(FALSE, target, &tgt_peg_revision, > + source, &src_peg_revision, > + src_start_revision, > + src_end_revision, > + depth, opt_state->mergeinfo_log, > + ctx, pool)); > } > else > { > > Modified: subversion/trunk/subversion/svn/svn.c > URL: > http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/svn.c?rev=1492168&r1=1492167&r2=1492168&view=diff > ============================================================================== > --- subversion/trunk/subversion/svn/svn.c (original) > +++ subversion/trunk/subversion/svn/svn.c Wed Jun 12 12:06:03 2013 > @@ -133,7 +133,8 @@ typedef enum svn_cl__longopt_t { > opt_include_externals, > opt_show_inherited_props, > opt_search, > - opt_search_and > + opt_search_and, > + opt_mergeinfo_log > } svn_cl__longopt_t; > > > @@ -379,6 +380,8 @@ const apr_getopt_option_t svn_cl__option > N_("use ARG as search pattern (glob syntax)")}, > {"search-and", opt_search_and, 1, > N_("combine ARG with the previous search pattern")}, > + {"log", opt_mergeinfo_log, 0, > + N_("show revision log message, author and date")}, > > /* Long-opt Aliases > * > @@ -1108,7 +1111,7 @@ const svn_opt_subcommand_desc2_t svn_cl_ > " and the default for TARGET is HEAD for a URL or BASE for a WC > path.\n" > "\n" > " The depth can be 'empty' or 'infinity'; the default is 'empty'.\n"), > - {'r', 'R', opt_depth, opt_show_revs} }, > + {'r', 'R', opt_depth, opt_show_revs, opt_mergeinfo_log} }, > > { "mkdir", svn_cl__mkdir, {0}, N_ > ("Create a new directory under version control.\n" > @@ -2212,6 +2215,9 @@ sub_main(int argc, const char *argv[], a > _("'%s' is not a valid --show-revs value"), > utf8_opt_arg)); > break; > + case opt_mergeinfo_log: > + opt_state.mergeinfo_log = TRUE; > + break; > case opt_reintegrate: > opt_state.reintegrate = TRUE; > break; > > Modified: subversion/trunk/subversion/tests/cmdline/mergeinfo_tests.py > URL: > http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/mergeinfo_tests.py?rev=1492168&r1=1492167&r2=1492168&view=diff > ============================================================================== > --- subversion/trunk/subversion/tests/cmdline/mergeinfo_tests.py (original) > +++ subversion/trunk/subversion/tests/cmdline/mergeinfo_tests.py Wed Jun 12 > 12:06:03 2013 > @@ -779,6 +779,31 @@ def noninheritable_mergeinfo_not_always_ > [], sbox.repo_url + '/A', sbox.repo_url + '/branch', > '--show-revs', 'eligible', '-R') > > +@SkipUnless(server_has_mergeinfo) > +def mergeinfo_log(sbox): > + "'mergeinfo --log' on a path with mergeinfo" > + > + sbox.build() > + wc_dir = sbox.wc_dir > + > + # make a branch 'A2' > + sbox.simple_repo_copy('A', 'A2') # r2 > + # make a change in branch 'A' > + sbox.simple_mkdir('A/newdir') > + sbox.simple_commit() # r3 > + sbox.simple_update() > + > + # Dummy up some mergeinfo. > + svntest.actions.run_and_verify_svn(None, None, [], > + 'ps', SVN_PROP_MERGEINFO, '/A:3', > + sbox.ospath('A2')) > + svntest.actions.run_and_verify_svn(None, > + None, [], > + 'mergeinfo', '--show-revs=merged', > + '--log', sbox.repo_url + '/A', > + sbox.ospath('A2')) > + > + > ######################################################################## > # Run the tests > > @@ -796,6 +821,7 @@ test_list = [ None, > wc_target_inherits_mergeinfo_from_repos, > natural_history_is_not_eligible_nor_merged, > noninheritable_mergeinfo_not_always_eligible, > + mergeinfo_log, > ] > > if __name__ == '__main__': > >