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_fs.h 00019 * @brief Interface to the Subversion filesystem. 00020 */ 00021 00022 00023 #ifndef SVN_FS_H 00024 #define SVN_FS_H 00025 00026 #include <apr_pools.h> 00027 #include <apr_hash.h> 00028 #include <apr_tables.h> 00029 #include "svn_types.h" 00030 #include "svn_error.h" 00031 #include "svn_delta.h" 00032 #include "svn_io.h" 00033 00034 00035 #ifdef __cplusplus 00036 extern "C" { 00037 #endif /* __cplusplus */ 00038 00039 00040 /** 00041 * @since New in 1.1. 00042 * 00043 * Get libsvn_fs version information. 00044 */ 00045 const svn_version_t *svn_fs_version (void); 00046 00047 00048 /* Opening and creating filesystems. */ 00049 00050 00051 /** An object representing a Subversion filesystem. */ 00052 typedef struct svn_fs_t svn_fs_t; 00053 00054 00055 /** @{ 00056 * Filesystem configuration options 00057 */ 00058 #define SVN_FS_CONFIG_BDB_TXN_NOSYNC "bdb-txn-nosync" 00059 #define SVN_FS_CONFIG_BDB_LOG_AUTOREMOVE "bdb-log-autoremove" 00060 00061 /** @since New in 1.1. */ 00062 #define SVN_FS_CONFIG_FS_TYPE "fs-type" 00063 /** @since New in 1.1. */ 00064 #define SVN_FS_TYPE_BDB "bdb" 00065 /** @since New in 1.1. */ 00066 #define SVN_FS_TYPE_FSFS "fsfs" 00067 /** @} */ 00068 00069 00070 /** @since New in 1.2. 00071 * 00072 * Callers should invoke this function to initialize global state in 00073 * the FS library before creating FS objects. If this function is 00074 * invoked, no FS objects may be created in another thread at the same 00075 * time as this invocation, and the provided @a pool must last longer 00076 * than any FS object created subsequently. 00077 * 00078 * If this function is not called, the FS library will make a best 00079 * effort to bootstrap a mutex for protecting data common to FS 00080 * objects; however, there is a small window of failure. Also, a 00081 * small amount of data will be leaked if the Subversion FS library is 00082 * dynamically unloaded. 00083 * 00084 * If this function is called multiple times before the pool passed to 00085 * the first call is destroyed or cleared, the later calls will have 00086 * no effect. 00087 */ 00088 svn_error_t *svn_fs_initialize (apr_pool_t *pool); 00089 00090 00091 /** The type of a warning callback function. @a baton is the value specified 00092 * in the call to @c svn_fs_set_warning_func; the filesystem passes it through 00093 * to the callback. @a err contains the warning message. 00094 * 00095 * The callback function should not clear the error that is passed to it; 00096 * its caller should do that. 00097 */ 00098 typedef void (*svn_fs_warning_callback_t) (void *baton, svn_error_t *err); 00099 00100 00101 /** Provide a callback function, @a warning, that @a fs should use to 00102 * report (non-fatal) errors. To print an error, the filesystem will call 00103 * @a warning, passing it @a warning_baton and the error. 00104 * 00105 * By default, this is set to a function that will crash the process. 00106 * Dumping to @c stderr or <tt>/dev/tty</tt> is not acceptable default 00107 * behavior for server processes, since those may both be equivalent to 00108 * <tt>/dev/null</tt>. 00109 */ 00110 void svn_fs_set_warning_func (svn_fs_t *fs, 00111 svn_fs_warning_callback_t warning, 00112 void *warning_baton); 00113 00114 00115 00116 /** 00117 * @since New in 1.1. 00118 * 00119 * Create a new, empty Subversion filesystem, stored in the directory 00120 * @a path, and return a pointer to it in @a *fs_p. @a path must not 00121 * currently exist, but its parent must exist. If @a fs_config is not 00122 * @c NULL, the options it contains modify the behavior of the 00123 * filesystem. The interpretation of @a fs_config is specific to the 00124 * filesystem back-end. The new filesystem may be closed by 00125 * destroying @a pool. 00126 * 00127 * @note The lifetime of @a fs_config must not be shorter than @a 00128 * pool's. It's a good idea to allocate @a fs_config from @a pool or 00129 * one of its ancestors. 00130 * 00131 * If @a fs_config contains a value for @c SVN_FS_CONFIG_FS_TYPE, that 00132 * value determines the filesystem type for the new filesystem. 00133 * Currently defined values are: 00134 * 00135 * SVN_FS_TYPE_BDB Berkeley-DB implementation 00136 * SVN_FS_TYPE_FSFS Native-filesystem implementation 00137 * 00138 * Otherwise, the BDB filesystem type is assumed. Once the filesystem 00139 * is created, its type will be recorded so that other functions will 00140 * know how to operate on it. 00141 */ 00142 svn_error_t *svn_fs_create (svn_fs_t **fs_p, const char *path, 00143 apr_hash_t *fs_config, apr_pool_t *pool); 00144 00145 /** 00146 * @since New in 1.1. 00147 * 00148 * Open a Subversion filesystem located in the directory @a path, and 00149 * return a pointer to it in @a *fs_p. If @a fs_config is not @c 00150 * NULL, the options it contains modify the behavior of the 00151 * filesystem. The interpretation of @a fs_config is specific to the 00152 * filesystem back-end. The opened filesystem may be closed by 00153 * destroying @a pool. 00154 * 00155 * @note The lifetime of @a fs_config must not be shorter than @a 00156 * pool's. It's a good idea to allocate @a fs_config from @a pool or 00157 * one of its ancestors. 00158 * 00159 * Only one thread may operate on any given filesystem object at once. 00160 * Two threads may access the same filesystem simultaneously only if 00161 * they open separate filesystem objects. 00162 * 00163 * NOTE: you probably don't want to use this directly. Take a look at 00164 * @c svn_repos_open() instead. 00165 */ 00166 svn_error_t *svn_fs_open (svn_fs_t **fs_p, const char *path, 00167 apr_hash_t *config, apr_pool_t *pool); 00168 00169 /** 00170 * @since New in 1.1. 00171 * 00172 * Return the path to @a fs's repository, allocated in @a pool. 00173 * Note: this is just what was passed to @c svn_fs_create() or 00174 * @a svn_fs_open() -- might be absolute, might not. 00175 */ 00176 const char *svn_fs_path (svn_fs_t *fs, apr_pool_t *pool); 00177 00178 /** 00179 * @since New in 1.1. 00180 * 00181 * Delete the filesystem at @a path. */ 00182 svn_error_t *svn_fs_delete_fs (const char *path, apr_pool_t *pool); 00183 00184 /** 00185 * @since New in 1.1. 00186 * 00187 * Copy a possibly live Subversion filesystem from @a src_path to 00188 * @a dest_path. If @a clean is @c TRUE, perform cleanup on the 00189 * source filesystem as part of the copy operation; currently, this 00190 * means deleting copied, unused logfiles for a Berkeley DB source 00191 * filesystem. 00192 */ 00193 svn_error_t *svn_fs_hotcopy (const char *src_path, const char *dest_path, 00194 svn_boolean_t clean, apr_pool_t *pool); 00195 00196 /** Subversion filesystems based on Berkeley DB. 00197 * 00198 * The following functions are specific to Berkeley DB filesystems. 00199 * 00200 * @defgroup svn_fs_bdb berkeley db filesystems 00201 * @{ 00202 */ 00203 00204 /** Register an error handling function for Berkeley DB error messages. 00205 * If a Berkeley DB error occurs, the filesystem will call @a handler 00206 * with two strings: an error message prefix, which will be zero, and 00207 * an error message. @a handler should print it out, log it somewhere, 00208 * etc. 00209 * 00210 * Since Berkeley DB's error messages are sometimes much more 00211 * informative than the error codes the functions return, it's worth 00212 * calling this function and providing some kind of error message 00213 * handler. 00214 * 00215 * This function calls @c DBENV->set_errcall, with @a handler as the 00216 * @c db_errcall_fcn argument. 00217 */ 00218 svn_error_t *svn_fs_set_berkeley_errcall (svn_fs_t *fs, 00219 void (*handler) (const char *errpfx, 00220 char *msg)); 00221 00222 /** Perform any necessary non-catastrophic recovery on a Berkeley 00223 * DB-based Subversion filesystem, stored in the environment @a path. 00224 * Do any necessary allocation within @a pool. 00225 * 00226 * After an unexpected server exit, due to a server crash or a system 00227 * crash, a Subversion filesystem based on Berkeley DB needs to run 00228 * recovery procedures to bring the database back into a consistent 00229 * state and release any locks that were held by the deceased process. 00230 * The recovery procedures require exclusive access to the database 00231 * --- while they execute, no other process or thread may access the 00232 * database. 00233 * 00234 * In a server with multiple worker processes, like Apache, if a 00235 * worker process accessing the filesystem dies, you must stop the 00236 * other worker processes, and run recovery. Then, the other worker 00237 * processes can re-open the database and resume work. 00238 * 00239 * If the server exited cleanly, there is no need to run recovery, but 00240 * there is no harm in it, either, and it take very little time. So 00241 * it's a fine idea to run recovery when the server process starts, 00242 * before it begins handling any requests. 00243 */ 00244 svn_error_t *svn_fs_berkeley_recover (const char *path, 00245 apr_pool_t *pool); 00246 00247 00248 /** Set @a *logfiles to an array of <tt>const char *</tt> log file names 00249 * of Berkeley DB-based Subversion filesystem. 00250 * 00251 * If @a only_unused is @c TRUE, set @a *logfiles to an array which 00252 * contains only the names of Berkeley DB log files no longer in use 00253 * by the filesystem. Otherwise, all log files (used and unused) are 00254 * returned. 00255 00256 * This function wraps the Berkeley DB 'log_archive' function 00257 * called by the db_archive binary. Repository administrators may 00258 * want to run this function periodically and delete the unused log 00259 * files, as a way of reclaiming disk space. 00260 */ 00261 svn_error_t *svn_fs_berkeley_logfiles (apr_array_header_t **logfiles, 00262 const char *path, 00263 svn_boolean_t only_unused, 00264 apr_pool_t *pool); 00265 00266 00267 /** 00268 * The following functions are similar to their generic counterparts, 00269 * but only work on Berkeley DB filesystems. 00270 * 00271 * @defgroup svn_fs_bdb_deprecated berkeley db filesystem compatibility 00272 * @{ 00273 */ 00274 00275 /** @deprecated Provided for backward compatibility with the 1.0 API. */ 00276 svn_fs_t *svn_fs_new (apr_hash_t *fs_config, apr_pool_t *pool); 00277 00278 /** @deprecated Provided for backward compatibility with the 1.0 API. */ 00279 svn_error_t *svn_fs_create_berkeley (svn_fs_t *fs, const char *path); 00280 00281 /** @deprecated Provided for backward compatibility with the 1.0 API. */ 00282 svn_error_t *svn_fs_open_berkeley (svn_fs_t *fs, const char *path); 00283 00284 /** @deprecated Provided for backward compatibility with the 1.0 API. */ 00285 const char *svn_fs_berkeley_path (svn_fs_t *fs, apr_pool_t *pool); 00286 00287 /** @deprecated Provided for backward compatibility with the 1.0 API. */ 00288 svn_error_t *svn_fs_delete_berkeley (const char *path, apr_pool_t *pool); 00289 00290 /** @deprecated Provided for backward compatibility with the 1.0 API. */ 00291 svn_error_t *svn_fs_hotcopy_berkeley (const char *src_path, 00292 const char *dest_path, 00293 svn_boolean_t clean_logs, 00294 apr_pool_t *pool); 00295 /** @} */ 00296 00297 /** @} */ 00298 00299 00300 /** Filesystem Access Contexts. 00301 * 00302 * @since New in 1.2. 00303 * 00304 * At certain times, filesystem functions need access to temporary 00305 * user data. For example, which user is changing a file? If the 00306 * file is locked, has an appropriate lock-token been supplied? 00307 * 00308 * This temporary user data is stored in an "access context" object, 00309 * and the access context is then connected to the filesystem object. 00310 * Whenever a filesystem function requires information, it can pull 00311 * things out of the context as needed. 00312 * 00313 * @defgroup svn_fs_access_ctx filesystem access contexts 00314 * @{ 00315 */ 00316 00317 /** An opaque object representing temporary user data. */ 00318 typedef struct svn_fs_access_t svn_fs_access_t; 00319 00320 00321 /** Set @a *access_ctx to a new @c svn_fs_access_t object representing 00322 * @a username, allocated in @a pool. @a username is presumed to 00323 * have been authenticated by the caller. 00324 */ 00325 svn_error_t *svn_fs_create_access (svn_fs_access_t **access_ctx, 00326 const char *username, 00327 apr_pool_t *pool); 00328 00329 00330 /** Associate @a access_ctx with an open @a fs. 00331 * 00332 * This function can be run multiple times on the same open 00333 * filesystem, in order to change the filesystem access context for 00334 * different filesystem operations. Pass a NULL value for @a 00335 * access_ctx to disassociate the current access context from the 00336 * filesystem. 00337 */ 00338 svn_error_t *svn_fs_set_access (svn_fs_t *fs, 00339 svn_fs_access_t *access_ctx); 00340 00341 00342 /** Set @a *access_ctx to the current @a fs access context, or NULL if 00343 * there is no current fs access context. 00344 */ 00345 svn_error_t *svn_fs_get_access (svn_fs_access_t **access_ctx, 00346 svn_fs_t *fs); 00347 00348 00349 /** Accessors for the access context: */ 00350 00351 /** Set @a *username to the name represented by @a access_ctx. */ 00352 svn_error_t *svn_fs_access_get_username (const char **username, 00353 svn_fs_access_t *access_ctx); 00354 00355 00356 /** Push a lock-token @a token into the context @a access_ctx. The 00357 * context remembers all tokens it receives, and makes them available 00358 * to fs functions. The token is not duplicated into @a access_ctx's 00359 * pool; make sure the token's lifetime is at least as long as @a 00360 * access_ctx. */ 00361 svn_error_t *svn_fs_access_add_lock_token (svn_fs_access_t *access_ctx, 00362 const char *token); 00363 00364 /** @} */ 00365 00366 00367 /** Filesystem Nodes. 00368 * 00369 * In a Subversion filesystem, a `node' corresponds roughly to an 00370 * `inode' in a Unix filesystem: 00371 * - A node is either a file or a directory. 00372 * - A node's contents change over time. 00373 * - When you change a node's contents, it's still the same node; it's 00374 * just been changed. So a node's identity isn't bound to a specific 00375 * set of contents. 00376 * - If you rename a node, it's still the same node, just under a 00377 * different name. So a node's identity isn't bound to a particular 00378 * filename. 00379 * 00380 * A `node revision' refers to a node's contents at a specific point in 00381 * time. Changing a node's contents always creates a new revision of that 00382 * node. Once created, a node revision's contents never change. 00383 * 00384 * When we create a node, its initial contents are the initial revision of 00385 * the node. As users make changes to the node over time, we create new 00386 * revisions of that same node. When a user commits a change that deletes 00387 * a file from the filesystem, we don't delete the node, or any revision 00388 * of it --- those stick around to allow us to recreate prior revisions of 00389 * the filesystem. Instead, we just remove the reference to the node 00390 * from the directory. 00391 * 00392 * @defgroup svn_fs_nodes filesystem nodes 00393 * @{ 00394 */ 00395 00396 /** An object representing a node-id. */ 00397 typedef struct svn_fs_id_t svn_fs_id_t; 00398 00399 00400 /** Return -1, 0, or 1 if node revisions @a a and @a B are unrelated, 00401 * equivalent, or otherwise related (respectively). 00402 */ 00403 int svn_fs_compare_ids (const svn_fs_id_t *a, const svn_fs_id_t *b); 00404 00405 00406 00407 /** Return non-zero IFF the nodes associated with @a id1 and @a id2 are 00408 * related, else return zero. 00409 */ 00410 svn_boolean_t svn_fs_check_related (const svn_fs_id_t *id1, 00411 const svn_fs_id_t *id2); 00412 00413 00414 /** 00415 * @deprecated Provided for backward compatibility with the 1.0 API. 00416 * 00417 * NOTE: This function is not guaranteed to work with all filesystem 00418 * types. There is currently no un-deprecated equivalent; contact the 00419 * Subversion developers if you have a need for it. 00420 */ 00421 svn_fs_id_t *svn_fs_parse_id (const char *data, 00422 apr_size_t len, 00423 apr_pool_t *pool); 00424 00425 00426 /** Return a Subversion string containing the unparsed form of the 00427 * node or node revision id @a id. Allocate the string containing the 00428 * unparsed form in @a pool. 00429 */ 00430 svn_string_t *svn_fs_unparse_id (const svn_fs_id_t *id, 00431 apr_pool_t *pool); 00432 00433 /** @} */ 00434 00435 00436 /** Filesystem Transactions. 00437 * 00438 * To make a change to a Subversion filesystem: 00439 * - Create a transaction object, using @c svn_fs_begin_txn. 00440 * - Call @c svn_fs_txn_root, to get the transaction's root directory. 00441 * - Make whatever changes you like in that tree. 00442 * - Commit the transaction, using @c svn_fs_commit_txn. 00443 * 00444 * The filesystem implementation guarantees that your commit will 00445 * either: 00446 * - succeed completely, so that all of the changes are committed to 00447 * create a new revision of the filesystem, or 00448 * - fail completely, leaving the filesystem unchanged. 00449 * 00450 * Until you commit the transaction, any changes you make are 00451 * invisible. Only when your commit succeeds do they become visible 00452 * to the outside world, as a new revision of the filesystem. 00453 * 00454 * If you begin a transaction, and then decide you don't want to make 00455 * the change after all (say, because your net connection with the 00456 * client disappeared before the change was complete), you can call 00457 * @c svn_fs_abort_txn, to cancel the entire transaction; this 00458 * leaves the filesystem unchanged. 00459 * 00460 * The only way to change the contents of files or directories, or 00461 * their properties, is by making a transaction and creating a new 00462 * revision, as described above. Once a revision has been committed, it 00463 * never changes again; the filesystem interface provides no means to 00464 * go back and edit the contents of an old revision. Once history has 00465 * been recorded, it is set in stone. Clients depend on this property 00466 * to do updates and commits reliably; proxies depend on this property 00467 * to cache changes accurately; and so on. 00468 * 00469 * There are two kinds of nodes in the filesystem: mutable, and 00470 * immutable. Revisions in the filesystem consist entirely of 00471 * immutable nodes, whose contents never change. A transaction in 00472 * progress, which the user is still constructing, uses mutable nodes 00473 * for those nodes which have been changed so far, and refers to 00474 * immutable nodes from existing revisions for portions of the tree 00475 * which haven't been changed yet in that transaction. 00476 * 00477 * Immutable nodes, as part of revisions, never refer to mutable 00478 * nodes, which are part of uncommitted transactions. Mutable nodes 00479 * may refer to immutable nodes, or other mutable nodes. 00480 * 00481 * Note that the terms "immutable" and "mutable" describe whether or 00482 * not the nodes have been changed as part of a transaction --- not 00483 * the permissions on the nodes they refer to. Even if you aren't 00484 * authorized to modify the filesystem's root directory, you might be 00485 * authorized to change some descendant of the root; doing so would 00486 * create a new mutable copy of the root directory. Mutability refers 00487 * to the role of the node: part of an existing revision, or part of a 00488 * new one. This is independent of your authorization to make changes 00489 * to a given node. 00490 * 00491 * Transactions are actually persistent objects, stored in the 00492 * database. You can open a filesystem, begin a transaction, and 00493 * close the filesystem, and then a separate process could open the 00494 * filesystem, pick up the same transaction, and continue work on it. 00495 * When a transaction is successfully committed, it is removed from 00496 * the database. 00497 * 00498 * Every transaction is assigned a name. You can open a transaction 00499 * by name, and resume work on it, or find out the name of a 00500 * transaction you already have open. You can also list all the 00501 * transactions currently present in the database. 00502 * 00503 * Transaction names are guaranteed to contain only letters (upper- 00504 * and lower-case), digits, `-', and `.', from the ASCII character 00505 * set. 00506 * 00507 * @defgroup svn_fs_txns filesystem transactions 00508 * @{ 00509 */ 00510 00511 /** The type of a Subversion transaction object. */ 00512 typedef struct svn_fs_txn_t svn_fs_txn_t; 00513 00514 00515 /** @defgroup svn_fs_begin_txn2_flags Bitmask flags for svn_fs_begin_txn2() 00516 * @since New in 1.2 00517 * @{ */ 00518 00519 /** Do on-the-fly out-of-dateness checks. That is, an fs routine may 00520 * throw error if a caller tries to edit an out-of-date item in the 00521 * transaction. 00522 * 00523 * @warning ### Not yet implemented. 00524 */ 00525 #define SVN_FS_TXN_CHECK_OOD 0x00001 00526 00527 /** Do on-the-fly lock checks. That is, an fs routine may throw error 00528 * if a caller tries to edit a locked item without having rights to the lock. 00529 */ 00530 #define SVN_FS_TXN_CHECK_LOCKS 0x00002 00531 /** @} */ 00532 00533 /** @since New in 1.2 00534 * 00535 * Begin a new transaction on the filesystem @a fs, based on existing 00536 * revision @a rev. Set @a *txn_p to a pointer to the new transaction. 00537 * When committed, this transaction will create a new revision. 00538 * 00539 * Allocate the new transaction in @a pool; when @a pool is freed, the new 00540 * transaction will be closed (neither committed nor aborted). 00541 * 00542 * @a flags determines transaction enforcement behaviors, and is composed 00543 * from the constants SVN_FS_TXN_* (@c SVN_FS_TXN_CHECK_OOD etc.). 00544 * 00545 * @note If you're building a txn for committing, you probably 00546 * don't want to call this directly. Instead, call 00547 * @c svn_repos_fs_begin_txn_for_commit(), which honors the 00548 * repository's hook configurations. 00549 */ 00550 svn_error_t *svn_fs_begin_txn2 (svn_fs_txn_t **txn_p, 00551 svn_fs_t *fs, 00552 svn_revnum_t rev, 00553 apr_uint32_t flags, 00554 apr_pool_t *pool); 00555 00556 00557 /** @deprecated Provided for backward compatibility with svn 1.1 API. 00558 * 00559 * Same as svn_fs_begin_txn2(), but with @a flags set to 0. 00560 * 00561 */ 00562 svn_error_t *svn_fs_begin_txn (svn_fs_txn_t **txn_p, 00563 svn_fs_t *fs, 00564 svn_revnum_t rev, 00565 apr_pool_t *pool); 00566 00567 00568 00569 /** Commit @a txn. 00570 * 00571 * @note You usually don't want to call this directly. 00572 * Instead, call @c svn_repos_fs_commit_txn(), which honors the 00573 * repository's hook configurations. 00574 * 00575 * If the transaction conflicts with other changes committed to the 00576 * repository, return an @c SVN_ERR_FS_CONFLICT error. Otherwise, create 00577 * a new filesystem revision containing the changes made in @a txn, 00578 * storing that new revision number in @a *new_rev, and return zero. 00579 * 00580 * If @a conflict_p is non-zero, use it to provide details on any 00581 * conflicts encountered merging @a txn with the most recent committed 00582 * revisions. If a conflict occurs, set @a *conflict_p to the path of 00583 * the conflict in @a txn, with the same lifetime as @a txn; 00584 * otherwise, set @a *conflict_p to null. 00585 * 00586 * If the commit succeeds, @a txn is invalid. 00587 * 00588 * If the commit fails, @a txn is still valid; you can make more 00589 * operations to resolve the conflict, or call @c svn_fs_abort_txn to 00590 * abort the transaction. 00591 * 00592 * NOTE: Success or failure of the commit of @a txn is determined by 00593 * examining the value of @a *new_rev upon this function's return. If 00594 * the value is a valid revision number, the commit was successful, 00595 * even though a non-@c NULL function return value may indicate that 00596 * something else went wrong. 00597 */ 00598 svn_error_t *svn_fs_commit_txn (const char **conflict_p, 00599 svn_revnum_t *new_rev, 00600 svn_fs_txn_t *txn, 00601 apr_pool_t *pool); 00602 00603 00604 /** Abort the transaction @a txn. Any changes made in @a txn are 00605 * discarded, and the filesystem is left unchanged. Use @a pool for 00606 * any necessary allocations. 00607 * 00608 * NOTE: This function first sets the state of @a txn to "dead", and 00609 * then attempts to purge it and any related data from the filesystem. 00610 * If some part of the cleanup process fails, @a txn and some portion 00611 * of its data may remain in the database after this function returns. 00612 * Use @c svn_fs_purge_txn() to retry the transaction cleanup. 00613 */ 00614 svn_error_t *svn_fs_abort_txn (svn_fs_txn_t *txn, 00615 apr_pool_t *pool); 00616 00617 00618 /** Cleanup the dead transaction in @a fs whose ID is @a txn_id. Use 00619 * @a pool for all allocations. If the transaction is not yet dead, 00620 * the error @c SVN_ERR_FS_TRANSACTION_NOT_DEAD is returned. (The 00621 * caller probably forgot to abort the transaction, or the cleanup 00622 * step of that abort failed for some reason.) 00623 */ 00624 svn_error_t *svn_fs_purge_txn (svn_fs_t *fs, 00625 const char *txn_id, 00626 apr_pool_t *pool); 00627 00628 00629 /** Set @a *name_p to the name of the transaction @a txn, as a 00630 * null-terminated string. Allocate the name in @a pool. 00631 */ 00632 svn_error_t *svn_fs_txn_name (const char **name_p, 00633 svn_fs_txn_t *txn, 00634 apr_pool_t *pool); 00635 00636 /** Return @a txn's base revision. */ 00637 svn_revnum_t svn_fs_txn_base_revision (svn_fs_txn_t *txn); 00638 00639 00640 00641 /** Open the transaction named @a name in the filesystem @a fs. Set @a *txn 00642 * to the transaction. 00643 * 00644 * If there is no such transaction, @c SVN_ERR_FS_NO_SUCH_TRANSACTION is 00645 * the error returned. 00646 * 00647 * Allocate the new transaction in @a pool; when @a pool is freed, the new 00648 * transaction will be closed (neither committed nor aborted). 00649 */ 00650 svn_error_t *svn_fs_open_txn (svn_fs_txn_t **txn, 00651 svn_fs_t *fs, 00652 const char *name, 00653 apr_pool_t *pool); 00654 00655 00656 /** Set @a *names_p to an array of <tt>const char *</tt> ids which are the 00657 * names of all the currently active transactions in the filesystem @a fs. 00658 * Allocate the array in @a pool. 00659 */ 00660 svn_error_t *svn_fs_list_transactions (apr_array_header_t **names_p, 00661 svn_fs_t *fs, 00662 apr_pool_t *pool); 00663 00664 /* Transaction properties */ 00665 00666 /** Set @a *value_p to the value of the property named @a propname on 00667 * transaction @a txn. If @a txn has no property by that name, set 00668 * @a *value_p to zero. Allocate the result in @a pool. 00669 */ 00670 svn_error_t *svn_fs_txn_prop (svn_string_t **value_p, 00671 svn_fs_txn_t *txn, 00672 const char *propname, 00673 apr_pool_t *pool); 00674 00675 00676 /** Set @a *table_p to the entire property list of transaction @a txn in 00677 * filesystem @a fs, as an APR hash table allocated in @a pool. The 00678 * resulting table maps property names to pointers to @c svn_string_t 00679 * objects containing the property value. 00680 */ 00681 svn_error_t *svn_fs_txn_proplist (apr_hash_t **table_p, 00682 svn_fs_txn_t *txn, 00683 apr_pool_t *pool); 00684 00685 00686 /** Change a transactions @a txn's property's value, or add/delete a 00687 * property. @a name is the name of the property to change, and @a value 00688 * is the new value of the property, or zero if the property should be 00689 * removed altogether. Do any necessary temporary allocation in @a pool. 00690 */ 00691 svn_error_t *svn_fs_change_txn_prop (svn_fs_txn_t *txn, 00692 const char *name, 00693 const svn_string_t *value, 00694 apr_pool_t *pool); 00695 00696 /** @} */ 00697 00698 00699 /** Roots. 00700 * 00701 * An @c svn_fs_root_t object represents the root directory of some 00702 * revision or transaction in a filesystem. To refer to particular 00703 * node, you provide a root, and a directory path relative that root. 00704 * 00705 * @defgroup svn_fs_roots filesystem roots 00706 * @{ 00707 */ 00708 00709 /** The Filesystem Root object. */ 00710 typedef struct svn_fs_root_t svn_fs_root_t; 00711 00712 00713 /** Set @a *root_p to the root directory of revision @a rev in filesystem 00714 * @a fs. Allocate @a *root_p in @a pool. 00715 */ 00716 svn_error_t *svn_fs_revision_root (svn_fs_root_t **root_p, 00717 svn_fs_t *fs, 00718 svn_revnum_t rev, 00719 apr_pool_t *pool); 00720 00721 00722 /** Set @a *root_p to the root directory of @a txn. Allocate @a *root_p in 00723 * @a pool. 00724 */ 00725 svn_error_t *svn_fs_txn_root (svn_fs_root_t **root_p, 00726 svn_fs_txn_t *txn, 00727 apr_pool_t *pool); 00728 00729 00730 /** Free the root directory @a root. Simply clearing or destroying the 00731 * pool @a root was allocated in will have the same effect as calling 00732 * this function. 00733 */ 00734 void svn_fs_close_root (svn_fs_root_t *root); 00735 00736 00737 /** Return the filesystem to which @a root belongs. */ 00738 svn_fs_t *svn_fs_root_fs (svn_fs_root_t *root); 00739 00740 00741 /** Return @c TRUE iff @a root is a transaction root. */ 00742 svn_boolean_t svn_fs_is_txn_root (svn_fs_root_t *root); 00743 00744 /** Return @c TRUE iff @a root is a revision root. */ 00745 svn_boolean_t svn_fs_is_revision_root (svn_fs_root_t *root); 00746 00747 00748 /** If @a root is the root of a transaction, return the name of the 00749 * transaction, allocated in @a pool; otherwise, return null. 00750 */ 00751 const char *svn_fs_txn_root_name (svn_fs_root_t *root, 00752 apr_pool_t *pool); 00753 00754 00755 /** If @a root is the root of a revision, return the revision number. 00756 * Otherwise, return @c SVN_INVALID_REVNUM. 00757 */ 00758 svn_revnum_t svn_fs_revision_root_revision (svn_fs_root_t *root); 00759 00760 /** @} */ 00761 00762 00763 /** Directory entry names and directory paths. 00764 * 00765 * Here are the rules for directory entry names, and directory paths: 00766 * 00767 * A directory entry name is a Unicode string encoded in UTF-8, and 00768 * may not contain the null character (U+0000). The name should be in 00769 * Unicode canonical decomposition and ordering. No directory entry 00770 * may be named '.', '..', or the empty string. Given a directory 00771 * entry name which fails to meet these requirements, a filesystem 00772 * function returns an SVN_ERR_FS_PATH_SYNTAX error. 00773 * 00774 * A directory path is a sequence of zero or more directory entry 00775 * names, separated by slash characters (U+002f), and possibly ending 00776 * with slash characters. Sequences of two or more consecutive slash 00777 * characters are treated as if they were a single slash. If a path 00778 * ends with a slash, it refers to the same node it would without the 00779 * slash, but that node must be a directory, or else the function 00780 * returns an SVN_ERR_FS_NOT_DIRECTORY error. 00781 * 00782 * A path consisting of the empty string, or a string containing only 00783 * slashes, refers to the root directory. 00784 * 00785 * @defgroup svn_fs_directories filesystem directories 00786 * @{ 00787 */ 00788 00789 00790 00791 /** The kind of change that occurred on the path. */ 00792 typedef enum 00793 { 00794 /** default value */ 00795 svn_fs_path_change_modify = 0, 00796 00797 /** path added in txn */ 00798 svn_fs_path_change_add, 00799 00800 /** path removed in txn */ 00801 svn_fs_path_change_delete, 00802 00803 /** path removed and re-added in txn */ 00804 svn_fs_path_change_replace, 00805 00806 /** ignore all previous change items for path (internal-use only) */ 00807 svn_fs_path_change_reset 00808 00809 } svn_fs_path_change_kind_t; 00810 00811 /** Change descriptor. */ 00812 typedef struct svn_fs_path_change_t 00813 { 00814 /** node revision id of changed path */ 00815 const svn_fs_id_t *node_rev_id; 00816 00817 /** kind of change */ 00818 svn_fs_path_change_kind_t change_kind; 00819 00820 /** were there text mods? */ 00821 svn_boolean_t text_mod; 00822 00823 /** were there property mods? */ 00824 svn_boolean_t prop_mod; 00825 00826 } svn_fs_path_change_t; 00827 00828 00829 /** Determine what has changed under a @a root. 00830 * 00831 * Allocate and return a hash @a *changed_paths_p containing descriptions 00832 * of the paths changed under @a root. The hash is keyed with 00833 * <tt>const char *</tt> paths, and has @c svn_fs_path_change_t * values. 00834 * Use @c pool for all allocations, including the hash and its values. 00835 */ 00836 svn_error_t *svn_fs_paths_changed (apr_hash_t **changed_paths_p, 00837 svn_fs_root_t *root, 00838 apr_pool_t *pool); 00839 00840 /** @} */ 00841 00842 00843 /* Operations appropriate to all kinds of nodes. */ 00844 00845 /** Set @a *kind_p to the type of node present at @a path under @a 00846 * root. If @a path does not exist under @a root, set @a *kind to @c 00847 * svn_node_none. Use @a pool for temporary allocation. 00848 */ 00849 svn_error_t *svn_fs_check_path (svn_node_kind_t *kind_p, 00850 svn_fs_root_t *root, 00851 const char *path, 00852 apr_pool_t *pool); 00853 00854 00855 /** An opaque node history object. */ 00856 typedef struct svn_fs_history_t svn_fs_history_t; 00857 00858 00859 /** Set @a *history_p to an opaque node history object which 00860 * represents @a path under @a root. @a root must be a revision root. 00861 * Use @a pool for all allocations. 00862 */ 00863 svn_error_t *svn_fs_node_history (svn_fs_history_t **history_p, 00864 svn_fs_root_t *root, 00865 const char *path, 00866 apr_pool_t *pool); 00867 00868 00869 /** Set @a *prev_history_t to an opaque node history object which 00870 * represents the previous (or "next oldest") interesting history 00871 * location for the filesystem node represented by @a history, or @c 00872 * NULL if no such previous history exists. If @a cross_copies is @c 00873 * FALSE, also return @c NULL if stepping backwards in history to @a 00874 * prev_history_t would cross a filesystem copy operation. 00875 * 00876 * NOTE: If this is the first call to svn_fs_history_prev() for the @a 00877 * history object, it could return a history object whose location is 00878 * the same as the original. This will happen if the original 00879 * location was an interesting one (where the node was modified, or 00880 * took place in a copy event). This behavior allows looping callers 00881 * to avoid the calling svn_fs_history_location() on the object 00882 * returned by svn_fs_node_history(), and instead go ahead and begin 00883 * calling svn_fs_history_prev(). 00884 * 00885 * NOTE: This function uses node-id ancestry alone to determine 00886 * modifiedness, and therefore does NOT claim that in any of the 00887 * returned revisions file contents changed, properties changed, 00888 * directory entries lists changed, etc. 00889 * 00890 * ALSO NOTE: The revisions returned for @a path will be older than or 00891 * the same age as the revision of that path in @a root. That is, if 00892 * @a root is a revision root based on revision X, and @a path was 00893 * modified in some revision(s) younger than X, those revisions 00894 * younger than X will not be included for @a path. */ 00895 svn_error_t *svn_fs_history_prev (svn_fs_history_t **prev_history_p, 00896 svn_fs_history_t *history, 00897 svn_boolean_t cross_copies, 00898 apr_pool_t *pool); 00899 00900 00901 /** Set @a *path and @a *revision to the path and revision, 00902 * respectively, of the @a history object. Use @a pool for all 00903 * allocations. 00904 */ 00905 svn_error_t *svn_fs_history_location (const char **path, 00906 svn_revnum_t *revision, 00907 svn_fs_history_t *history, 00908 apr_pool_t *pool); 00909 00910 00911 /** Set @a *is_dir to @c TRUE iff @a path in @a root is a directory. 00912 * Do any necessary temporary allocation in @a pool. 00913 */ 00914 svn_error_t *svn_fs_is_dir (svn_boolean_t *is_dir, 00915 svn_fs_root_t *root, 00916 const char *path, 00917 apr_pool_t *pool); 00918 00919 00920 /** Set @a *is_file to @c TRUE iff @a path in @a root is a file. 00921 * Do any necessary temporary allocation in @a pool. 00922 */ 00923 svn_error_t *svn_fs_is_file (svn_boolean_t *is_file, 00924 svn_fs_root_t *root, 00925 const char *path, 00926 apr_pool_t *pool); 00927 00928 00929 /** Get the id of a node. 00930 * 00931 * Set @a *id_p to the node revision ID of @a path in @a root, allocated in 00932 * @a pool. 00933 * 00934 * If @a root is the root of a transaction, keep in mind that other 00935 * changes to the transaction can change which node @a path refers to, 00936 * and even whether the path exists at all. 00937 */ 00938 svn_error_t *svn_fs_node_id (const svn_fs_id_t **id_p, 00939 svn_fs_root_t *root, 00940 const char *path, 00941 apr_pool_t *pool); 00942 00943 /** Set @a *revision to the revision in which @a path under @a root was 00944 * created. Use @a pool for any temporary allocations. @a *revision will 00945 * be set to @c SVN_INVALID_REVNUM for uncommitted nodes (i.e. modified nodes 00946 * under a transaction root). 00947 */ 00948 svn_error_t *svn_fs_node_created_rev (svn_revnum_t *revision, 00949 svn_fs_root_t *root, 00950 const char *path, 00951 apr_pool_t *pool); 00952 00953 /** Set @a *created_path to the path at which @a path under @a root was 00954 * created. Use @a pool for all allocations. Callers may use this 00955 * function in conjunction with svn_fs_node_created_rev() perform a 00956 * reverse lookup of the mapping of (path, revision) -> node-id that 00957 * svn_fs_node_id() performs. 00958 */ 00959 svn_error_t *svn_fs_node_created_path (const char **created_path, 00960 svn_fs_root_t *root, 00961 const char *path, 00962 apr_pool_t *pool); 00963 00964 00965 /** Set @a *value_p to the value of the property named @a propname of 00966 * @a path in @a root. If the node has no property by that name, set 00967 * @a *value_p to zero. Allocate the result in @a pool. 00968 */ 00969 svn_error_t *svn_fs_node_prop (svn_string_t **value_p, 00970 svn_fs_root_t *root, 00971 const char *path, 00972 const char *propname, 00973 apr_pool_t *pool); 00974 00975 00976 /** Set @a *table_p to the entire property list of @a path in @a root, 00977 * as an APR hash table allocated in @a pool. The resulting table maps 00978 * property names to pointers to @c svn_string_t objects containing the 00979 * property value. 00980 */ 00981 svn_error_t *svn_fs_node_proplist (apr_hash_t **table_p, 00982 svn_fs_root_t *root, 00983 const char *path, 00984 apr_pool_t *pool); 00985 00986 00987 /** Change a node's property's value, or add/delete a property. 00988 * 00989 * - @a root and @a path indicate the node whose property should change. 00990 * @a root must be the root of a transaction, not the root of a revision. 00991 * - @a name is the name of the property to change. 00992 * - @a value is the new value of the property, or zero if the property should 00993 * be removed altogether. 00994 * Do any necessary temporary allocation in @a pool. 00995 */ 00996 svn_error_t *svn_fs_change_node_prop (svn_fs_root_t *root, 00997 const char *path, 00998 const char *name, 00999 const svn_string_t *value, 01000 apr_pool_t *pool); 01001 01002 01003 /** Determine if the properties of two path/root combinations are different. 01004 * 01005 * Set @a *changed_p to 1 if the properties at @a path1 under @a root1 differ 01006 * from those at @a path2 under @a root2, or set it to 0 if they are the 01007 * same. Both paths must exist under their respective roots, and both 01008 * roots must be in the same filesystem. 01009 */ 01010 svn_error_t *svn_fs_props_changed (svn_boolean_t *changed_p, 01011 svn_fs_root_t *root1, 01012 const char *path1, 01013 svn_fs_root_t *root2, 01014 const char *path2, 01015 apr_pool_t *pool); 01016 01017 01018 /** Discover a node's copy ancestry, if any. 01019 * 01020 * If the node at @a path in @a root was copied from some other node, set 01021 * @a *rev_p and @a *path_p to the revision and path of the other node, 01022 * allocating @a *path_p in @a pool. 01023 * 01024 * Else if there is no copy ancestry for the node, set @a *rev_p to 01025 * @c SVN_INVALID_REVNUM and @a *path_p to null. 01026 * 01027 * If an error is returned, the values of @a *rev_p and @a *path_p are 01028 * undefined, but otherwise, if one of them is set as described above, 01029 * you may assume the other is set correspondingly. 01030 * 01031 * @a root may be a revision root or a transaction root. 01032 * 01033 * Notes: 01034 * - Copy ancestry does not descend. After copying directory D to 01035 * E, E will have copy ancestry referring to D, but E's children 01036 * may not. See also @c svn_fs_copy(). 01037 * 01038 * - Copy ancestry *under* a copy is preserved. That is, if you 01039 * copy /A/D/G/pi to /A/D/G/pi2, and then copy /A/D/G to /G, then 01040 * /G/pi2 will still have copy ancestry pointing to /A/D/G/pi. 01041 * We don't know if this is a feature or a bug yet; if it turns 01042 * out to be a bug, then the fix is to make @c svn_fs_copied_from() 01043 * observe the following logic, which currently callers may 01044 * choose to follow themselves: if node X has copy history, but 01045 * its ancestor A also has copy history, then you may ignore X's 01046 * history if X's revision-of-origin is earlier than A's -- 01047 * because that would mean that X's copy history was preserved in 01048 * a copy-under-a-copy scenario. If X's revision-of-origin is 01049 * the same as A's, then it was copied under A during the same 01050 * transaction that created A. (X's revision-of-origin cannot be 01051 * greater than A's, if X has copy history.) ### todo: See how 01052 * people like this, it can always be hidden behind the curtain 01053 * if necessary. 01054 * 01055 * - Copy ancestry is not stored as a regular subversion property 01056 * because it is not inherited. Copying foo to bar results in a 01057 * revision of bar with copy ancestry; but committing a text 01058 * change to bar right after that results in a new revision of 01059 * bar without copy ancestry. 01060 */ 01061 svn_error_t *svn_fs_copied_from (svn_revnum_t *rev_p, 01062 const char **path_p, 01063 svn_fs_root_t *root, 01064 const char *path, 01065 apr_pool_t *pool); 01066 01067 01068 /** Merge changes between two nodes into a third node. 01069 * 01070 * Given nodes @a source and @a target, and a common ancestor @a ancestor, 01071 * modify @a target to contain all the changes made between @a ancestor and 01072 * @a source, as well as the changes made between @a ancestor and @a target. 01073 * @a target_root must be the root of a transaction, not a revision. 01074 * 01075 * @a source, @a target, and @a ancestor are generally directories; this 01076 * function recursively merges the directories' contents. If they are 01077 * files, this function simply returns an error whenever @a source, 01078 * @a target, and @a ancestor are all distinct node revisions. 01079 * 01080 * If there are differences between @a ancestor and @a source that conflict 01081 * with changes between @a ancestor and @a target, this function returns an 01082 * @c SVN_ERR_FS_CONFLICT error. 01083 * 01084 * If the merge is successful, @a target is left in the merged state, and 01085 * the base root of @a target's txn is set to the root node of @a source. 01086 * If an error is returned (whether for conflict or otherwise), @a target 01087 * is left unaffected. 01088 * 01089 * If @a conflict_p is non-null, then: a conflict error sets @a *conflict_p 01090 * to the name of the node in @a target which couldn't be merged, 01091 * otherwise, success sets @a *conflict_p to null. 01092 * 01093 * Do any necessary temporary allocation in @a pool. 01094 */ 01095 svn_error_t *svn_fs_merge (const char **conflict_p, 01096 svn_fs_root_t *source_root, 01097 const char *source_path, 01098 svn_fs_root_t *target_root, 01099 const char *target_path, 01100 svn_fs_root_t *ancestor_root, 01101 const char *ancestor_path, 01102 apr_pool_t *pool); 01103 01104 01105 01106 /* Directories. */ 01107 01108 01109 /** The type of a Subversion directory entry. */ 01110 typedef struct svn_fs_dirent_t 01111 { 01112 01113 /** The name of this directory entry. */ 01114 const char *name; 01115 01116 /** The node revision ID it names. */ 01117 const svn_fs_id_t *id; 01118 01119 /** The node kind. */ 01120 svn_node_kind_t kind; 01121 01122 } svn_fs_dirent_t; 01123 01124 01125 /** Set @a *entries_p to a newly allocated APR hash table containing the 01126 * entries of the directory at @a path in @a root. The keys of the table 01127 * are entry names, as byte strings, excluding the final null 01128 * character; the table's values are pointers to @c svn_fs_dirent_t 01129 * structures. Allocate the table and its contents in @a pool. 01130 */ 01131 svn_error_t *svn_fs_dir_entries (apr_hash_t **entries_p, 01132 svn_fs_root_t *root, 01133 const char *path, 01134 apr_pool_t *pool); 01135 01136 01137 /** Create a new directory named @a path in @a root. The new directory has 01138 * no entries, and no properties. @a root must be the root of a transaction, 01139 * not a revision. 01140 * 01141 * Do any necessary temporary allocation in @a pool. 01142 */ 01143 svn_error_t *svn_fs_make_dir (svn_fs_root_t *root, 01144 const char *path, 01145 apr_pool_t *pool); 01146 01147 01148 /** Delete the node named @a path in @a root. If the node being deleted is 01149 * a directory, its contents will be deleted recursively. @a root must be 01150 * the root of a transaction, not of a revision. Use @a pool for 01151 * temporary allocation. 01152 * 01153 * This function may be more efficient than making the equivalent 01154 * series of calls to @c svn_fs_delete, because it takes advantage of the 01155 * fact that, to delete an immutable subtree, shared with some 01156 * committed revision, you need only remove the directory entry. The 01157 * dumb algorithm would recurse into the subtree and end up cloning 01158 * each non-empty directory it contains, only to delete it later. 01159 * 01160 * If return @c SVN_ERR_FS_NO_SUCH_ENTRY, then the basename of @a path is 01161 * missing from its parent, that is, the final target of the deletion 01162 * is missing. 01163 * 01164 * Attempting to remove the root dir also results in an error, 01165 * @c SVN_ERR_FS_ROOT_DIR, even if the dir is empty. 01166 */ 01167 svn_error_t *svn_fs_delete (svn_fs_root_t *root, 01168 const char *path, 01169 apr_pool_t *pool); 01170 01171 01172 /** Create a copy of @a from_path in @a from_root named @a to_path in 01173 * @a to_root. If @a from_path in @a from_root is a directory, copy the 01174 * tree it refers to recursively. 01175 * 01176 * The copy will remember its source; use @c svn_fs_copied_from() to 01177 * access this information. 01178 * 01179 * @a to_root must be the root of a transaction; @a from_path must be the 01180 * root of a revision. (Requiring @a from_path to be the root of a 01181 * revision makes the implementation trivial: there is no detectable 01182 * difference (modulo node revision ID's) between copying @a from and 01183 * simply adding a reference to it. So the operation takes place in 01184 * constant time. However, there's no reason not to extend this to 01185 * mutable nodes --- it's just more code.) Further, @a to_root and @a 01186 * from_root must represent the same filesystem. 01187 * 01188 * Note: to do a copy without preserving copy history, use 01189 * @c svn_fs_revision_link(). 01190 * 01191 * Do any necessary temporary allocation in @a pool. 01192 */ 01193 svn_error_t *svn_fs_copy (svn_fs_root_t *from_root, 01194 const char *from_path, 01195 svn_fs_root_t *to_root, 01196 const char *to_path, 01197 apr_pool_t *pool); 01198 01199 01200 /** Like @c svn_fs_copy(), but doesn't record copy history, and preserves 01201 * the PATH. You cannot use @c svn_fs_copied_from() later to find out 01202 * where this copy came from. 01203 * 01204 * Use @c svn_fs_revision_link() in situations where you don't care 01205 * about the copy history, and where @a to_path and @a from_path are 01206 * the same, because it is cheaper than @c svn_fs_copy(). 01207 */ 01208 svn_error_t *svn_fs_revision_link (svn_fs_root_t *from_root, 01209 svn_fs_root_t *to_root, 01210 const char *path, 01211 apr_pool_t *pool); 01212 01213 /* Files. */ 01214 01215 /** Set @a *length_p to the length of the file @a path in @a root, in bytes. 01216 * Do any necessary temporary allocation in @a pool. 01217 */ 01218 svn_error_t *svn_fs_file_length (svn_filesize_t *length_p, 01219 svn_fs_root_t *root, 01220 const char *path, 01221 apr_pool_t *pool); 01222 01223 01224 /** Put the MD5 checksum of file @a path into @a digest, which points 01225 * to @c APR_MD5_DIGESTSIZE bytes of storage. Use @a pool only for temporary 01226 * allocations. 01227 * 01228 * If the filesystem does not have a prerecorded checksum for @a path, 01229 * do not calculate a checksum dynamically, just put all 0's into @a 01230 * digest. (By convention, the all-zero checksum is considered to 01231 * match any checksum.) 01232 * 01233 * Notes: 01234 * 01235 * You might wonder, why do we only provide this interface for file 01236 * contents, and not for properties or directories? 01237 * 01238 * The answer is that property lists and directory entry lists are 01239 * essentially data structures, not text. We serialize them for 01240 * transmission, but there is no guarantee that the consumer will 01241 * parse them into the same form, or even the same order, as the 01242 * producer. It's difficult to find a checksumming method that 01243 * reaches the same result given such variation in input. (I suppose 01244 * we could calculate an independent MD5 sum for each propname and 01245 * value, and XOR them together; same with directory entry names. 01246 * Maybe that's the solution?) Anyway, for now we punt. The most 01247 * important data, and the only data that goes through svndiff 01248 * processing, is file contents, so that's what we provide 01249 * checksumming for. 01250 * 01251 * Internally, of course, the filesystem checksums everything, because 01252 * it has access to the lowest level storage forms: strings behind 01253 * representations. 01254 */ 01255 svn_error_t *svn_fs_file_md5_checksum (unsigned char digest[], 01256 svn_fs_root_t *root, 01257 const char *path, 01258 apr_pool_t *pool); 01259 01260 01261 /** Set @a *contents to a readable generic stream that will yield the 01262 * contents of the file @a path in @a root. Allocate the stream in 01263 * @a pool. You can only use @a *contents for as long as the underlying 01264 * filesystem is open. If @a path is not a file, return 01265 * @c SVN_ERR_FS_NOT_FILE. 01266 * 01267 * If @a root is the root of a transaction, it is possible that the 01268 * contents of the file @a path will change between calls to 01269 * @c svn_fs_file_contents(). In that case, the result of reading from 01270 * @a *contents is undefined. 01271 * 01272 * ### kff todo: I am worried about lifetime issues with this pool vs 01273 * the trail created farther down the call stack. Trace this function 01274 * to investigate... 01275 */ 01276 svn_error_t *svn_fs_file_contents (svn_stream_t **contents, 01277 svn_fs_root_t *root, 01278 const char *path, 01279 apr_pool_t *pool); 01280 01281 01282 /** Create a new file named @a path in @a root. The file's initial contents 01283 * are the empty string, and it has no properties. @a root must be the 01284 * root of a transaction, not a revision. 01285 * 01286 * Do any necessary temporary allocation in @a pool. 01287 */ 01288 svn_error_t *svn_fs_make_file (svn_fs_root_t *root, 01289 const char *path, 01290 apr_pool_t *pool); 01291 01292 01293 /** Apply a text delta to the file @a path in @a root. @a root must be the 01294 * root of a transaction, not a revision. 01295 * 01296 * Set @a *contents_p to a function ready to receive text delta windows 01297 * describing how to change the file's contents, relative to its 01298 * current contents. Set @a *contents_baton_p to a baton to pass to 01299 * @a *contents_p. 01300 * 01301 * If @a path does not exist in @a root, return an error. (You cannot use 01302 * this routine to create new files; use @c svn_fs_make_file to create 01303 * an empty file first.) 01304 * 01305 * @a base_checksum is the hex MD5 digest for the base text against 01306 * which the delta is to be applied; it is ignored if null, and may be 01307 * ignored even if not null. If it is not ignored, it must match the 01308 * checksum of the base text against which svndiff data is being 01309 * applied; if not, svn_fs_apply_textdelta or the @a *contents_p call 01310 * which detects the mismatch will return the error 01311 * @c SVN_ERR_CHECKSUM_MISMATCH (if there is no base text, there may 01312 * still be an error if @a base_checksum is neither null nor the 01313 * checksum of the empty string). 01314 * 01315 * @a result_checksum is the hex MD5 digest for the fulltext that 01316 * results from this delta application. It is ignored if null, but if 01317 * not null, it must match the checksum of the result; if it does not, 01318 * then the @a *contents_p call which detects the mismatch will return 01319 * the error @c SVN_ERR_CHECKSUM_MISMATCH. 01320 * 01321 * The caller must send all delta windows including the terminating 01322 * NULL window to @a *contents_p before making further changes to the 01323 * transaction. 01324 * 01325 * Do temporary allocation in @a pool. 01326 */ 01327 svn_error_t *svn_fs_apply_textdelta (svn_txdelta_window_handler_t *contents_p, 01328 void **contents_baton_p, 01329 svn_fs_root_t *root, 01330 const char *path, 01331 const char *base_checksum, 01332 const char *result_checksum, 01333 apr_pool_t *pool); 01334 01335 01336 /** Write data directly to the file @a path in @a root. @a root must be the 01337 * root of a transaction, not a revision. 01338 * 01339 * Set @a *contents_p to a stream ready to receive full textual data. 01340 * When the caller closes this stream, the data replaces the previous 01341 * contents of the file. 01342 * 01343 * If @a path does not exist in @a root, return an error. (You cannot use 01344 * this routine to create new files; use @c svn_fs_make_file to create 01345 * an empty file first.) 01346 * 01347 * @a result_checksum is the hex MD5 digest for the final fulltext 01348 * written to the stream. It is ignored if null, but if not null, it 01349 * must match the checksum of the result; if it does not, then the @a 01350 * *contents_p call which detects the mismatch will return the error 01351 * @c SVN_ERR_CHECKSUM_MISMATCH. 01352 * 01353 * Do any necessary temporary allocation in @a pool. 01354 * 01355 * ### This is like svn_fs_apply_textdelta, but takes the text 01356 * straight. It is currently used only by the loader, see 01357 * libsvn_repos/load.c. It should accept a checksum, of course, which 01358 * would come from an (optional) header in the dump file. See 01359 * http://subversion.tigris.org/issues/show_bug.cgi?id=1102 for more. 01360 */ 01361 svn_error_t *svn_fs_apply_text (svn_stream_t **contents_p, 01362 svn_fs_root_t *root, 01363 const char *path, 01364 const char *result_checksum, 01365 apr_pool_t *pool); 01366 01367 01368 /** Check if the contents of two root/path combos have changed. 01369 * 01370 * Set @a *changed_p to 1 if the contents at @a path1 under @a root1 differ 01371 * from those at @a path2 under @a root2, or set it to 0 if they are the 01372 * same. Both paths must exist under their respective roots, and both 01373 * roots must be in the same filesystem. 01374 */ 01375 svn_error_t *svn_fs_contents_changed (svn_boolean_t *changed_p, 01376 svn_fs_root_t *root1, 01377 const char *path1, 01378 svn_fs_root_t *root2, 01379 const char *path2, 01380 apr_pool_t *pool); 01381 01382 01383 01384 /* Filesystem revisions. */ 01385 01386 01387 /** Set @a *youngest_p to the number of the youngest revision in filesystem 01388 * @a fs. Use @a pool for all temporary allocation. 01389 * 01390 * The oldest revision in any filesystem is numbered zero. 01391 */ 01392 svn_error_t *svn_fs_youngest_rev (svn_revnum_t *youngest_p, 01393 svn_fs_t *fs, 01394 apr_pool_t *pool); 01395 01396 01397 /** Deltify predecessors of paths modified in @a revision in 01398 * filesystem @a fs. Use @a pool for all allocations. 01399 * 01400 * NOTE: This can be a time-consuming process, depending the breadth 01401 * of the changes made in @a revision, and the depth of the history of 01402 * those changed paths. 01403 */ 01404 svn_error_t *svn_fs_deltify_revision (svn_fs_t *fs, 01405 svn_revnum_t revision, 01406 apr_pool_t *pool); 01407 01408 01409 /** Set @a *value_p to the value of the property named @a propname on 01410 * revision @a rev in the filesystem @a fs. If @a rev has no property by 01411 * that name, set @a *value_p to zero. Allocate the result in @a pool. 01412 */ 01413 svn_error_t *svn_fs_revision_prop (svn_string_t **value_p, 01414 svn_fs_t *fs, 01415 svn_revnum_t rev, 01416 const char *propname, 01417 apr_pool_t *pool); 01418 01419 01420 /** Set @a *table_p to the entire property list of revision @a rev in 01421 * filesystem @a fs, as an APR hash table allocated in @a pool. The table 01422 * maps <tt>char *</tt> property names to @c svn_string_t * values; the names 01423 * and values are allocated in @a pool. 01424 */ 01425 svn_error_t *svn_fs_revision_proplist (apr_hash_t **table_p, 01426 svn_fs_t *fs, 01427 svn_revnum_t rev, 01428 apr_pool_t *pool); 01429 01430 01431 /** Change a revision's property's value, or add/delete a property. 01432 * 01433 * - @a fs is a filesystem, and @a rev is the revision in that filesystem 01434 * whose property should change. 01435 * - @a name is the name of the property to change. 01436 * - @a VALUE is the new value of the property, or zero if the property should 01437 * be removed altogether. 01438 * 01439 * Note that revision properties are non-historied --- you can change 01440 * them after the revision has been committed. They are not protected 01441 * via transactions. 01442 * 01443 * Do any necessary temporary allocation in @a pool. 01444 */ 01445 svn_error_t *svn_fs_change_rev_prop (svn_fs_t *fs, 01446 svn_revnum_t rev, 01447 const char *name, 01448 const svn_string_t *value, 01449 apr_pool_t *pool); 01450 01451 01452 01453 /* Computing deltas. */ 01454 01455 01456 /** Set @a *stream_p to a pointer to a delta stream that will turn the 01457 * contents of the file @a source into the contents of the file @a target. 01458 * If @a source_root is zero, use a file with zero length as the source. 01459 * 01460 * This function does not compare the two files' properties. 01461 * 01462 * Allocate @a *stream_p, and do any necessary temporary allocation, in 01463 * @a pool. 01464 */ 01465 svn_error_t *svn_fs_get_file_delta_stream (svn_txdelta_stream_t **stream_p, 01466 svn_fs_root_t *source_root, 01467 const char *source_path, 01468 svn_fs_root_t *target_root, 01469 const char *target_path, 01470 apr_pool_t *pool); 01471 01472 01473 01474 /* UUID manipulation. */ 01475 01476 /** Populate @a *uuid with the UUID associated with @a fs. Allocate 01477 @a *uuid in @a pool. */ 01478 svn_error_t *svn_fs_get_uuid (svn_fs_t *fs, 01479 const char **uuid, 01480 apr_pool_t *pool); 01481 01482 01483 /** Associate @a *uuid with @a fs. Use @a pool for any scratchwork. */ 01484 svn_error_t *svn_fs_set_uuid (svn_fs_t *fs, 01485 const char *uuid, 01486 apr_pool_t *pool); 01487 01488 01489 /* Non-historical properties. */ 01490 01491 /* [[Yes, do tell.]] */ 01492 01493 01494 01495 /** @defgroup svn_fs_locks filesystem locks 01496 * @{ 01497 * @since New in 1.2. */ 01498 01499 /** A lock represents one user's exclusive right to modify a path in a 01500 * filesystem. In order to create or destroy a lock, a username must 01501 * be associated with the filesystem's access context (see @c 01502 * svn_fs_access_t). 01503 * 01504 * When a lock is created, a 'lock-token' is returned. The lock-token 01505 * is a unique URI that represents the lock (treated as an opaque 01506 * string by the client), and is required to make further use of the 01507 * lock (including removal of the lock.) A lock-token can also be 01508 * queried to return a svn_lock_t structure that describes the details 01509 * of the lock. 01510 * 01511 * Locks are not secret; anyone can view existing locks in a 01512 * filesystem. Locks are not omnipotent: they can broken and stolen 01513 * by people who don't "own" the lock. (Though admins can tailor a 01514 * custom break/steal policy via libsvn_repos pre-lock hook script.) 01515 * 01516 * Locks can be created with an optional expiration date. If a lock 01517 * has an expiration date, then the act of fetching/reading it might 01518 * cause it to automatically expire, returning either nothing or an 01519 * expiration error (depending on the API). 01520 */ 01521 01522 01523 /** Lock @a path in @a fs, and set @a *lock to a lock 01524 * representing the new lock, allocated in @a pool. 01525 * 01526 * @warning You may prefer to use @a svn_repos_fs_lock instead, 01527 * which see. 01528 * 01529 * @a fs must have a username associated with it (see @c 01530 * svn_fs_access_t), else return @c SVN_ERR_FS_NO_USER. Set the 01531 * 'owner' field in the new lock to the fs username. 01532 * 01533 * @a comment is optional: it's either an xml-escapable UTF8 string 01534 * which describes the lock, or it is @c NULL. 01535 * 01536 * @a is_dav_comment describes whether the comment was created by a 01537 * generic DAV client; only mod_dav_svn's autoversioning feature needs 01538 * to use it. If in doubt, pass 0. 01539 * 01540 * If path is already locked, then return @c SVN_ERR_FS_PATH_ALREADY_LOCKED, 01541 * unless @a steal_lock is true, in which case "steal" the existing 01542 * lock, even if the FS access-context's username does not match the 01543 * current lock's owner: delete the existing lock on @a path, and 01544 * create a new one. 01545 * 01546 * @a token is a lock token such as can be generated using @c 01547 * svn_fs_generate_lock_token (indicating that the caller wants to 01548 * dictate the lock token used), or it is @c NULL (indicating that the 01549 * caller wishes to have a new token generated by this function). If 01550 * @a token is not @c NULL, and represents an existing lock, then @a 01551 * path must match the path associated with that existing lock. 01552 * 01553 * If @a expiration_date is zero, then create a non-expiring lock. 01554 * Else, the lock will expire at @a expiration_date. 01555 * 01556 * If @a current_rev is a valid revnum, then do an out-of-dateness 01557 * check. If the revnum is less than the last-changed-revision of @a 01558 * path (or if @a path doesn't exist in HEAD), return @c 01559 * SVN_ERR_FS_OUT_OF_DATE. 01560 * 01561 * Note: at this time, only files can be locked. 01562 */ 01563 svn_error_t *svn_fs_lock (svn_lock_t **lock, 01564 svn_fs_t *fs, 01565 const char *path, 01566 const char *token, 01567 const char *comment, 01568 svn_boolean_t is_dav_comment, 01569 apr_time_t expiration_date, 01570 svn_revnum_t current_rev, 01571 svn_boolean_t steal_lock, 01572 apr_pool_t *pool); 01573 01574 01575 /** Generate a unique lock-token using @a fs. Return in @a *token, 01576 * allocated in @a pool. 01577 * 01578 * This can be used in to populate lock->token before calling @c 01579 * svn_fs_attach_lock(). 01580 */ 01581 svn_error_t *svn_fs_generate_lock_token (const char **token, 01582 svn_fs_t *fs, 01583 apr_pool_t *pool); 01584 01585 01586 /** Remove the lock on @a path represented by @a token in @a fs. 01587 * 01588 * If @a token doesn't point to a lock, return @c SVN_ERR_FS_BAD_LOCK_TOKEN. 01589 * If @a token points to an expired lock, return @c SVN_ERR_FS_LOCK_EXPIRED. 01590 * If @a fs has no username associated with it, return @c SVN_ERR_FS_NO_USER 01591 * unless @a break_lock is specified. 01592 * 01593 * If @a token points to a lock, but the username of @a fs's access 01594 * context doesn't match the lock's owner, return @c 01595 * SVN_ERR_FS_LOCK_OWNER_MISMATCH. If @a break_lock is true, however, don't 01596 * return error; allow the lock to be "broken" in any case. In the latter 01597 * case, @a token shall be @c NULL. 01598 * 01599 * Use @a pool for temporary allocations. 01600 */ 01601 svn_error_t *svn_fs_unlock (svn_fs_t *fs, 01602 const char *path, 01603 const char *token, 01604 svn_boolean_t break_lock, 01605 apr_pool_t *pool); 01606 01607 01608 /** If @a path is locked in @a fs, set @a *lock to an svn_lock_t which 01609 * represents the lock, allocated in @a pool. 01610 * 01611 * If @a path is not locked, set @a *lock to NULL. 01612 */ 01613 svn_error_t *svn_fs_get_lock (svn_lock_t **lock, 01614 svn_fs_t *fs, 01615 const char *path, 01616 apr_pool_t *pool); 01617 01618 01619 /** The type of a lock discovery callback function. @a baton is the 01620 * value specified in the call to @c svn_fs_get_locks; the filesystem 01621 * passes it through to the callback. @a lock is a lock structure. 01622 * @a pool is a temporary subpool for use by the callback 01623 * implementation -- it is cleared after invocation of the callback. 01624 */ 01625 typedef svn_error_t *(*svn_fs_get_locks_callback_t) (void *baton, 01626 svn_lock_t *lock, 01627 apr_pool_t *pool); 01628 01629 01630 /** Report locks on or below @a path in @a fs using the @a 01631 * get_locks_func / @a get_locks_baton. Use @a pool for necessary 01632 * allocations. 01633 * 01634 * If the @a get_locks_func callback implementation returns an error, 01635 * lock iteration will terminate and that error will be returned by 01636 * this function. 01637 */ 01638 svn_error_t *svn_fs_get_locks (svn_fs_t *fs, 01639 const char *path, 01640 svn_fs_get_locks_callback_t get_locks_func, 01641 void *get_locks_baton, 01642 apr_pool_t *pool); 01643 01644 /** @} */ 01645 01646 /** @since New in 1.2. 01647 * 01648 * Append a textual list of all available FS modules to the stringbuf 01649 * @a output. 01650 */ 01651 svn_error_t *svn_fs_print_modules (svn_stringbuf_t *output, 01652 apr_pool_t *pool); 01653 01654 #ifdef __cplusplus 01655 } 01656 #endif /* __cplusplus */ 01657 01658 #endif /* SVN_FS_H */