const LogEntries * Client::log(const char * path, const Revision & revisionStart, const Revision & revisionEnd, bool discoverChangedPaths, bool strictNodeHistory) throw(ClientException) { Pool pool; Targets target(path); LogEntries * entries = new LogEntries(); svn_error_t *error; int limit = 0; error = svn_client_log2( target.array(pool), revisionStart.revision(), revisionEnd.revision(), limit, discoverChangedPaths ? 1 : 0, strictNodeHistory ? 1 : 0, logReceiver, entries, *m_context, // client ctx pool); if (error != NULL) { delete entries; throw ClientException(error); } return entries; }
// PYSVN_HAS_CLIENT_LOG, PYSVN_HAS_CLIENT_LOG2, PYSVN_HAS_CLIENT_LOG3 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 }, #if defined( PYSVN_HAS_CLIENT_LOG2 ) || defined( PYSVN_HAS_CLIENT_LOG3 ) { false, name_limit }, #endif #if defined( PYSVN_HAS_CLIENT_LOG3 ) { false, name_peg_revision }, #endif #if defined( PYSVN_HAS_CLIENT_LOG4 ) { false, name_include_merged_revisions }, { false, name_revprops }, #endif { false, NULL } }; FunctionArguments args( "log", args_desc, a_args, a_kws ); args.check(); 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 ); #if defined( PYSVN_HAS_CLIENT_LOG3 ) svn_opt_revision_t peg_revision = args.getRevision( name_peg_revision, svn_opt_revision_unspecified ); #endif #if defined( PYSVN_HAS_CLIENT_LOG4 ) svn_boolean_t include_merged_revisions = args.getBoolean( name_include_merged_revisions, false ); apr_array_header_t *revprops = NULL; Py::Object py_revprop = args.getArg( name_revprops ); if( py_revprop is not None ) { revprops = arrayOfStringsFromListOfStrings( py_revprop. pool ); } #endif 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 ); // std::cout << "peg_revision " << peg_revision.kind << " " << peg_revision.value.number << std::endl; // std::cout << "revision_start " << revision_start.kind << " " << revision_start.value.number << std::endl; // std::cout << "revision_end " << revision_end.kind << " " << revision_end.value.number << std::endl; #if defined( PYSVN_HAS_CLIENT_LOG3 ) revisionKindCompatibleCheck( is_url, peg_revision, name_peg_revision, name_url_or_path ); #endif revisionKindCompatibleCheck( is_url, revision_start, name_revision_start, name_url_or_path ); revisionKindCompatibleCheck( is_url, revision_end, name_revision_end, name_url_or_path ); } SvnPool pool( m_context ); apr_array_header_t *targets = targetsFromStringOrList( url_or_path_list, pool ); #if defined( PYSVN_HAS_CLIENT_LOG4 ) Log4Baton baton( permission, pool ); #else std::list<LogEntryInfo> all_entries; #endif try { checkThreadPermission(); PythonAllowThreads permission( m_context ); #if defined( PYSVN_HAS_CLIENT_LOG4 ) 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, logReceiver, &all_entries, m_context, pool ); #elif defined( PYSVN_HAS_CLIENT_LOG3 ) svn_error_t *error = svn_client_log3 ( targets, &peg_revision, &revision_start, &revision_end, limit, discover_changed_paths, strict_node_history, logReceiver, &all_entries, m_context, pool ); #elif defined( PYSVN_HAS_CLIENT_LOG2 ) svn_error_t *error = svn_client_log2 ( targets, &revision_start, &revision_end, limit, discover_changed_paths, strict_node_history, logReceiver, &all_entries, m_context, pool ); #else svn_error_t *error = svn_client_log ( targets, &revision_start, &revision_end, discover_changed_paths, strict_node_history, logReceiver, &all_entries, 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 ); } apr_time_t now = apr_time_now(); // convert the entries into python objects Py::List entries_list; std::list<LogEntryInfo>::const_iterator entry_it = all_entries.begin(); while( entry_it != all_entries.end() ) { const LogEntryInfo &entry = *entry_it; ++entry_it; Py::Dict entry_dict; entry_dict[name_author] = Py::String( entry.m_author, name_utf8 ); entry_dict[name_date] = toObject( convertStringToTime( entry.m_date, now, pool ) ); entry_dict[name_message] = Py::String( entry.m_message, name_utf8 ); entry_dict[name_revision] = Py::asObject( new pysvn_revision( svn_opt_revision_number, 0, entry.m_revision ) ); Py::List changed_paths_list; std::list<LogChangePathInfo>::const_iterator changed_paths_it = entry.m_changed_paths.begin(); while( changed_paths_it != entry.m_changed_paths.end() ) { const LogChangePathInfo &change_entry = *changed_paths_it; ++changed_paths_it; Py::Dict changed_entry_dict; changed_entry_dict[name_path] = Py::String( change_entry.m_path, name_utf8 ); changed_entry_dict[name_action] = Py::String( &change_entry.m_action, 1 ); changed_entry_dict[name_copyfrom_path] = utf8_string_or_none( change_entry.m_copy_from_path ); if( SVN_IS_VALID_REVNUM( change_entry.m_copy_from_revision ) ) changed_entry_dict[name_copyfrom_revision] = Py::asObject( new pysvn_revision( svn_opt_revision_number, 0, change_entry.m_copy_from_revision ) ); else changed_entry_dict[name_copyfrom_revision] = Py::None(); changed_paths_list.append( m_wrapper_log_changed_path.wrapDict( changed_entry_dict ) ); } entry_dict[name_changed_paths] = changed_paths_list; entries_list.append( m_wrapper_log.wrapDict( entry_dict ) ); } return entries_list; }