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