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