svn_fs.h

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