void CSVNLogQuery::Log ( const CTSVNPathList& targets , const SVNRev& peg_revision , const SVNRev& start , const SVNRev& end , int limit , bool strictNodeHistory , ILogReceiver* receiver , bool includeChanges , bool includeMerges , bool includeStandardRevProps , bool includeUserRevProps , const TRevPropNames& userRevProps) { SVNPool localpool (pool); // construct parameters: // everything we need to relay the result to the receiver SBaton baton = { receiver , includeChanges , includeStandardRevProps , includeUserRevProps}; // list of revision ranges to fetch // (as of now, there is only one such range) svn_opt_revision_range_t revision_range = {*start, *end}; apr_array_header_t* revision_ranges = apr_array_make (localpool, 1, sizeof(apr_array_header_t*)); *(svn_opt_revision_range_t**)apr_array_push (revision_ranges) = &revision_range; // build list of revprops to fetch. Fetch all of them // if all user-revprops are requested but no std-revprops // (post-filter before them passing to the receiver) apr_array_header_t* revprops = NULL; if (includeStandardRevProps) { // fetch user rev-props? if (includeUserRevProps) { // fetch some but not all user rev-props? if (!userRevProps.empty()) { revprops = apr_array_make ( localpool , (int)GetStandardRevProps().size() + (int)userRevProps.size() , sizeof(const char *)); AppendStrings (localpool, revprops, GetStandardRevProps()); AppendStrings (localpool, revprops, userRevProps); } } else { // standard revprops only revprops = apr_array_make ( localpool , (int)GetStandardRevProps().size() , sizeof(const char *)); AppendStrings (localpool, revprops, GetStandardRevProps()); } } else { // fetch some but not all user rev-props? if (includeUserRevProps && !userRevProps.empty()) { revprops = apr_array_make ( localpool , (int)userRevProps.size() , sizeof(const char *)); AppendStrings (localpool, revprops, userRevProps); } } CHooks::Instance().PreConnect(targets); SVNTRACE ( svn_error_t *result = svn_client_log5 ( targets.MakePathArray (localpool) , peg_revision , revision_ranges , limit , includeChanges , strictNodeHistory , includeMerges , revprops , LogReceiver , (void *)&baton , context , localpool), NULL ); if (result != NULL) throw SVNError (result); }
// PYSVN_HAS_CLIENT_LOG4 version Py::Object pysvn_client::cmd_log( const Py::Tuple &a_args, const Py::Dict &a_kws ) { static argument_description args_desc[] = { { true, name_url_or_path }, { false, name_revision_start }, { false, name_revision_end }, { false, name_discover_changed_paths }, { false, name_strict_node_history }, { false, name_limit }, { false, name_peg_revision }, { false, name_include_merged_revisions }, { false, name_revprops }, { false, NULL } }; FunctionArguments args( "log", args_desc, a_args, a_kws ); args.check(); SvnPool pool( m_context ); svn_opt_revision_t revision_start = args.getRevision( name_revision_start, svn_opt_revision_head ); svn_opt_revision_t revision_end = args.getRevision( name_revision_end, svn_opt_revision_number ); bool discover_changed_paths = args.getBoolean( name_discover_changed_paths, false ); bool strict_node_history = args.getBoolean( name_strict_node_history, true ); int limit = args.getInteger( name_limit, 0 ); svn_opt_revision_t peg_revision = args.getRevision( name_peg_revision, svn_opt_revision_unspecified ); svn_boolean_t include_merged_revisions = args.getBoolean( name_include_merged_revisions, false ); apr_array_header_t *revprops = NULL; if( args.hasArg( name_revprops ) ) { Py::Object py_revprop = args.getArg( name_revprops ); if( !py_revprop.isNone() ) { revprops = arrayOfStringsFromListOfStrings( py_revprop, pool ); } } Py::Object url_or_path_obj = args.getArg( name_url_or_path ); Py::List url_or_path_list; if( url_or_path_obj.isList() ) { url_or_path_list = url_or_path_obj; } else { Py::List py_list; py_list.append( url_or_path_obj ); url_or_path_list = py_list; } for( size_t i=0; i<url_or_path_list.size(); i++ ) { Py::Bytes py_path( asUtf8Bytes( url_or_path_list[ i ] ) ); std::string path( py_path.as_std_string() ); bool is_url = is_svn_url( path ); revisionKindCompatibleCheck( is_url, peg_revision, name_peg_revision, name_url_or_path ); revisionKindCompatibleCheck( is_url, revision_start, name_revision_start, name_url_or_path ); revisionKindCompatibleCheck( is_url, revision_end, name_revision_end, name_url_or_path ); } apr_array_header_t *targets = targetsFromStringOrList( url_or_path_list, pool ); Py::List log_list; try { checkThreadPermission(); PythonAllowThreads permission( m_context ); Log4Baton baton( &permission, pool, log_list ); baton.m_wrapper_log = &m_wrapper_log; baton.m_wrapper_log_changed_path = &m_wrapper_log_changed_path; #if defined( PYSVN_HAS_CLIENT_LOG5 ) apr_array_header_t *revision_ranges = apr_array_make( pool, 0, sizeof(svn_opt_revision_range_t *) ); svn_opt_revision_range_t *range = reinterpret_cast<svn_opt_revision_range_t *>( apr_palloc( pool, sizeof(*range) ) ); range->start = revision_start; range->end = revision_end; APR_ARRAY_PUSH( revision_ranges, svn_opt_revision_range_t * ) = range; svn_error_t *error = svn_client_log5 ( targets, &peg_revision, revision_ranges, limit, discover_changed_paths, strict_node_history, include_merged_revisions, revprops, log4Receiver, reinterpret_cast<void *>( &baton ), m_context, pool ); #else svn_error_t *error = svn_client_log4 ( targets, &peg_revision, &revision_start, &revision_end, limit, discover_changed_paths, strict_node_history, include_merged_revisions, revprops, log4Receiver, reinterpret_cast<void *>( &baton ), m_context, pool ); #endif permission.allowThisThread(); if( error != NULL ) throw SvnException( error ); } catch( SvnException &e ) { // use callback error over ClientException m_context.checkForError( m_module.client_error ); throw_client_error( e ); } return log_list; }