diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-08-05 16:22:51 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-08-05 16:22:51 +0000 |
commit | cf46733632c7279a9fd0fe6ce26f9185a4ae82a9 (patch) | |
tree | da27775a2161723ef342e91af41a8b51fedef405 /subversion/svn/log-cmd.c | |
parent | bb0ef45f7c46b0ae221b26265ef98a768c33f820 (diff) | |
download | subversion-tarball-master.tar.gz |
subversion-1.9.7HEADsubversion-1.9.7master
Diffstat (limited to 'subversion/svn/log-cmd.c')
-rw-r--r-- | subversion/svn/log-cmd.c | 158 |
1 files changed, 83 insertions, 75 deletions
diff --git a/subversion/svn/log-cmd.c b/subversion/svn/log-cmd.c index af57cf4..44f8a4c 100644 --- a/subversion/svn/log-cmd.c +++ b/subversion/svn/log-cmd.c @@ -37,51 +37,16 @@ #include "svn_pools.h" #include "private/svn_cmdline_private.h" +#include "private/svn_sorts_private.h" #include "cl.h" +#include "cl-log.h" #include "svn_private_config.h" /*** Code. ***/ -/* Baton for log_entry_receiver() and log_entry_receiver_xml(). */ -struct log_receiver_baton -{ - /* Client context. */ - svn_client_ctx_t *ctx; - - /* The target of the log operation. */ - const char *target_path_or_url; - svn_opt_revision_t target_peg_revision; - - /* Don't print log message body nor its line count. */ - svn_boolean_t omit_log_message; - - /* Whether to show diffs in the log. (maps to --diff) */ - svn_boolean_t show_diff; - - /* Depth applied to diff output. */ - svn_depth_t depth; - - /* Diff arguments received from command line. */ - const char *diff_extensions; - - /* Stack which keeps track of merge revision nesting, using svn_revnum_t's */ - apr_array_header_t *merge_stack; - - /* Log message search patterns. Log entries will only be shown if the author, - * the log message, or a changed path matches one of these patterns. */ - apr_array_header_t *search_patterns; - - /* Pool for persistent allocations. */ - apr_pool_t *pool; -}; - - -/* The separator between log messages. */ -#define SEP_STRING \ - "------------------------------------------------------------------------\n" /* Display a diff of the subtree TARGET_PATH_OR_URL@TARGET_PEG_REVISION as @@ -182,14 +147,14 @@ match_search_pattern(const char *search_pattern, hi; hi = apr_hash_next(hi)) { - const char *path = svn__apr_hash_index_key(hi); + const char *path = apr_hash_this_key(hi); svn_log_changed_path2_t *log_item; if (apr_fnmatch(pattern, path, flags) == APR_SUCCESS) return TRUE; /* Match copy-from paths, too. */ - log_item = svn__apr_hash_index_val(hi); + log_item = apr_hash_this_val(hi); if (log_item->copyfrom_path && SVN_IS_VALID_REVNUM(log_item->copyfrom_rev) && apr_fnmatch(pattern, @@ -249,7 +214,7 @@ match_search_patterns(apr_array_header_t *search_patterns, /* Implement `svn_log_entry_receiver_t', printing the logs in * a human-readable and machine-parseable format. * - * BATON is of type `struct log_receiver_baton'. + * BATON is of type `svn_cl__log_receiver_baton'. * * First, print a header line. Then if CHANGED_PATHS is non-null, * print all affected paths in a list headed "Changed paths:\n", @@ -323,12 +288,12 @@ match_search_patterns(apr_array_header_t *search_patterns, * ------------------------------------------------------------------------ * */ -static svn_error_t * -log_entry_receiver(void *baton, - svn_log_entry_t *log_entry, - apr_pool_t *pool) +svn_error_t * +svn_cl__log_entry_receiver(void *baton, + svn_log_entry_t *log_entry, + apr_pool_t *pool) { - struct log_receiver_baton *lb = baton; + svn_cl__log_receiver_baton *lb = baton; const char *author; const char *date; const char *message; @@ -343,7 +308,9 @@ log_entry_receiver(void *baton, if (! SVN_IS_VALID_REVNUM(log_entry->revision)) { - apr_array_pop(lb->merge_stack); + if (lb->merge_stack) + apr_array_pop(lb->merge_stack); + return SVN_NO_ERROR; } @@ -367,13 +334,18 @@ log_entry_receiver(void *baton, log_entry->changed_paths2, pool)) { if (log_entry->has_children) - APR_ARRAY_PUSH(lb->merge_stack, svn_revnum_t) = log_entry->revision; + { + if (! lb->merge_stack) + lb->merge_stack = apr_array_make(lb->pool, 1, sizeof(svn_revnum_t)); + + APR_ARRAY_PUSH(lb->merge_stack, svn_revnum_t) = log_entry->revision; + } return SVN_NO_ERROR; } SVN_ERR(svn_cmdline_printf(pool, - SEP_STRING "r%ld | %s | %s", + SVN_CL__LOG_SEP_STRING "r%ld | %s | %s", log_entry->revision, author, date)); if (message != NULL) @@ -392,6 +364,7 @@ log_entry_receiver(void *baton, { apr_array_header_t *sorted_paths; int i; + apr_pool_t *iterpool; /* Get an array of sorted hash keys. */ sorted_paths = svn_sort__hash(log_entry->changed_paths2, @@ -399,6 +372,7 @@ log_entry_receiver(void *baton, SVN_ERR(svn_cmdline_printf(pool, _("Changed paths:\n"))); + iterpool = svn_pool_create(pool); for (i = 0; i < sorted_paths->nelts; i++) { svn_sort__item_t *item = &(APR_ARRAY_IDX(sorted_paths, i, @@ -407,6 +381,8 @@ log_entry_receiver(void *baton, svn_log_changed_path2_t *log_item = item->value; const char *copy_data = ""; + svn_pool_clear(iterpool); + if (lb->ctx->cancel_func) SVN_ERR(lb->ctx->cancel_func(lb->ctx->cancel_baton)); @@ -414,34 +390,39 @@ log_entry_receiver(void *baton, && SVN_IS_VALID_REVNUM(log_item->copyfrom_rev)) { copy_data - = apr_psprintf(pool, + = apr_psprintf(iterpool, _(" (from %s:%ld)"), log_item->copyfrom_path, log_item->copyfrom_rev); } - SVN_ERR(svn_cmdline_printf(pool, " %c %s%s\n", + SVN_ERR(svn_cmdline_printf(iterpool, " %c %s%s\n", log_item->action, path, copy_data)); } + svn_pool_destroy(iterpool); } - if (lb->merge_stack->nelts > 0) + if (lb->merge_stack && lb->merge_stack->nelts > 0) { int i; + apr_pool_t *iterpool; /* Print the result of merge line */ if (log_entry->subtractive_merge) SVN_ERR(svn_cmdline_printf(pool, _("Reverse merged via:"))); else SVN_ERR(svn_cmdline_printf(pool, _("Merged via:"))); + iterpool = svn_pool_create(pool); for (i = 0; i < lb->merge_stack->nelts; i++) { svn_revnum_t rev = APR_ARRAY_IDX(lb->merge_stack, i, svn_revnum_t); - SVN_ERR(svn_cmdline_printf(pool, " r%ld%c", rev, + svn_pool_clear(iterpool); + SVN_ERR(svn_cmdline_printf(iterpool, " r%ld%c", rev, i == lb->merge_stack->nelts - 1 ? '\n' : ',')); } + svn_pool_destroy(iterpool); } if (message != NULL) @@ -473,7 +454,12 @@ log_entry_receiver(void *baton, } if (log_entry->has_children) - APR_ARRAY_PUSH(lb->merge_stack, svn_revnum_t) = log_entry->revision; + { + if (! lb->merge_stack) + lb->merge_stack = apr_array_make(lb->pool, 1, sizeof(svn_revnum_t)); + + APR_ARRAY_PUSH(lb->merge_stack, svn_revnum_t) = log_entry->revision; + } return SVN_NO_ERROR; } @@ -481,7 +467,7 @@ log_entry_receiver(void *baton, /* This implements `svn_log_entry_receiver_t', printing the logs in XML. * - * BATON is of type `struct log_receiver_baton'. + * BATON is of type `svn_cl__log_receiver_baton'. * * Here is an example of the output; note that the "<log>" and * "</log>" tags are not emitted by this function: @@ -515,12 +501,12 @@ log_entry_receiver(void *baton, * </log> * */ -static svn_error_t * -log_entry_receiver_xml(void *baton, - svn_log_entry_t *log_entry, - apr_pool_t *pool) +svn_error_t * +svn_cl__log_entry_receiver_xml(void *baton, + svn_log_entry_t *log_entry, + apr_pool_t *pool) { - struct log_receiver_baton *lb = baton; + svn_cl__log_receiver_baton *lb = baton; /* Collate whole log message into sb before printing. */ svn_stringbuf_t *sb = svn_stringbuf_create_empty(pool); char *revstr; @@ -540,7 +526,8 @@ log_entry_receiver_xml(void *baton, { svn_xml_make_close_tag(&sb, pool, "logentry"); SVN_ERR(svn_cl__error_checked_fputs(sb->data, stdout)); - apr_array_pop(lb->merge_stack); + if (lb->merge_stack) + apr_array_pop(lb->merge_stack); return SVN_NO_ERROR; } @@ -551,7 +538,12 @@ log_entry_receiver_xml(void *baton, log_entry->changed_paths2, pool)) { if (log_entry->has_children) - APR_ARRAY_PUSH(lb->merge_stack, svn_revnum_t) = log_entry->revision; + { + if (! lb->merge_stack) + lb->merge_stack = apr_array_make(lb->pool, 1, sizeof(svn_revnum_t)); + + APR_ARRAY_PUSH(lb->merge_stack, svn_revnum_t) = log_entry->revision; + } return SVN_NO_ERROR; } @@ -565,8 +557,19 @@ log_entry_receiver_xml(void *baton, revstr = apr_psprintf(pool, "%ld", log_entry->revision); /* <logentry revision="xxx"> */ - svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "logentry", - "revision", revstr, NULL); + if (lb->merge_stack && lb->merge_stack->nelts > 0) + { + svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "logentry", + "revision", revstr, "reverse-merge", + log_entry->subtractive_merge ? "true" : "false", + SVN_VA_NULL); + + } + else + { + svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "logentry", + "revision", revstr, SVN_VA_NULL); + } /* <author>xxx</author> */ svn_cl__xml_tagged_cdata(&sb, pool, "author", author); @@ -587,7 +590,7 @@ log_entry_receiver_xml(void *baton, /* <paths> */ svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "paths", - NULL); + SVN_VA_NULL); /* Get an array of sorted hash keys. */ sorted_paths = svn_sort__hash(log_entry->changed_paths2, @@ -619,7 +622,7 @@ log_entry_receiver_xml(void *baton, log_item->text_modified), "prop-mods", svn_tristate__to_word( log_item->props_modified), - NULL); + SVN_VA_NULL); } else { @@ -632,7 +635,7 @@ log_entry_receiver_xml(void *baton, log_item->text_modified), "prop-mods", svn_tristate__to_word( log_item->props_modified), - NULL); + SVN_VA_NULL); } /* xxx</path> */ svn_xml_escape_cdata_cstring(&sb, path, pool); @@ -652,7 +655,7 @@ log_entry_receiver_xml(void *baton, svn_compat_log_revprops_clear(log_entry->revprops); if (log_entry->revprops && apr_hash_count(log_entry->revprops) > 0) { - svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "revprops", NULL); + svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "revprops", SVN_VA_NULL); SVN_ERR(svn_cmdline__print_xml_prop_hash(&sb, log_entry->revprops, FALSE, /* name_only */ FALSE, pool)); @@ -660,7 +663,12 @@ log_entry_receiver_xml(void *baton, } if (log_entry->has_children) - APR_ARRAY_PUSH(lb->merge_stack, svn_revnum_t) = log_entry->revision; + { + if (! lb->merge_stack) + lb->merge_stack = apr_array_make(lb->pool, 1, sizeof(svn_revnum_t)); + + APR_ARRAY_PUSH(lb->merge_stack, svn_revnum_t) = log_entry->revision; + } else svn_xml_make_close_tag(&sb, pool, "logentry"); @@ -677,7 +685,7 @@ svn_cl__log(apr_getopt_t *os, svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state; svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx; apr_array_header_t *targets; - struct log_receiver_baton lb; + svn_cl__log_receiver_baton lb; const char *target; int i; apr_array_header_t *revprops; @@ -785,7 +793,7 @@ svn_cl__log(apr_getopt_t *os, lb.depth = opt_state->depth == svn_depth_unknown ? svn_depth_infinity : opt_state->depth; lb.diff_extensions = opt_state->extensions; - lb.merge_stack = apr_array_make(pool, 0, sizeof(svn_revnum_t)); + lb.merge_stack = NULL; lb.search_patterns = opt_state->search_patterns; lb.pool = pool; @@ -813,8 +821,8 @@ svn_cl__log(apr_getopt_t *os, hi != NULL; hi = apr_hash_next(hi)) { - const char *property = svn__apr_hash_index_key(hi); - svn_string_t *value = svn__apr_hash_index_val(hi); + const char *property = apr_hash_this_key(hi); + svn_string_t *value = apr_hash_this_val(hi); if (value && value->data[0] != '\0') return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, @@ -839,7 +847,7 @@ svn_cl__log(apr_getopt_t *os, opt_state->stop_on_copy, opt_state->use_merge_history, revprops, - log_entry_receiver_xml, + svn_cl__log_entry_receiver_xml, &lb, ctx, pool)); @@ -862,13 +870,13 @@ svn_cl__log(apr_getopt_t *os, opt_state->stop_on_copy, opt_state->use_merge_history, revprops, - log_entry_receiver, + svn_cl__log_entry_receiver, &lb, ctx, pool)); if (! opt_state->incremental) - SVN_ERR(svn_cmdline_printf(pool, SEP_STRING)); + SVN_ERR(svn_cmdline_printf(pool, SVN_CL__LOG_SEP_STRING)); } return SVN_NO_ERROR; |