00001 /** 00002 * @copyright 00003 * ==================================================================== 00004 * Copyright (c) 2000-2004 CollabNet. All rights reserved. 00005 * 00006 * This software is licensed as described in the file COPYING, which 00007 * you should have received as part of this distribution. The terms 00008 * are also available at http://subversion.tigris.org/license-1.html. 00009 * If newer versions of this license are posted there, you may use a 00010 * newer version instead, at your option. 00011 * 00012 * This software consists of voluntary contributions made by many 00013 * individuals. For exact contribution history, see the revision 00014 * history and logs, available at http://subversion.tigris.org/. 00015 * ==================================================================== 00016 * @endcopyright 00017 * 00018 * @file svn_repos.h 00019 * @brief tools built on top of the filesystem. 00020 */ 00021 00022 00023 #ifndef SVN_REPOS_H 00024 #define SVN_REPOS_H 00025 00026 #include <apr_pools.h> 00027 #include <apr_hash.h> 00028 #include "svn_fs.h" 00029 #include "svn_delta.h" 00030 #include "svn_types.h" 00031 #include "svn_error.h" 00032 #include "svn_version.h" 00033 00034 00035 #ifdef __cplusplus 00036 extern "C" { 00037 #endif /* __cplusplus */ 00038 00039 /* ---------------------------------------------------------------*/ 00040 00041 /** 00042 * Get libsvn_repos version information. 00043 * @since New in 1.1. 00044 */ 00045 const svn_version_t *svn_repos_version (void); 00046 00047 00048 00049 /** Callback type for checking authorization on paths produced by (at 00050 * least) svn_repos_dir_delta(). 00051 * 00052 * Set @a *allowed to TRUE to indicate that some operation is 00053 * authorized for @a path in @a root, or set it to FALSE to indicate 00054 * unauthorized (presumably according to state stored in @a baton). 00055 * 00056 * Do not assume @a pool has any lifetime beyond this call. 00057 * 00058 * The exact operation being authorized depends on the callback 00059 * implementation. For read authorization, for example, the caller 00060 * would implement an instance that does read checking, and pass it as 00061 * a parameter named [perhaps] 'authz_read_func'. The receiver of 00062 * that parameter might also take another parameter named 00063 * 'authz_write_func', which although sharing this type, would be a 00064 * different implementation. 00065 * 00066 * Note: If someday we want more sophisticated authorization states 00067 * than just yes/no, @a allowed can become an enum type. 00068 */ 00069 typedef svn_error_t *(*svn_repos_authz_func_t) (svn_boolean_t *allowed, 00070 svn_fs_root_t *root, 00071 const char *path, 00072 void *baton, 00073 apr_pool_t *pool); 00074 00075 /** @since New in 1.1. 00076 * A callback function type for use in @c svn_repos_get_file_revs. 00077 * @a baton is provided by the caller, @a path is the pathname of the file 00078 * in revision @a rev and @a rev_props are the revision properties. 00079 * If @a delta_handler and @a delta_baton are non-NULL, they may be set to a 00080 * handler/baton which will be called with the delta between the previous 00081 * revision and this one after the return of this callback. They may be 00082 * left as NULL/NULL. 00083 * @a prop_diffs is an array of svn_prop_t elements indicating the property 00084 * delta for this and the previous revision. 00085 * @a pool may be used for temporary allocations, but you can't rely 00086 * on objects allocated to live outside of this particular call and the 00087 * immediately following calls to @a *delta_handler if any. */ 00088 typedef svn_error_t *(*svn_repos_file_rev_handler_t) 00089 (void *baton, 00090 const char *path, 00091 svn_revnum_t rev, 00092 apr_hash_t *rev_props, 00093 svn_txdelta_window_handler_t *delta_handler, 00094 void **delta_baton, 00095 apr_array_header_t *prop_diffs, 00096 apr_pool_t *pool); 00097 00098 00099 /** The repository object. */ 00100 typedef struct svn_repos_t svn_repos_t; 00101 00102 /* Opening and creating repositories. */ 00103 00104 00105 /** Find the root path of the repository that contains @a path. 00106 * 00107 * If a repository was found, the path to the root of the repository 00108 * is returned, else @c NULL. The pointer to the returned path may be 00109 * equal to @a path argument. 00110 */ 00111 const char *svn_repos_find_root_path (const char *path, 00112 apr_pool_t *pool); 00113 00114 /** Set @a *repos_p to a repository object for the repository at @a path. 00115 * 00116 * Allocate @a *repos_p in @a pool. 00117 * 00118 * Acquires a shared lock on the repository, and attaches a cleanup 00119 * function to @a pool to remove the lock. If no lock can be acquired, 00120 * returns error, with undefined effect on @a *repos_p. If an exclusive 00121 * lock is present, this blocks until it's gone. 00122 */ 00123 svn_error_t *svn_repos_open (svn_repos_t **repos_p, 00124 const char *path, 00125 apr_pool_t *pool); 00126 00127 /** Create a new Subversion repository at @a path, building the necessary 00128 * directory structure, creating the Berkeley DB filesystem environment, 00129 * and so on. Return the (open) repository object in @a *repos_p, 00130 * allocated in @a pool. 00131 * 00132 * @a config is a client configuration hash of @c svn_config_t * items 00133 * keyed on config category names, and may be NULL. 00134 * 00135 * @a fs_config is passed to the filesystem, and may be NULL. 00136 * 00137 * @a unused_1 and @a unused_2 are not used and should be NULL. 00138 */ 00139 svn_error_t *svn_repos_create (svn_repos_t **repos_p, 00140 const char *path, 00141 const char *unused_1, 00142 const char *unused_2, 00143 apr_hash_t *config, 00144 apr_hash_t *fs_config, 00145 apr_pool_t *pool); 00146 00147 /** Destroy the Subversion repository found at @a path, using @a pool for any 00148 * necessary allocations. 00149 */ 00150 svn_error_t *svn_repos_delete (const char *path, apr_pool_t *pool); 00151 00152 /** Return the filesystem associated with repository object @a repos. */ 00153 svn_fs_t *svn_repos_fs (svn_repos_t *repos); 00154 00155 00156 /** Make a hot copy of the Subversion repository found at @a src_path 00157 * to @a dst_path. 00158 * 00159 * @copydoc svn_fs_hotcopy_berkeley() 00160 */ 00161 svn_error_t * svn_repos_hotcopy (const char *src_path, 00162 const char *dst_path, 00163 svn_boolean_t clean_logs, 00164 apr_pool_t *pool); 00165 00166 /** 00167 * @deprecated Provided for backward compatibility with the 1.0.0 API. 00168 * 00169 * Run database recovery procedures on the repository at @a path, 00170 * returning the database to a consistent state. Use @a pool for all 00171 * allocation. 00172 * 00173 * Acquires an @a exclusive lock on the repository, recovers the 00174 * database, and releases the lock. If an exclusive lock can't be 00175 * acquired, returns error. 00176 */ 00177 svn_error_t *svn_repos_recover (const char *path, apr_pool_t *pool); 00178 00179 /** 00180 * @since New in 1.1. 00181 * 00182 * Run database recovery procedures on the repository at @a path, 00183 * returning the database to a consistent state. Use @a pool for all 00184 * allocation. 00185 * 00186 * Acquires an @a exclusive lock on the repository, recovers the 00187 * database, and releases the lock. If an exclusive lock can't be 00188 * acquired, returns error. 00189 * 00190 * If @a nonblocking is TRUE, an error of type EWOULDBLOCK is 00191 * returned if the lock is not immediately available. 00192 * 00193 * If @a start_callback is not NULL, it will be called with @a 00194 * start_callback_baton as argument before the recovery starts, but 00195 * after the exclusive lock has been acquired. 00196 */ 00197 svn_error_t *svn_repos_recover2 (const char *path, 00198 svn_boolean_t nonblocking, 00199 svn_error_t *(*start_callback) (void *baton), 00200 void *start_callback_baton, 00201 apr_pool_t *pool); 00202 00203 /** This function is a wrapper around svn_fs_berkeley_logfiles(), 00204 * returning log file paths relative to the root of the repository. 00205 * 00206 * @copydoc svn_fs_berkeley_logfiles() 00207 */ 00208 svn_error_t *svn_repos_db_logfiles (apr_array_header_t **logfiles, 00209 const char *path, 00210 svn_boolean_t only_unused, 00211 apr_pool_t *pool); 00212 00213 00214 00215 /* Repository Paths */ 00216 00217 /** Return the top-level repository path allocated in @a pool. */ 00218 const char *svn_repos_path (svn_repos_t *repos, apr_pool_t *pool); 00219 00220 /** Return the path to @a repos's Berkeley DB environment, allocated in 00221 * @a pool. 00222 */ 00223 const char *svn_repos_db_env (svn_repos_t *repos, apr_pool_t *pool); 00224 00225 /** Return path to @a repos's config directory, allocated in @a pool. */ 00226 const char *svn_repos_conf_dir (svn_repos_t *repos, apr_pool_t *pool); 00227 00228 /** Return path to @a repos's svnserve.conf, allocated in @a pool. */ 00229 const char *svn_repos_svnserve_conf (svn_repos_t *repos, apr_pool_t *pool); 00230 00231 /** Return path to @a repos's lock directory, allocated in @a pool. */ 00232 const char *svn_repos_lock_dir (svn_repos_t *repos, apr_pool_t *pool); 00233 00234 /** Return path to @a repos's db lockfile, allocated in @a pool. */ 00235 const char *svn_repos_db_lockfile (svn_repos_t *repos, apr_pool_t *pool); 00236 00237 /** Return path to @a repos's db logs lockfile, allocated in @a pool. */ 00238 const char *svn_repos_db_logs_lockfile (svn_repos_t *repos, apr_pool_t *pool); 00239 00240 /** Return the path to @a repos's hook directory, allocated in @a pool. */ 00241 const char *svn_repos_hook_dir (svn_repos_t *repos, apr_pool_t *pool); 00242 00243 /** Return the path to @a repos's start-commit hook, allocated in @a pool. */ 00244 const char *svn_repos_start_commit_hook (svn_repos_t *repos, apr_pool_t *pool); 00245 00246 /** Return the path to @a repos's pre-commit hook, allocated in @a pool. */ 00247 const char *svn_repos_pre_commit_hook (svn_repos_t *repos, apr_pool_t *pool); 00248 00249 /** Return the path to @a repos's post-commit hook, allocated in @a pool. */ 00250 const char *svn_repos_post_commit_hook (svn_repos_t *repos, apr_pool_t *pool); 00251 00252 /** Return the path to @a repos's pre-revprop-change hook, allocated in 00253 * @a pool. 00254 */ 00255 const char *svn_repos_pre_revprop_change_hook (svn_repos_t *repos, 00256 apr_pool_t *pool); 00257 00258 /** Return the path to @a repos's post-revprop-change hook, allocated in 00259 * @a pool. 00260 */ 00261 const char *svn_repos_post_revprop_change_hook (svn_repos_t *repos, 00262 apr_pool_t *pool); 00263 00264 00265 00266 /* ---------------------------------------------------------------*/ 00267 00268 /* Reporting the state of a working copy, for updates. */ 00269 00270 00271 /** Construct and return a @a report_baton that will be paired with some 00272 * @c svn_ra_reporter_t table. The table and baton are used to build a 00273 * transaction in the system; when the report is finished, 00274 * @c svn_repos_dir_delta is called on the transaction, driving 00275 * @a editor/@a edit_baton. 00276 * 00277 * Specifically, the report will create a transaction made by @a username, 00278 * relative to @a fs_base in the filesystem. @a target is a single path 00279 * component, used to limit the scope of the report to a single entry of 00280 * @a fs_base, or "" if all of @a fs_base itself is the main subject of 00281 * the report. 00282 * 00283 * @a tgt_path and @a revnum is the fs path/revision pair that is the 00284 * "target" of @c dir_delta. In other words, a tree delta will be 00285 * returned that transforms the transaction into @a tgt_path/@a revnum. 00286 * @a tgt_path may (indeed, should) be @c NULL when the source and target 00287 * paths of the report are the same. That is, @a tgt_path should *only* 00288 * be specified when specifying that the resultant editor drive be one 00289 * that transforms the reported hierarchy into a pristine tree of 00290 * @a tgt_path at revision @a revnum. Else, a @c NULL value for @a tgt_path 00291 * will indicate that the editor should be driven in such a way as to 00292 * transform the reported hierarchy to revision @a revnum, preserving the 00293 * reported hierarchy. 00294 * 00295 * @a text_deltas instructs the driver of the @a editor to enable 00296 * the generation of text deltas. 00297 * 00298 * @a recurse instructs the driver of the @a editor to send a recursive 00299 * delta (or not.) 00300 * 00301 * @a ignore_ancestry instructs the driver to ignore node ancestry 00302 * when determining how to transmit differences. 00303 * 00304 * The @a authz_read_func and @a authz_read_baton are passed along to 00305 * @c svn_repos_dir_delta(); see that function for how they are used. 00306 * 00307 * All allocation for the context and collected state will occur in 00308 * @a pool. 00309 */ 00310 svn_error_t * 00311 svn_repos_begin_report (void **report_baton, 00312 svn_revnum_t revnum, 00313 const char *username, 00314 svn_repos_t *repos, 00315 const char *fs_base, 00316 const char *target, 00317 const char *tgt_path, 00318 svn_boolean_t text_deltas, 00319 svn_boolean_t recurse, 00320 svn_boolean_t ignore_ancestry, 00321 const svn_delta_editor_t *editor, 00322 void *edit_baton, 00323 svn_repos_authz_func_t authz_read_func, 00324 void *authz_read_baton, 00325 apr_pool_t *pool); 00326 00327 00328 /** Given a @a report_baton constructed by @c svn_repos_begin_report(), this 00329 * routine will build @a revision:@a path into the current transaction. 00330 * This routine is called multiple times to create a transaction that 00331 * is a "mirror" of a working copy. 00332 * 00333 * The first call of this in a given report usually passes an empty 00334 * @a path; that allows the reporter to set up the correct root revision 00335 * (useful when creating a txn, for example). 00336 * 00337 * If @a start_empty is set and @a path is a directory, then remove 00338 * all children and props of the freshly-linked directory. This is 00339 * for 'low confidence' client reporting. 00340 * 00341 * All temporary allocations are done in @a pool. 00342 */ 00343 svn_error_t *svn_repos_set_path (void *report_baton, 00344 const char *path, 00345 svn_revnum_t revision, 00346 svn_boolean_t start_empty, 00347 apr_pool_t *pool); 00348 00349 00350 /** Given a @a report_baton constructed by @c svn_repos_begin_report(), 00351 * this routine will build @a revision:@a link_path into the current 00352 * transaction at @a path. Note that while @a path is relative to the 00353 * anchor/target used in the creation of the @a report_baton, @a link_path 00354 * is an absolute filesystem path! 00355 * 00356 * If @a start_empty is set and @a path is a directory, then remove 00357 * all children and props of the freshly-linked directory. This is 00358 * for 'low confidence' client reporting. 00359 * 00360 * All temporary allocations are done in @a pool. 00361 */ 00362 svn_error_t *svn_repos_link_path (void *report_baton, 00363 const char *path, 00364 const char *link_path, 00365 svn_revnum_t revision, 00366 svn_boolean_t start_empty, 00367 apr_pool_t *pool); 00368 00369 /** Given a @a report_baton constructed by @c svn_repos_begin_report(), 00370 * this routine will remove @a path from the current fs transaction. 00371 * 00372 * (This allows the reporter's driver to describe missing pieces of a 00373 * working copy, so that 'svn up' can recreate them.) 00374 * 00375 * All temporary allocations are done in @a pool. 00376 */ 00377 svn_error_t *svn_repos_delete_path (void *report_baton, 00378 const char *path, 00379 apr_pool_t *pool); 00380 00381 /** Make the filesystem compare the transaction to a revision and have 00382 * it drive an update editor (using @c svn_repos_delta_dirs()), then 00383 * abort the transaction. If an error occurs during the driving of 00384 * the editor, we do NOT abort the edit; that responsibility belongs 00385 * to the caller, if it happens at all. The fs transaction will be 00386 * aborted even if the editor drive fails, so the caller does not need 00387 * to clean up. 00388 */ 00389 svn_error_t *svn_repos_finish_report (void *report_baton, 00390 apr_pool_t *pool); 00391 00392 00393 /** The report-driver is bailing, so abort the fs transaction. This 00394 * function can be called anytime before @c svn_repos_finish_report() is 00395 * called. No other reporting functions should be called after calling 00396 * this function. 00397 */ 00398 svn_error_t *svn_repos_abort_report (void *report_baton, 00399 apr_pool_t *pool); 00400 00401 00402 /* ---------------------------------------------------------------*/ 00403 00404 /* The magical dir_delta update routines. */ 00405 00406 /** Use the provided @a editor and @a edit_baton to describe the changes 00407 * necessary for making a given node (and its descendants, if it is a 00408 * directory) under @a src_root look exactly like @a tgt_path under 00409 * @a tgt_root. @a src_entry is the node to update. If @a src_entry 00410 * is empty, then compute the difference between the entire tree 00411 * anchored at @a src_parent_dir under @a src_root and @a tgt_path 00412 * under @a target_root. Else, describe the changes needed to update 00413 * only that entry in @a src_parent_dir. Typically, callers of this 00414 * function will use a @a tgt_path that is the concatenation of @a 00415 * src_parent_dir and @a src_entry. 00416 * 00417 * @a src_root and @a tgt_root can both be either revision or transaction 00418 * roots. If @a tgt_root is a revision, @a editor's @c set_target_revision() 00419 * will be called with the @a tgt_root's revision number, else it will 00420 * not be called at all. 00421 * 00422 * If @a authz_read_func is non-null, invoke it before any call to 00423 * 00424 * @a editor->open_root 00425 * @a editor->add_directory 00426 * @a editor->open_directory 00427 * @a editor->add_file 00428 * @a editor->open_file 00429 * 00430 * passing @a tgt_root, the same path that would be passed to the 00431 * editor function in question, and @a authz_read_baton. If the 00432 * @a *allowed parameter comes back TRUE, then proceed with the planned 00433 * editor call; else if FALSE, then invoke @a editor->absent_file or 00434 * @a editor->absent_directory as appropriate, except if the planned 00435 * editor call was open_root, throw SVN_ERR_AUTHZ_ROOT_UNREADABLE. 00436 * 00437 * If @a text_deltas is @c FALSE, send a single @c NULL txdelta window to 00438 * the window handler returned by @a editor->apply_textdelta(). 00439 * 00440 * If @a entry_props is @c TRUE, accompany each opened/added entry with 00441 * propchange editor calls that relay special "entry props" (this 00442 * is typically used only for working copy updates). 00443 * 00444 * @a ignore_ancestry instructs the function to ignore node ancestry 00445 * when determining how to transmit differences. 00446 * 00447 * Before completing successfully, this function calls @a editor's 00448 * @c close_edit(), so the caller should expect its @a edit_baton to be 00449 * invalid after its use with this function. 00450 * 00451 * Do any allocation necessary for the delta computation in @a pool. 00452 * This function's maximum memory consumption is at most roughly 00453 * proportional to the greatest depth of the tree under @a tgt_root, not 00454 * the total size of the delta. 00455 */ 00456 svn_error_t * 00457 svn_repos_dir_delta (svn_fs_root_t *src_root, 00458 const char *src_parent_dir, 00459 const char *src_entry, 00460 svn_fs_root_t *tgt_root, 00461 const char *tgt_path, 00462 const svn_delta_editor_t *editor, 00463 void *edit_baton, 00464 svn_repos_authz_func_t authz_read_func, 00465 void *authz_read_baton, 00466 svn_boolean_t text_deltas, 00467 svn_boolean_t recurse, 00468 svn_boolean_t entry_props, 00469 svn_boolean_t ignore_ancestry, 00470 apr_pool_t *pool); 00471 00472 /** Use the provided @a editor and @a edit_baton to describe the 00473 * skeletal changes made in a particular filesystem @a root 00474 * (revision or transaction). 00475 * 00476 * The @a editor passed to this function should be aware of the fact 00477 * that calls to its change_dir_prop(), change_file_prop(), and 00478 * apply_textdelta() functions will not contain meaningful data, and 00479 * merely serve as indications that properties or textual contents 00480 * were changed. 00481 * 00482 * NOTE: this editor driver passes SVN_INVALID_REVNUM for all 00483 * revision parameters in the editor interface except the copyfrom 00484 * parameter of the add_file() and add_directory() editor functions. 00485 * 00486 * ### TODO: This ought to take an svn_repos_authz_func_t too. 00487 * The only reason it doesn't yet is the difficulty of implementing 00488 * that correctly, plus lack of strong present need -- it's currently 00489 * only used in creating a DAV MERGE response, in 'svnadmin dump', and 00490 * in svnlook. 00491 */ 00492 svn_error_t * 00493 svn_repos_replay (svn_fs_root_t *root, 00494 const svn_delta_editor_t *editor, 00495 void *edit_baton, 00496 apr_pool_t *pool); 00497 00498 00499 /* ---------------------------------------------------------------*/ 00500 00501 /* Making commits. */ 00502 00503 /** Return an @a editor and @a edit_baton to commit changes to @a session->fs, 00504 * beginning at location 'rev:@a base_path', where "rev" is the argument 00505 * given to @c open_root(). Store @a user as the author of the commit and 00506 * @a log_msg as the commit message. 00507 * 00508 * @a repos is a previously opened repository. @a repos_url is the decoded 00509 * URL to the base of the repository, and is used to check copyfrom paths. 00510 * 00511 * Calling @a (*editor)->close_edit completes the commit. Before 00512 * @c close_edit returns, but after the commit has succeeded, it will 00513 * invoke @a callback with the new revision number, the commit date (as a 00514 * <tt>const char *</tt>), commit author (as a <tt>const char *</tt>), and 00515 * @a callback_baton as arguments. If @a callback returns an error, that 00516 * error will be returned from @c close_edit, otherwise if there was a 00517 * post-commit hook failure, then that error will be returned and will 00518 * have code SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED. 00519 */ 00520 svn_error_t *svn_repos_get_commit_editor (const svn_delta_editor_t **editor, 00521 void **edit_baton, 00522 svn_repos_t *repos, 00523 const char *repos_url, 00524 const char *base_path, 00525 const char *user, 00526 const char *log_msg, 00527 svn_commit_callback_t callback, 00528 void *callback_baton, 00529 apr_pool_t *pool); 00530 00531 00532 /* ---------------------------------------------------------------*/ 00533 00534 /* Finding particular revisions. */ 00535 00536 /** Set @a *revision to the revision number in @a repos's filesystem that was 00537 * youngest at time @a tm. 00538 */ 00539 svn_error_t * 00540 svn_repos_dated_revision (svn_revnum_t *revision, 00541 svn_repos_t *repos, 00542 apr_time_t tm, 00543 apr_pool_t *pool); 00544 00545 00546 /** Given a @a root/@a path within some filesystem, return three pieces of 00547 * information allocated in @a pool: 00548 * 00549 * - set @a *committed_rev to the revision in which the object was 00550 * last modified. (In fs parlance, this is the revision in which 00551 * the particular node-rev-id was 'created'.) 00552 * 00553 * - set @a *committed_date to the date of said revision, or @c NULL 00554 * if not available. 00555 * 00556 * - set @a *last_author to the author of said revision, or @c NULL 00557 * if not available. 00558 */ 00559 svn_error_t * 00560 svn_repos_get_committed_info (svn_revnum_t *committed_rev, 00561 const char **committed_date, 00562 const char **last_author, 00563 svn_fs_root_t *root, 00564 const char *path, 00565 apr_pool_t *pool); 00566 00567 00568 /** Callback type for use with svn_repos_history(). @a path and @a 00569 * revision represent interesting history locations in the lifetime 00570 * of the path passed to svn_repos_history(). @a baton is the same 00571 * baton given to svn_repos_history(). @a pool is provided for the 00572 * convenience of the implementor, who should not expect it to live 00573 * longer than a single callback call. 00574 */ 00575 typedef svn_error_t *(*svn_repos_history_func_t) (void *baton, 00576 const char *path, 00577 svn_revnum_t revision, 00578 apr_pool_t *pool); 00579 00580 /** 00581 * @since New in 1.1. 00582 * 00583 * Call @a history_func (with @a history_baton) for each interesting 00584 * history location in the lifetime of @a path in @a fs, from the 00585 * youngest of @a end and @ start to the oldest. Only cross 00586 * filesystem copy history if @a cross_copies is @c TRUE. And do all 00587 * of this in @a pool. 00588 * 00589 * If @a authz_read_func is non-NULL, then use it (and @a 00590 * authz_read_baton) to verify that @a path in @a end is readable; if 00591 * not, return SVN_ERR_AUTHZ_UNREADABLE. Also verify the readability 00592 * of every ancestral path/revision pair before pushing them at @a 00593 * history_func. If a pair is deemed unreadable, then do not send 00594 * them; instead, immmediately stop traversing history and return 00595 * SVN_NO_ERROR. 00596 */ 00597 svn_error_t * 00598 svn_repos_history2 (svn_fs_t *fs, 00599 const char *path, 00600 svn_repos_history_func_t history_func, 00601 void *history_baton, 00602 svn_repos_authz_func_t authz_read_func, 00603 void *authz_read_baton, 00604 svn_revnum_t start, 00605 svn_revnum_t end, 00606 svn_boolean_t cross_copies, 00607 apr_pool_t *pool); 00608 00609 /** 00610 * @deprecated Provided for backward compatibility with the 1.0.0 API. 00611 * 00612 * Similar to svn_repos_history(), but with @a authz_read_func and 00613 * @a authz_read_baton always set to NULL. 00614 */ 00615 svn_error_t * 00616 svn_repos_history (svn_fs_t *fs, 00617 const char *path, 00618 svn_repos_history_func_t history_func, 00619 void *history_baton, 00620 svn_revnum_t start, 00621 svn_revnum_t end, 00622 svn_boolean_t cross_copies, 00623 apr_pool_t *pool); 00624 00625 00626 /** 00627 * @since New in 1.1. 00628 * 00629 * Set @a *locations to be a mapping of the revisions to the paths of 00630 * the file @a fs_path present at the repository in revision 00631 * @a peg_revision, where the revisions are taken out of the array 00632 * @a location_revisions. 00633 * 00634 * @a location_revisions is an array of svn_revnum_t's and @a *locations 00635 * maps svn_revnum_t's to const char *. 00636 * 00637 * If optional @a authz_read_func is non-NULL, then use it (and @a 00638 * authz_read_baton) to verify that the peg-object is readable. If not, 00639 * return SVN_ERR_AUTHZ_UNREADABLE. Also use the @a authz_read_func 00640 * to check that every path returned in the hash is readable. If an 00641 * unreadable path is encountered, stop tracing and return 00642 * SVN_NO_ERROR. 00643 * 00644 * @a pool is used for all allocations. 00645 */ 00646 svn_error_t * 00647 svn_repos_trace_node_locations (svn_fs_t *fs, 00648 apr_hash_t **locations, 00649 const char *fs_path, 00650 svn_revnum_t peg_revision, 00651 apr_array_header_t *location_revisions, 00652 svn_repos_authz_func_t authz_read_func, 00653 void *authz_read_baton, 00654 apr_pool_t *pool); 00655 00656 /* ### other queries we can do someday -- 00657 00658 * fetch the last revision created by <user> 00659 (once usernames become revision properties!) 00660 * fetch the last revision where <path> was modified 00661 00662 */ 00663 00664 00665 00666 /* ---------------------------------------------------------------*/ 00667 00668 /* Retrieving log messages. */ 00669 00670 00671 /** Invoke @a receiver with @a receiver_baton on each log message from 00672 * @a start to @a end in @a repos's filesystem. @a start may be greater 00673 * or less than @a end; this just controls whether the log messages are 00674 * processed in descending or ascending revision number order. 00675 * 00676 * If @a start or @a end is @c SVN_INVALID_REVNUM, it defaults to youngest. 00677 * 00678 * If @a paths is non-null and has one or more elements, then only show 00679 * revisions in which at least one of @a paths was changed (i.e., if 00680 * file, text or props changed; if dir, props changed or an entry was 00681 * added or deleted). Each path is an <tt>const char *</tt> representing 00682 * an absolute path in the repository. 00683 * 00684 * ### todo: need to consider whether the above directory behavior is 00685 * most useful, or if we should actually treat _any_ node change in a 00686 * directory as a visible change for purposes of log... i.e., show 00687 * bubble-up. The reason this might be useful is so that running log 00688 * on a directory would give a msg for every change under that dir, 00689 * no matter how far down. See the thread started on the dev list by 00690 * Lars Kellogg-Stedman <lars@larsshack.org> with the subject 00691 * "Single repository, multiple projects?" for more. We may simple 00692 * need to offer a few different semantics for @a paths. 00693 * 00694 * If @a discover_changed_paths, then each call to @a receiver passes a 00695 * <tt>const apr_hash_t *</tt> for the receiver's @a changed_paths 00696 * argument; the hash's keys are all the paths committed in that revision. 00697 * Otherwise, each call to @a receiver passes null for @a changed_paths. 00698 * 00699 * If @a strict_node_history is set, copy history (if any exists) will 00700 * not be traversed while harvesting revision logs for each path. 00701 * 00702 * If any invocation of @a receiver returns error, return that error 00703 * immediately and without wrapping it. 00704 * 00705 * If @a start or @a end is a non-existent revision, return the error 00706 * @c SVN_ERR_FS_NO_SUCH_REVISION, without ever invoking @a receiver. 00707 * 00708 * If optional @a authz_read_func is non-NULL, then use this function 00709 * (along with optional @a authz_read_baton) to check the readability 00710 * of each changed-path in each revision about to be "pushed" at 00711 * @a receiver. If a revision has all unreadable changed-paths, then 00712 * don't push the revision at all. If a revision has a mixture of 00713 * readable and unreadable changed-paths, then silently omit the 00714 * unreadable changed-paths when pushing the revision. 00715 * 00716 * See also the documentation for @c svn_log_message_receiver_t. 00717 * 00718 * Use @a pool for temporary allocations. 00719 */ 00720 svn_error_t * 00721 svn_repos_get_logs2 (svn_repos_t *repos, 00722 const apr_array_header_t *paths, 00723 svn_revnum_t start, 00724 svn_revnum_t end, 00725 svn_boolean_t discover_changed_paths, 00726 svn_boolean_t strict_node_history, 00727 svn_repos_authz_func_t authz_read_func, 00728 void *authz_read_baton, 00729 svn_log_message_receiver_t receiver, 00730 void *receiver_baton, 00731 apr_pool_t *pool); 00732 00733 /** 00734 * @deprecated Provided for backward compatibility with the 1.0.0 API. 00735 * 00736 * Same as to svn_repos_dump_fs2(), but with @a authz_read_func and 00737 * @a authz_read_baton always set to NULL. 00738 */ 00739 svn_error_t * 00740 svn_repos_get_logs (svn_repos_t *repos, 00741 const apr_array_header_t *paths, 00742 svn_revnum_t start, 00743 svn_revnum_t end, 00744 svn_boolean_t discover_changed_paths, 00745 svn_boolean_t strict_node_history, 00746 svn_log_message_receiver_t receiver, 00747 void *receiver_baton, 00748 apr_pool_t *pool); 00749 00750 00751 00752 /* ---------------------------------------------------------------*/ 00753 00754 /* Retreiving multiple revisions of a file. */ 00755 00756 /** @since New in 1.1. 00757 * Retrieve a subset of the interesting revisions of a file @a path in 00758 * @a repos as seen in revision @a end. Invoke @a handler with 00759 * @a handler_baton as its first argument for each such revision. 00760 * @a pool is used for all allocations. See @c svn_fs_history_prev for 00761 * a discussion of interesting revisions. 00762 * 00763 * If optional @a authz_read_func is non-NULL, then use this function 00764 * (along with optional @a authz_read_baton) to check the readability 00765 * of the rev-path in each interesting revision encountered. 00766 * 00767 * Revision discovery happens from @a end to @a start, and if an 00768 * unreadable revision is encountered before @a start is reached, then 00769 * revision discovery stops and only the revisions from @a end to the 00770 * oldest readable revision are returned (So it will appear that @a 00771 * path was added without history in the latter revision). 00772 * 00773 * If there is an interesting revision of the file that is less than or 00774 * equal to start, the iteration will start at that revision. Else, the 00775 * iteration will start at the first revision of the file in the repository, 00776 * which has to be less than or equal to end. Note that if the function 00777 * succeeds, @a handler will have been called at least once. 00778 * 00779 * In a series of calls, the file contents for the first interesting revision 00780 * will be provided as a text delta against the empty file. In the following 00781 * calls, the delta will be against the contents for the previous call. */ 00782 svn_error_t *svn_repos_get_file_revs (svn_repos_t *repos, 00783 const char *path, 00784 svn_revnum_t start, 00785 svn_revnum_t end, 00786 svn_repos_authz_func_t authz_read_func, 00787 void *authz_read_baton, 00788 svn_repos_file_rev_handler_t handler, 00789 void *handler_baton, 00790 apr_pool_t *pool); 00791 00792 00793 /* ---------------------------------------------------------------*/ 00794 00795 /** 00796 * @defgroup svn_repos_hook_wrappers Hook-sensitive wrappers for libsvn_fs 00797 * routines. 00798 * @{ 00799 */ 00800 00801 /** Like @c svn_fs_commit_txn(), but invoke the @a repos's pre- and 00802 * post-commit hooks around the commit. Use @a pool for any necessary 00803 * allocations. 00804 * 00805 * If the pre-commit hook or svn_fs_commit_txn() fails, throw the 00806 * original error to caller. If an error occurs when running the 00807 * post-commit hook, return the original error wrapped with 00808 * SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED. If the caller sees this 00809 * error, it knows that the commit succeeded anyway. 00810 * 00811 * @a conflict_p, @a new_rev, and @a txn are as in @c svn_fs_commit_txn(). 00812 */ 00813 svn_error_t *svn_repos_fs_commit_txn (const char **conflict_p, 00814 svn_repos_t *repos, 00815 svn_revnum_t *new_rev, 00816 svn_fs_txn_t *txn, 00817 apr_pool_t *pool); 00818 00819 /** Like @c svn_fs_begin_txn(), but use @a author and @a log_msg to set the 00820 * corresponding properties on transaction @a *txn_p. @a repos is the 00821 * repository object which contains the filesystem. @a rev, @a *txn_p, and 00822 * @a pool are as in @c svn_fs_begin_txn(). 00823 * 00824 * Before a txn is created, the repository's start-commit hooks are 00825 * run; if any of them fail, no txn is created, @a *txn_p is unaffected, 00826 * and @c SVN_ERR_REPOS_HOOK_FAILURE is returned. 00827 * 00828 * @a log_msg may be @c NULL to indicate the message is not (yet) available. 00829 * The caller will need to attach it to the transaction at a later time. 00830 */ 00831 svn_error_t *svn_repos_fs_begin_txn_for_commit (svn_fs_txn_t **txn_p, 00832 svn_repos_t *repos, 00833 svn_revnum_t rev, 00834 const char *author, 00835 const char *log_msg, 00836 apr_pool_t *pool); 00837 00838 00839 /** Like @c svn_fs_begin_txn(), but use @a author to set the corresponding 00840 * property on transaction @a *txn_p. @a repos is the repository object 00841 * which contains the filesystem. @a rev, @a *txn_p, and @a pool are as in 00842 * @c svn_fs_begin_txn(). 00843 * 00844 * ### Someday: before a txn is created, some kind of read-hook could 00845 * be called here. 00846 */ 00847 svn_error_t *svn_repos_fs_begin_txn_for_update (svn_fs_txn_t **txn_p, 00848 svn_repos_t *repos, 00849 svn_revnum_t rev, 00850 const char *author, 00851 apr_pool_t *pool); 00852 00853 00854 /** 00855 * @since New in 1.1. 00856 * 00857 * Like @c svn_fs_change_rev_prop(), but invoke the @a repos's pre- and 00858 * post-revprop-change hooks around the change. Use @a pool for 00859 * temporary allocations. 00860 * 00861 * @a rev is the revision whose property to change, @a name is the 00862 * name of the property, and @a new_value is the new value of the 00863 * property. @a author is the authenticated username of the person 00864 * changing the property value, or null if not available. 00865 * 00866 * If @a authz_read_func is non-NULL, then use it (with @a 00867 * authz_read_baton) to validate the changed-paths associated with @a 00868 * rev. If the revision contains any unreadable changed paths, then 00869 * return SVN_ERR_AUTHZ_UNREADABLE. 00870 */ 00871 svn_error_t *svn_repos_fs_change_rev_prop2 (svn_repos_t *repos, 00872 svn_revnum_t rev, 00873 const char *author, 00874 const char *name, 00875 const svn_string_t *new_value, 00876 svn_repos_authz_func_t 00877 authz_read_func, 00878 void *authz_read_baton, 00879 apr_pool_t *pool); 00880 00881 /** 00882 * @deprecated Provided for backward compatibility with the 1.0.0 API. 00883 * 00884 * Similar to svn_repos_fs_change_rev_prop2(), but with the 00885 * @a authz_read_func parameter always NULL. 00886 */ 00887 svn_error_t *svn_repos_fs_change_rev_prop (svn_repos_t *repos, 00888 svn_revnum_t rev, 00889 const char *author, 00890 const char *name, 00891 const svn_string_t *new_value, 00892 apr_pool_t *pool); 00893 00894 00895 00896 /** 00897 * @since New in 1.1. 00898 * 00899 * Set @a *value_p to the value of the property named @a propname on 00900 * revision @a rev in the filesystem opened in @a repos. If @a rev 00901 * has no property by that name, set @a *value_p to zero. Allocate 00902 * the result in @a pool. 00903 * 00904 * If @a authz_read_func is non-NULL, then use it (with @a 00905 * authz_read_baton) to validate the changed-paths associated with @a 00906 * rev. If the changed-paths are all unreadable, then set @a *value_p 00907 * to zero unconditionally. If only some of the changed-paths are 00908 * unreadable, then allow 'svn:author' and 'svn:date' propvalues to be 00909 * fetched, but return 0 for any other property. 00910 */ 00911 svn_error_t *svn_repos_fs_revision_prop (svn_string_t **value_p, 00912 svn_repos_t *repos, 00913 svn_revnum_t rev, 00914 const char *propname, 00915 svn_repos_authz_func_t 00916 authz_read_func, 00917 void *authz_read_baton, 00918 apr_pool_t *pool); 00919 00920 00921 /** 00922 * @since New in 1.1. 00923 * 00924 * Set @a *table_p to the entire property list of revision @a rev in 00925 * filesystem opened in @a repos, as a hash table allocated in @a 00926 * pool. The table maps <tt>char *</tt> property names to @c 00927 * svn_string_t * values; the names and values are allocated in @a 00928 * pool. 00929 * 00930 * If @a authz_read_func is non-NULL, then use it (with @a 00931 * authz_read_baton) to validate the changed-paths associated with @a 00932 * rev. If the changed-paths are all unreadable, then return an empty 00933 * hash. If only some of the changed-paths are unreadable, then return 00934 * an empty hash, except for 'svn:author' and 'svn:date' properties 00935 * (assuming those properties exist). 00936 */ 00937 svn_error_t *svn_repos_fs_revision_proplist (apr_hash_t **table_p, 00938 svn_repos_t *repos, 00939 svn_revnum_t rev, 00940 svn_repos_authz_func_t 00941 authz_read_func, 00942 void *authz_read_baton, 00943 apr_pool_t *pool); 00944 00945 00946 00947 /* ---------------------------------------------------------------*/ 00948 00949 /* Prop-changing wrappers for libsvn_fs routines. */ 00950 00951 /* NOTE: svn_repos_fs_change_rev_prop() also exists, but is located 00952 above with the hook-related functions. */ 00953 00954 00955 /** Validating wrapper for @c svn_fs_change_node_prop() (which see for 00956 * argument descriptions). 00957 */ 00958 svn_error_t *svn_repos_fs_change_node_prop (svn_fs_root_t *root, 00959 const char *path, 00960 const char *name, 00961 const svn_string_t *value, 00962 apr_pool_t *pool); 00963 00964 /** Validating wrapper for @c svn_fs_change_txn_prop() (which see for 00965 * argument descriptions). 00966 */ 00967 svn_error_t *svn_repos_fs_change_txn_prop (svn_fs_txn_t *txn, 00968 const char *name, 00969 const svn_string_t *value, 00970 apr_pool_t *pool); 00971 00972 /** @} */ 00973 00974 /* ---------------------------------------------------------------*/ 00975 00976 /** 00977 * @defgroup svn_repos_inspection Data structures and editor things for 00978 * repository inspection. 00979 * @{ 00980 * 00981 * As it turns out, the @c svn_repos_dir_delta() interface can be 00982 * extremely useful for examining the repository, or more exactly, 00983 * changes to the repository. @c svn_repos_dir_delta() allows for 00984 * differences between two trees to be described using an editor. 00985 * 00986 * By using the specific editor found below in conjunction with 00987 * @c svn_repos_dir_delta(), the description of how to transform one tree 00988 * into another can be used to build an in-memory linked-list tree, 00989 * which each node representing a repository node that was changed as a 00990 * result of having @c svn_repos_dir_delta() drive that editor. 00991 */ 00992 00993 /** A node in the repository. */ 00994 typedef struct svn_repos_node_t 00995 { 00996 /** Node type (file, dir, etc.) */ 00997 svn_node_kind_t kind; 00998 00999 /** How this node entered the node tree: 'A'dd, 'D'elete, 'R'eplace */ 01000 char action; 01001 01002 /** Were there any textual mods? (files only) */ 01003 svn_boolean_t text_mod; 01004 01005 /** Where there any property mods? */ 01006 svn_boolean_t prop_mod; 01007 01008 /** The name of this node as it appears in its parent's entries list */ 01009 const char *name; 01010 01011 /** The filesystem revision where this was copied from (if any) */ 01012 svn_revnum_t copyfrom_rev; 01013 01014 /** The filesystem path where this was copied from (if any) */ 01015 const char *copyfrom_path; 01016 01017 /** Pointer to the next sibling of this node */ 01018 struct svn_repos_node_t *sibling; 01019 01020 /** Pointer to the first child of this node */ 01021 struct svn_repos_node_t *child; 01022 01023 /** Pointer to the parent of this node */ 01024 struct svn_repos_node_t *parent; 01025 01026 } svn_repos_node_t; 01027 01028 01029 /** Set @a *editor and @a *edit_baton to an editor that, when driven by 01030 * @c svn_repos_dir_delta(), builds an <tt>svn_repos_node_t *</tt> tree 01031 * representing the delta from @a base_root to @a root in @a repos's 01032 * filesystem. 01033 * 01034 * Invoke @c svn_repos_node_from_baton() on @a edit_baton to obtain the root 01035 * node afterwards. 01036 * 01037 * Note that the delta includes "bubbled-up" directories; that is, 01038 * many of the directory nodes will have no prop_mods. 01039 * 01040 * Allocate the tree and its contents in @a node_pool; do all other 01041 * allocation in @a pool. 01042 */ 01043 svn_error_t *svn_repos_node_editor (const svn_delta_editor_t **editor, 01044 void **edit_baton, 01045 svn_repos_t *repos, 01046 svn_fs_root_t *base_root, 01047 svn_fs_root_t *root, 01048 apr_pool_t *node_pool, 01049 apr_pool_t *pool); 01050 01051 /** Return the root node of the linked-list tree generated by driving 01052 * the editor created by @c svn_repos_node_editor() with 01053 * @c svn_repos_dir_delta(), which is stored in @a edit_baton. This is 01054 * only really useful if used *after* the editor drive is completed. 01055 */ 01056 svn_repos_node_t *svn_repos_node_from_baton (void *edit_baton); 01057 01058 /** @} */ 01059 01060 /* ---------------------------------------------------------------*/ 01061 01062 /** 01063 * @defgroup svn_repos_dump_load Dumping and loading filesystem data 01064 * @{ 01065 * 01066 * The filesystem 'dump' format contains nothing but the abstract 01067 * structure of the filesystem -- independent of any internal node-id 01068 * schema or database back-end. All of the data in the dumpfile is 01069 * acquired by public function calls into svn_fs.h. Similarly, the 01070 * parser which reads the dumpfile is able to reconstruct the 01071 * filesystem using only public svn_fs.h routines. 01072 * 01073 * Thus the dump/load feature's main purpose is for *migrating* data 01074 * from one svn filesystem to another -- presumably two filesystems 01075 * which have different internal implementations. 01076 * 01077 * If you simply want to backup your filesystem, you're probably 01078 * better off using the built-in facilities of the DB backend (using 01079 * Berkeley DB's hot-backup feature, for example.) 01080 * 01081 * For a description of the dumpfile format, see 01082 * /trunk/notes/fs_dumprestore.txt. 01083 */ 01084 01085 /* The RFC822-style headers in our dumpfile format. */ 01086 #define SVN_REPOS_DUMPFILE_MAGIC_HEADER "SVN-fs-dump-format-version" 01087 #define SVN_REPOS_DUMPFILE_FORMAT_VERSION 3 01088 #define SVN_REPOS_DUMPFILE_UUID "UUID" 01089 #define SVN_REPOS_DUMPFILE_CONTENT_LENGTH "Content-length" 01090 01091 #define SVN_REPOS_DUMPFILE_REVISION_NUMBER "Revision-number" 01092 01093 #define SVN_REPOS_DUMPFILE_NODE_PATH "Node-path" 01094 #define SVN_REPOS_DUMPFILE_NODE_KIND "Node-kind" 01095 #define SVN_REPOS_DUMPFILE_NODE_ACTION "Node-action" 01096 #define SVN_REPOS_DUMPFILE_NODE_COPYFROM_PATH "Node-copyfrom-path" 01097 #define SVN_REPOS_DUMPFILE_NODE_COPYFROM_REV "Node-copyfrom-rev" 01098 #define SVN_REPOS_DUMPFILE_TEXT_COPY_SOURCE_CHECKSUM "Text-copy-source-md5" 01099 #define SVN_REPOS_DUMPFILE_TEXT_CONTENT_CHECKSUM "Text-content-md5" 01100 01101 #define SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH "Prop-content-length" 01102 #define SVN_REPOS_DUMPFILE_TEXT_CONTENT_LENGTH "Text-content-length" 01103 01104 /* @since New in 1.1. */ 01105 #define SVN_REPOS_DUMPFILE_PROP_DELTA "Prop-delta" 01106 /* @since New in 1.1. */ 01107 #define SVN_REPOS_DUMPFILE_TEXT_DELTA "Text-delta" 01108 01109 /** The different "actions" attached to nodes in the dumpfile. */ 01110 enum svn_node_action 01111 { 01112 svn_node_action_change, 01113 svn_node_action_add, 01114 svn_node_action_delete, 01115 svn_node_action_replace 01116 }; 01117 01118 /** The different policies for processing the UUID in the dumpfile. */ 01119 enum svn_repos_load_uuid 01120 { 01121 svn_repos_load_uuid_default, 01122 svn_repos_load_uuid_ignore, 01123 svn_repos_load_uuid_force 01124 }; 01125 01126 /** 01127 * @since New in 1.1. 01128 * 01129 * Dump the contents of the filesystem within already-open @a repos into 01130 * writable @a dumpstream. Begin at revision @a start_rev, and dump every 01131 * revision up through @a end_rev. Use @a pool for all allocation. If 01132 * non-@c NULL, send feedback to @a feedback_stream. @a dumpstream can be 01133 * @c NULL for the purpose of verifying the repository. 01134 * 01135 * If @a start_rev is @c SVN_INVALID_REVNUM, then start dumping at revision 01136 * 0. If @a end_rev is @c SVN_INVALID_REVNUM, then dump through the @c HEAD 01137 * revision. 01138 * 01139 * If @a incremental is @c TRUE, the first revision dumped will be a diff 01140 * against the previous revision (usually it looks like a full dump of 01141 * the tree). 01142 * 01143 * If @a use_deltas is @c TRUE, output only node properties which have 01144 * changed relative to the previous contents, and output text contents 01145 * as svndiff data against the previous contents. Regardless of how 01146 * this flag is set, the first revision of a non-incremental dump will 01147 * be done with full plain text. A dump with @a use_deltas set cannot 01148 * be loaded by Subversion 1.0.x. 01149 * 01150 * If @a cancel_func is not @c NULL, it is called periodically with 01151 * @a cancel_baton as argument to see if the client wishes to cancel 01152 * the dump. 01153 */ 01154 svn_error_t *svn_repos_dump_fs2 (svn_repos_t *repos, 01155 svn_stream_t *dumpstream, 01156 svn_stream_t *feedback_stream, 01157 svn_revnum_t start_rev, 01158 svn_revnum_t end_rev, 01159 svn_boolean_t incremental, 01160 svn_boolean_t use_deltas, 01161 svn_cancel_func_t cancel_func, 01162 void *cancel_baton, 01163 apr_pool_t *pool); 01164 01165 01166 /** 01167 * @deprecated Provided for backward compatibility with the 1.0.0 API. 01168 * 01169 * Similar to svn_repos_dump_fs2(), but with the @a use_deltas 01170 * parameter always set to @c FALSE. 01171 */ 01172 svn_error_t *svn_repos_dump_fs (svn_repos_t *repos, 01173 svn_stream_t *dumpstream, 01174 svn_stream_t *feedback_stream, 01175 svn_revnum_t start_rev, 01176 svn_revnum_t end_rev, 01177 svn_boolean_t incremental, 01178 svn_cancel_func_t cancel_func, 01179 void *cancel_baton, 01180 apr_pool_t *pool); 01181 01182 01183 /** Read and parse dumpfile-formatted @a dumpstream, reconstructing 01184 * filesystem revisions in already-open @a repos, handling uuids 01185 * in accordance with @a uuid_action. 01186 * 01187 * Read and parse dumpfile-formatted @a dumpstream, reconstructing 01188 * filesystem revisions in already-open @a repos. Use @a pool for all 01189 * allocation. If non-@c NULL, send feedback to @a feedback_stream. 01190 * 01191 * If the dumpstream contains copy history that is unavailable in the 01192 * repository, an error will be thrown. 01193 * 01194 * The repository's UUID will be updated iff 01195 * the dumpstream contains a UUID and 01196 * @a uuid_action is not equal to @c svn_repos_load_uuid_ignore and 01197 * either the repository contains no revisions or 01198 * @a uuid_action is equal to @c svn_repos_load_uuid_force. 01199 * 01200 * If the dumpstream contains no UUID, then @a uuid_action is 01201 * ignored and the repository UUID is not touched. 01202 * 01203 * If @a parent_dir is not null, then the parser will reparent all the 01204 * loaded nodes, from root to @a parent_dir. The directory @a parent_dir 01205 * must be an existing directory in the repository. 01206 * 01207 * If @a cancel_func is not @c NULL, it is called periodically with 01208 * @a cancel_baton as argument to see if the client wishes to cancel 01209 * the load. 01210 */ 01211 svn_error_t *svn_repos_load_fs (svn_repos_t *repos, 01212 svn_stream_t *dumpstream, 01213 svn_stream_t *feedback_stream, 01214 enum svn_repos_load_uuid uuid_action, 01215 const char *parent_dir, 01216 svn_cancel_func_t cancel_func, 01217 void *cancel_baton, 01218 apr_pool_t *pool); 01219 01220 01221 /** 01222 * @since New in 1.1. 01223 * 01224 * A vtable that is driven by @c svn_repos_parse_dumpstream2. */ 01225 typedef struct svn_repos_parse_fns2_t 01226 { 01227 /** The parser has discovered a new revision record within the 01228 * parsing session represented by @a parse_baton. All the headers are 01229 * placed in @a headers (allocated in @a pool), which maps <tt>const 01230 * char *</tt> header-name ==> <tt>const char *</tt> header-value. 01231 * The @a revision_baton received back (also allocated in @a pool) 01232 * represents the revision. 01233 */ 01234 svn_error_t *(*new_revision_record) (void **revision_baton, 01235 apr_hash_t *headers, 01236 void *parse_baton, 01237 apr_pool_t *pool); 01238 01239 /** The parser has discovered a new uuid record within the parsing 01240 * session represented by @a parse_baton. The uuid's value is 01241 * @a uuid, and it is allocated in @a pool. 01242 */ 01243 svn_error_t *(*uuid_record) (const char *uuid, 01244 void *parse_baton, 01245 apr_pool_t *pool); 01246 01247 /** The parser has discovered a new node record within the current 01248 * revision represented by @a revision_baton. All the headers are 01249 * placed in @a headers as above, allocated in @a pool. The 01250 * @a node_baton received back is allocated in @a pool and represents 01251 * the node. 01252 */ 01253 svn_error_t *(*new_node_record) (void **node_baton, 01254 apr_hash_t *headers, 01255 void *revision_baton, 01256 apr_pool_t *pool); 01257 01258 /** For a given @a revision_baton, set a property @a name to @a value. */ 01259 svn_error_t *(*set_revision_property) (void *revision_baton, 01260 const char *name, 01261 const svn_string_t *value); 01262 01263 /** For a given @a node_baton, set a property @a name to @a value. */ 01264 svn_error_t *(*set_node_property) (void *node_baton, 01265 const char *name, 01266 const svn_string_t *value); 01267 01268 /** For a given @a node_baton, delete property @a name. */ 01269 svn_error_t *(*delete_node_property) (void *node_baton, const char *name); 01270 01271 /** For a given @a node_baton, remove all properties. */ 01272 svn_error_t *(*remove_node_props) (void *node_baton); 01273 01274 /** For a given @a node_baton, receive a writable @a stream capable of 01275 * receiving the node's fulltext. After writing the fulltext, call 01276 * the stream's @c close() function. 01277 * 01278 * If a @c NULL is returned instead of a stream, the vtable is 01279 * indicating that no text is desired, and the parser will not 01280 * attempt to send it. 01281 */ 01282 svn_error_t *(*set_fulltext) (svn_stream_t **stream, 01283 void *node_baton); 01284 01285 /** For a given @a node_baton, set @a handler and @a handler_baton 01286 * to a window handler and baton capable of receiving a delta 01287 * against the node's previous contents. A NULL window will be 01288 * sent to the handler after all the windows are sent. 01289 * 01290 * If a @c NULL is returned instead of a handler, the vtable is 01291 * indicating that no delta is desired, and the parser will not 01292 * attempt to send it. 01293 */ 01294 svn_error_t *(*apply_textdelta) (svn_txdelta_window_handler_t *handler, 01295 void **handler_baton, 01296 void *node_baton); 01297 01298 /** The parser has reached the end of the current node represented by 01299 * @a node_baton, it can be freed. 01300 */ 01301 svn_error_t *(*close_node) (void *node_baton); 01302 01303 /** The parser has reached the end of the current revision 01304 * represented by @a revision_baton. In other words, there are no more 01305 * changed nodes within the revision. The baton can be freed. 01306 */ 01307 svn_error_t *(*close_revision) (void *revision_baton); 01308 01309 } svn_repos_parser_fns2_t; 01310 01311 01312 01313 /** 01314 * @since New in 1.1. 01315 * 01316 * Read and parse dumpfile-formatted @a stream, calling callbacks in 01317 * @a parse_fns/@a parse_baton, and using @a pool for allocations. 01318 * 01319 * If @a cancel_func is not @c NULL, it is called periodically with 01320 * @a cancel_baton as argument to see if the client wishes to cancel 01321 * the dump. 01322 * 01323 * This parser has built-in knowledge of the dumpfile format, but only 01324 * in a general sense: 01325 * 01326 * * it recognizes revision and node records by looking for either 01327 * a REVISION_NUMBER or NODE_PATH headers. 01328 * 01329 * * it recognizes the CONTENT-LENGTH headers, so it knows if and 01330 * how to suck up the content body. 01331 * 01332 * * it knows how to parse a content body into two parts: props 01333 * and text, and pass the pieces to the vtable. 01334 * 01335 * This is enough knowledge to make it easy on vtable implementors, 01336 * but still allow expansion of the format: most headers are ignored. 01337 */ 01338 svn_error_t * 01339 svn_repos_parse_dumpstream2 (svn_stream_t *stream, 01340 const svn_repos_parser_fns2_t *parse_fns, 01341 void *parse_baton, 01342 svn_cancel_func_t cancel_func, 01343 void *cancel_baton, 01344 apr_pool_t *pool); 01345 01346 01347 /** 01348 * @since New in 1.1. 01349 * 01350 * Set @a *parser and @a *parse_baton to a vtable parser which commits new 01351 * revisions to the fs in @a repos. The constructed parser will treat 01352 * UUID records in a manner consistent with @a uuid_action. Use @a pool 01353 * to operate on the fs. 01354 * 01355 * If @a use_history is set, then the parser will require relative 01356 * 'copyfrom' history to exist in the repository when it encounters 01357 * nodes that are added-with-history. 01358 * 01359 * If @a parent_dir is not null, then the parser will reparent all the 01360 * loaded nodes, from root to @a parent_dir. The directory @a parent_dir 01361 * must be an existing directory in the repository. 01362 * 01363 * Print all parsing feedback to @a outstream (if non-@c NULL). 01364 * 01365 */ 01366 svn_error_t * 01367 svn_repos_get_fs_build_parser2 (const svn_repos_parser_fns2_t **parser, 01368 void **parse_baton, 01369 svn_repos_t *repos, 01370 svn_boolean_t use_history, 01371 enum svn_repos_load_uuid uuid_action, 01372 svn_stream_t *outstream, 01373 const char *parent_dir, 01374 apr_pool_t *pool); 01375 01376 01377 /** 01378 * @deprecated Provided for backward compatibility with the 1.0.0 API. 01379 * 01380 * A vtable that is driven by @c svn_repos_parse_dumpstream. Lacks 01381 * the delete_node_property and apply_textdelta callbacks. 01382 */ 01383 typedef struct svn_repos_parse_fns_t 01384 { 01385 svn_error_t *(*new_revision_record) (void **revision_baton, 01386 apr_hash_t *headers, 01387 void *parse_baton, 01388 apr_pool_t *pool); 01389 svn_error_t *(*uuid_record) (const char *uuid, 01390 void *parse_baton, 01391 apr_pool_t *pool); 01392 svn_error_t *(*new_node_record) (void **node_baton, 01393 apr_hash_t *headers, 01394 void *revision_baton, 01395 apr_pool_t *pool); 01396 svn_error_t *(*set_revision_property) (void *revision_baton, 01397 const char *name, 01398 const svn_string_t *value); 01399 svn_error_t *(*set_node_property) (void *node_baton, 01400 const char *name, 01401 const svn_string_t *value); 01402 svn_error_t *(*remove_node_props) (void *node_baton); 01403 svn_error_t *(*set_fulltext) (svn_stream_t **stream, 01404 void *node_baton); 01405 svn_error_t *(*close_node) (void *node_baton); 01406 svn_error_t *(*close_revision) (void *revision_baton); 01407 } svn_repos_parser_fns_t; 01408 01409 01410 /** 01411 * @deprecated Provided for backward compatibility with the 1.0.0 API. 01412 * 01413 * Similar to svn_repos_parse_dumpstream2, but uses the more limited 01414 * svn_repos_parser_fns_t vtable type. 01415 */ 01416 svn_error_t * 01417 svn_repos_parse_dumpstream (svn_stream_t *stream, 01418 const svn_repos_parser_fns_t *parse_fns, 01419 void *parse_baton, 01420 svn_cancel_func_t cancel_func, 01421 void *cancel_baton, 01422 apr_pool_t *pool); 01423 01424 01425 /** 01426 * @deprecated Provided for backward compatibility with the 1.0.0 API. 01427 * 01428 * Similar to svn_repos_get_fs_build_parser2, but yields the more 01429 * limited svn_repos_parser_fns_t vtable type. 01430 */ 01431 svn_error_t * 01432 svn_repos_get_fs_build_parser (const svn_repos_parser_fns_t **parser, 01433 void **parse_baton, 01434 svn_repos_t *repos, 01435 svn_boolean_t use_history, 01436 enum svn_repos_load_uuid uuid_action, 01437 svn_stream_t *outstream, 01438 const char *parent_dir, 01439 apr_pool_t *pool); 01440 01441 01442 /** @} */ 01443 01444 #ifdef __cplusplus 01445 } 01446 #endif /* __cplusplus */ 01447 01448 #endif /* SVN_REPOS_H */
1.2.18