[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: svn commit: r35253 - in trunk/subversion: include libsvn_fs libsvn_fs_base libsvn_fs_base/bdb libsvn_fs_fs libsvn_repos

From: David Glasser <glasser_at_davidglasser.net>
Date: Wed, 14 Jan 2009 16:48:36 -0500

Uh.... is the reply-to for svn@ no longer dev@?

--dave

On Wed, Jan 14, 2009 at 4:48 PM, David Glasser <glasser_at_davidglasser.net> wrote:
> Oh, grr. I got cocky and committed while the BDB tests were still
> running. And doing that just guarantees that it won't work.
>
> The fallback logic in svn_fs_paths_changed2 only tells you the kind of
> the node at the end of the revision, which certainly won't work for
> deletes. This ends up making some tests fail under BDB, but it's
> worse than that.
>
> New plan: get rid of get_all_kinds_and_copyfroms. The new API will
> return some changed-paths which may or may not have kinds and
> copyfroms on them; if they don't, it's the caller's responsibility to
> decide what to do.
>
> --dave
>
> On Wed, Jan 14, 2009 at 4:09 PM, David Glasser <glasser_at_davidglasser.net> wrote:
>> For efficiency reasons, the system has converted the large body of this message into an attachment.
>>
>> ---------- Forwarded message ----------
>> From: glasser_at_tigris.org
>> To: svn_at_subversion.tigris.org
>> Date: Wed, 14 Jan 2009 13:09:17 -0800
>> Subject: svn commit: r35253 - in trunk/subversion: include libsvn_fs libsvn_fs_base libsvn_fs_base/bdb libsvn_fs_fs libsvn_repos
>> Author: glasser
>> Date: Wed Jan 14 13:09:17 2009
>> New Revision: 35253
>>
>> Log:
>> Rev svn_fs_paths_changed to include the node kind and copyfrom
>> information for the changed paths, with a flag controlling whether or
>> not the user *really* wants the information (that is, whether to fetch
>> it even if it isn't "free" with the changed path list).
>>
>> In FSFS, start recording node kinds in the changed paths list for
>> format 4 revisions and for all transactions. (FSFS already stored
>> copyfrom information in all changed paths list.) In BDB, don't (yet)
>> return any of this data unless the I-really-want-it-even-if-it's-slow
>> flag is set.
>>
>> Update svn_repos_replay to use the new API; this means that for the
>> send_delta=False case, replay doesn't need to do any FS touching other
>> than the initial svn_fs_paths_changed2. (Well, and some MD5 lookups,
>> which could probably be removed later.) This can speedup some uses of
>> replay, such as the ChangeCollector in the Python bindings which is
>> used by mailer.py.
>>
>> This is also a first step towards fixing Issue #1967, though I don't
>> personally plan to continue down that road.
>>
>> * subversion/include/svn_fs.h
>> (svn_fs_path_change2_t): Rev with new node_kind and copyfrom_* fields.
>> (svn_fs_path_change_t): Deprecate.
>> (svn_fs_paths_changed2): Rev, returning the new type and taking a
>> new flag.
>> (svn_fs_paths_changed): Deprecate.
>>
>> * subversion/libsvn_fs/fs-loader.c
>> (svn_fs_paths_changed2): New; implements the
>> get_all_kinds_and_copyfroms flag.
>> (svn_fs_paths_changed): Implement in terms of new version.
>>
>> * subversion/libsvn_fs_base/bdb/changes-table.c
>> (fold_change): Use new type; initialize new fields.
>>
>> * subversion/libsvn_fs_base/bdb/changes-table.h
>> (svn_fs_bdb__changes_fetch): Update docstring.
>>
>> * subversion/libsvn_fs_base/tree.c
>> (verify_locks): Use new type.
>>
>> * subversion/libsvn_fs_fs/fs.h
>> (SVN_FS_FS__MIN_KIND_IN_CHANGED_FORMAT): New.
>> (change_t): Add node_kind field.
>>
>> * subversion/libsvn_fs_fs/fs_fs.c
>> (fold_change): Use new type. Use copyfrom_cache purely for its
>> caching-on-rev-root purpose rather than as the only place that
>> copyfrom data is stored (it is now stored inside the changed_ts
>> themselves).
>> (read_change): Read kind from action if it is there.
>> (fetch_all_changes): Don't use a copyfrom_cache unless one is
>> passed in.
>> (svn_fs_fs__txn_changes_fetch): Don't use a copyfrom_cache.
>> (write_change_entry): Use new type. Write the node kind too if
>> requested.
>> (svn_fs_fs__add_change): Use new type. Take node_kind argument.
>> (write_final_changed_path_info): Use new type. Don't use a
>> copyfrom_cache. Check format to see if we should write kinds.
>> (verify_locks): Use new type. Adjust.
>>
>> * subversion/libsvn_fs_fs/fs_fs.h
>> (svn_fs_fs__add_change): Take node_kind argument.
>> (svn_fs_fs__txn_changes_fetch): Don't use a copyfrom_cache.
>>
>> * subversion/libsvn_fs_fs/structure
>> Document storage of node kind in changed paths lists.
>>
>> * subversion/libsvn_fs_fs/tree.c
>> (add_change): Take node_kind argument.
>> (fs_change_node_prop, fs_make_dir, fs_delete_node, copy_helper,
>> fs_make_file, apply_textdelta, apply_text): Pass node kind to
>> add_change.
>> (fs_paths_changed): Update docstring; remove copyfrom_cache from
>> svn_fs_fs__txn_changes_fetch call.
>>
>> * subversion/libsvn_repos/replay.c
>> (add_subdir): Use new type.
>> (path_driver_cb_func): Use new type; replace calls to
>> svn_fs_check_path and svn_fs_copied_from with field references.
>> (svn_repos_replay2): Use new API and type.
>>
>> Modified:
>> trunk/subversion/include/svn_fs.h
>> trunk/subversion/libsvn_fs/fs-loader.c
>> trunk/subversion/libsvn_fs_base/bdb/changes-table.c
>> trunk/subversion/libsvn_fs_base/bdb/changes-table.h
>> trunk/subversion/libsvn_fs_base/tree.c
>> trunk/subversion/libsvn_fs_fs/fs.h
>> trunk/subversion/libsvn_fs_fs/fs_fs.c
>> trunk/subversion/libsvn_fs_fs/fs_fs.h
>> trunk/subversion/libsvn_fs_fs/structure
>> trunk/subversion/libsvn_fs_fs/tree.c
>> trunk/subversion/libsvn_repos/replay.c
>>
>> Modified: trunk/subversion/include/svn_fs.h
>> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/include/svn_fs.h?pathrev=35253&r1=35252&r2=35253
>> ==============================================================================
>> --- trunk/subversion/include/svn_fs.h Wed Jan 14 12:59:58 2009 (r35252)
>> +++ trunk/subversion/include/svn_fs.h Wed Jan 14 13:09:17 2009 (r35253)
>> @@ -1045,7 +1045,42 @@ typedef enum
>>
>> } svn_fs_path_change_kind_t;
>>
>> -/** Change descriptor. */
>> +/** Change descriptor.
>> + *
>> + * @since New in 1.6. */
>> +typedef struct svn_fs_path_change2_t
>> +{
>> + /** node revision id of changed path */
>> + const svn_fs_id_t *node_rev_id;
>> +
>> + /** kind of change */
>> + svn_fs_path_change_kind_t change_kind;
>> +
>> + /** were there text mods? */
>> + svn_boolean_t text_mod;
>> +
>> + /** were there property mods? */
>> + svn_boolean_t prop_mod;
>> +
>> + /** what node kind is the path?
>> + (Note: it is legal for this to be @c svn_node_unknown.) */
>> + svn_node_kind_t node_kind;
>> +
>> + /** Copyfrom revision and path; this is only valid if copyfrom_known
>> + * is true. */
>> + svn_boolean_t copyfrom_known;
>> + svn_revnum_t copyfrom_rev;
>> + const char *copyfrom_path;
>> +
>> +} svn_fs_path_change2_t;
>> +
>> +
>> +/** Similar to @c svn_fs_path_change2_t, but without kind and copyfrom
>> + * information.
>> + *
>> + * @deprecated Provided for backwards compatibility with the 1.5 API.
>> + */
>> +
>> typedef struct svn_fs_path_change_t
>> {
>> /** node revision id of changed path */
>> @@ -1067,10 +1102,29 @@ typedef struct svn_fs_path_change_t
>> *
>> * Allocate and return a hash @a *changed_paths_p containing descriptions
>> * of the paths changed under @a root. The hash is keyed with
>> - * <tt>const char *</tt> paths, and has @c svn_fs_path_change_t * values.
>> + * <tt>const char *</tt> paths, and has @c svn_fs_path_change2_t * values.
>> + * If @a get_all_kinds_and_copyfroms is true, none of the @c node_kind fields
>> + * in the @c svn_fs_path_change2_t * values will be @c svn_node_unknown,
>> + * and all of the @c copyfrom_known fields will be TRUE; otherwise, some
>> + * kind and copyfrom data may be left blank (if fetching it would be
>> + * inefficient).
>> + *
>> * Use @c pool for all allocations, including the hash and its values.
>> */
>> svn_error_t *
>> +svn_fs_paths_changed2(apr_hash_t **changed_paths_p,
>> + svn_fs_root_t *root,
>> + svn_boolean_t get_all_kinds_and_copyfroms,
>> + apr_pool_t *pool);
>> +
>> +
>> +/** Same as svn_fs_paths_changed2(), only with @c svn_fs_path_change_t * values
>> + * in the hash (and thus no kind or copyfrom data).
>> + *
>> + * @deprecated Provided for backward compatibility with the 1.5 API.
>> + */
>> +SVN_DEPRECATED
>> +svn_error_t *
>> svn_fs_paths_changed(apr_hash_t **changed_paths_p,
>> svn_fs_root_t *root,
>> apr_pool_t *pool);
>>
>> Modified: trunk/subversion/libsvn_fs/fs-loader.c
>> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/libsvn_fs/fs-loader.c?pathrev=35253&r1=35252&r2=35253
>> ==============================================================================
>> --- trunk/subversion/libsvn_fs/fs-loader.c Wed Jan 14 12:59:58 2009 (r35252)
>> +++ trunk/subversion/libsvn_fs/fs-loader.c Wed Jan 14 13:09:17 2009 (r35253)
>> @@ -780,10 +780,82 @@ svn_fs_revision_root_revision(svn_fs_roo
>> }
>>
>> svn_error_t *
>> +svn_fs_paths_changed2(apr_hash_t **changed_paths_p, svn_fs_root_t *root,
>> + svn_boolean_t get_all_kinds_and_copyfroms,
>> + apr_pool_t *pool)
>> +{
>> + SVN_ERR(root->vtable->paths_changed(changed_paths_p, root, pool));
>> +
>> + /* If the caller really needs to know all the kinds and copyfroms,
>> + * we'll fill them in, even if this way is slower. */
>> + if (get_all_kinds_and_copyfroms)
>> + {
>> + apr_hash_index_t *hi;
>> + for (hi = apr_hash_first(pool, *changed_paths_p);
>> + hi;
>> + hi = apr_hash_next(hi))
>> + {
>> + const void *key;
>> + const char *path;
>> + void *val;
>> + svn_fs_path_change2_t *change;
>> + apr_hash_this(hi, &key, NULL, &val);
>> + path = key;
>> + change = val;
>> + if (change->node_kind == svn_node_unknown)
>> + {
>> + SVN_ERR(svn_fs_check_path(&(change->node_kind), root, path,
>> + pool));
>> + }
>> + if (! change->copyfrom_known)
>> + {
>> + if (change->change_kind == svn_fs_path_change_add
>> + || change->change_kind == svn_fs_path_change_replace)
>> + {
>> + SVN_ERR(svn_fs_copied_from(&(change->copyfrom_rev),
>> + &(change->copyfrom_path),
>> + root, path, pool));
>> + }
>> + else
>> + {
>> + change->copyfrom_rev = SVN_INVALID_REVNUM;
>> + change->copyfrom_path = NULL;
>> + }
>> + change->copyfrom_known = TRUE;
>> + }
>> + }
>> + }
>> + return SVN_NO_ERROR;
>> +}
>> +
>> +svn_error_t *
>> svn_fs_paths_changed(apr_hash_t **changed_paths_p, svn_fs_root_t *root,
>> apr_pool_t *pool)
>> {
>> - return root->vtable->paths_changed(changed_paths_p, root, pool);
>> + apr_hash_t *changed_paths_new_structs;
>> + apr_hash_index_t *hi;
>> +
>> + SVN_ERR(svn_fs_paths_changed2(&changed_paths_new_structs, root, FALSE, pool));
>> + *changed_paths_p = apr_hash_make(pool);
>> + for (hi = apr_hash_first(pool, changed_paths_new_structs);
>> + hi;
>> + hi = apr_hash_next(hi))
>> + {
>> + const void *vkey;
>> + apr_ssize_t klen;
>> + void *vval;
>> + svn_fs_path_change2_t *val;
>> + svn_fs_path_change_t *change;
>> + apr_hash_this(hi, &vkey, &klen, &vval);
>> + val = vval;
>> + change = apr_palloc(pool, sizeof(*change));
>> + change->node_rev_id = val->node_rev_id;
>> + change->change_kind = val->change_kind;
>> + change->text_mod = val->text_mod;
>> + change->prop_mod = val->prop_mod;
>> + apr_hash_set(*changed_paths_p, vkey, klen, change);
>> + }
>> + return SVN_NO_ERROR;
>> }
>>
>> svn_error_t *
>>
>> Modified: trunk/subversion/libsvn_fs_base/bdb/changes-table.c
>> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/libsvn_fs_base/bdb/changes-table.c?pathrev=35253&r1=35252&r2=35253
>> ==============================================================================
>> --- trunk/subversion/libsvn_fs_base/bdb/changes-table.c Wed Jan 14 12:59:58 2009 (r35252)
>> +++ trunk/subversion/libsvn_fs_base/bdb/changes-table.c Wed Jan 14 13:09:17 2009 (r35253)
>> @@ -116,14 +116,14 @@ svn_fs_bdb__changes_delete(svn_fs_t *fs,
>>
>>
>> /* Merge the internal-use-only CHANGE into a hash of public-FS
>> - svn_fs_path_change_t CHANGES, collapsing multiple changes into a
>> + svn_fs_path_change2_t CHANGES, collapsing multiple changes into a
>> single succinct change per path. */
>> static svn_error_t *
>> fold_change(apr_hash_t *changes,
>> const change_t *change)
>> {
>> apr_pool_t *pool = apr_hash_pool_get(changes);
>> - svn_fs_path_change_t *old_change, *new_change;
>> + svn_fs_path_change2_t *old_change, *new_change;
>> const char *path;
>>
>> if ((old_change = apr_hash_get(changes, change->path, APR_HASH_KEY_STRING)))
>> @@ -223,6 +223,8 @@ fold_change(apr_hash_t *changes,
>> new_change->change_kind = change->kind;
>> new_change->text_mod = change->text_mod;
>> new_change->prop_mod = change->prop_mod;
>> + new_change->node_kind = svn_node_unknown;
>> + new_change->copyfrom_known = FALSE;
>> path = apr_pstrdup(pool, change->path);
>> }
>>
>>
>> Modified: trunk/subversion/libsvn_fs_base/bdb/changes-table.h
>> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/libsvn_fs_base/bdb/changes-table.h?pathrev=35253&r1=35252&r2=35253
>> ==============================================================================
>> --- trunk/subversion/libsvn_fs_base/bdb/changes-table.h Wed Jan 14 12:59:58 2009 (r35252)
>> +++ trunk/subversion/libsvn_fs_base/bdb/changes-table.h Wed Jan 14 13:09:17 2009 (r35253)
>> @@ -63,7 +63,7 @@ svn_error_t *svn_fs_bdb__changes_delete(
>> apr_pool_t *pool);
>>
>> /* Return a hash *CHANGES_P, keyed on const char * paths, and
>> - containing svn_fs_path_change_t * values representing summarized
>> + containing svn_fs_path_change2_t * values representing summarized
>> changed records associated with KEY in FS, as part of TRAIL.
>> Allocate the array and its items in POOL. */
>> svn_error_t *svn_fs_bdb__changes_fetch(apr_hash_t **changes_p,
>>
>> Modified: trunk/subversion/libsvn_fs_base/tree.c
>> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/libsvn_fs_base/tree.c?pathrev=35253&r1=35252&r2=35253
>> ==============================================================================
>> --- trunk/subversion/libsvn_fs_base/tree.c Wed Jan 14 12:59:58 2009 (r35252)
>> +++ trunk/subversion/libsvn_fs_base/tree.c Wed Jan 14 13:09:17 2009 (r35253)
>> @@ -2484,7 +2484,7 @@ verify_locks(const char *txn_name,
>> for (i = 0; i < changed_paths->nelts; i++)
>> {
>> const char *path;
>> - svn_fs_path_change_t *change;
>> + svn_fs_path_change2_t *change;
>> svn_boolean_t recurse = TRUE;
>>
>> svn_pool_clear(subpool);
>>
>> Modified: trunk/subversion/libsvn_fs_fs/fs.h
>> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/libsvn_fs_fs/fs.h?pathrev=35253&r1=35252&r2=35253
>> ==============================================================================
>> --- trunk/subversion/libsvn_fs_fs/fs.h Wed Jan 14 12:59:58 2009 (r35252)
>> +++ trunk/subversion/libsvn_fs_fs/fs.h Wed Jan 14 13:09:17 2009 (r35253)
>> @@ -109,6 +109,9 @@ extern "C" {
>> /* The minimum format number that supports packed shards. */
>> #define SVN_FS_FS__MIN_PACKED_FORMAT 4
>>
>> +/* The minimum format number that stores node kinds in changed-paths lists. */
>> +#define SVN_FS_FS__MIN_KIND_IN_CHANGED_FORMAT 4
>> +
>> /* Private FSFS-specific data shared between all svn_txn_t objects that
>> relate to a particular transaction in a filesystem (as identified
>> by transaction id and filesystem UUID). Objects of this type are
>> @@ -374,6 +377,9 @@ typedef struct
>> svn_boolean_t text_mod;
>> svn_boolean_t prop_mod;
>>
>> + /* Node kind (possibly svn_node_unknown). */
>> + svn_node_kind_t node_kind;
>> +
>> /* Copyfrom revision and path. */
>> svn_revnum_t copyfrom_rev;
>> const char * copyfrom_path;
>>
>> Modified: trunk/subversion/libsvn_fs_fs/fs_fs.c
>> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/libsvn_fs_fs/fs_fs.c?pathrev=35253&r1=35252&r2=35253
>> ==============================================================================
>> --- trunk/subversion/libsvn_fs_fs/fs_fs.c Wed Jan 14 12:59:58 2009 (r35252)
>> +++ trunk/subversion/libsvn_fs_fs/fs_fs.c Wed Jan 14 13:09:17 2009 (r35253)
>> @@ -3615,33 +3615,23 @@ svn_fs_fs__rep_copy(representation_t *re
>> }
>>
>> /* Merge the internal-use-only CHANGE into a hash of public-FS
>> - svn_fs_path_change_t CHANGES, collapsing multiple changes into a
>> + svn_fs_path_change2_t CHANGES, collapsing multiple changes into a
>> single summarical (is that real word?) change per path. Also keep
>> - the COPYFROM_HASH up to date with new adds and replaces. */
>> + the COPYFROM_CACHE up to date with new adds and replaces. */
>> static svn_error_t *
>> fold_change(apr_hash_t *changes,
>> const change_t *change,
>> - apr_hash_t *copyfrom_hash)
>> + apr_hash_t *copyfrom_cache)
>> {
>> apr_pool_t *pool = apr_hash_pool_get(changes);
>> - apr_pool_t *copyfrom_pool = apr_hash_pool_get(copyfrom_hash);
>> - svn_fs_path_change_t *old_change, *new_change;
>> - const char *path, *copyfrom_string, *copyfrom_path = NULL;
>> + svn_fs_path_change2_t *old_change, *new_change;
>> + const char *path = NULL;
>>
>> if ((old_change = apr_hash_get(changes, change->path, APR_HASH_KEY_STRING)))
>> {
>> /* This path already exists in the hash, so we have to merge
>> this change into the already existing one. */
>>
>> - /* Get the existing copyfrom entry for this path. */
>> - copyfrom_string = apr_hash_get(copyfrom_hash, change->path,
>> - APR_HASH_KEY_STRING);
>> -
>> - /* If this entry existed in the copyfrom hash, we don't need to
>> - copy it. */
>> - if (copyfrom_string)
>> - copyfrom_path = change->path;
>> -
>> /* Since the path already exists in the hash, we don't have to
>> dup the allocation for the path itself. */
>> path = change->path;
>> @@ -3680,7 +3670,6 @@ fold_change(apr_hash_t *changes,
>> /* A reset here will simply remove the path change from the
>> hash. */
>> old_change = NULL;
>> - copyfrom_string = NULL;
>> break;
>>
>> case svn_fs_path_change_delete:
>> @@ -3698,7 +3687,8 @@ fold_change(apr_hash_t *changes,
>> old_change->text_mod = change->text_mod;
>> old_change->prop_mod = change->prop_mod;
>> }
>> - copyfrom_string = NULL;
>> + old_change->copyfrom_rev = SVN_INVALID_REVNUM;
>> + old_change->copyfrom_path = NULL;
>> break;
>>
>> case svn_fs_path_change_add:
>> @@ -3711,13 +3701,15 @@ fold_change(apr_hash_t *changes,
>> old_change->text_mod = change->text_mod;
>> old_change->prop_mod = change->prop_mod;
>> if (change->copyfrom_rev == SVN_INVALID_REVNUM)
>> - copyfrom_string = apr_pstrdup(copyfrom_pool, "");
>> + {
>> + old_change->copyfrom_rev = SVN_INVALID_REVNUM;
>> + old_change->copyfrom_path = NULL;
>> + }
>> else
>> {
>> - copyfrom_string = apr_psprintf(copyfrom_pool,
>> - "%ld %s",
>> - change->copyfrom_rev,
>> - change->copyfrom_path);
>> + old_change->copyfrom_rev = change->copyfrom_rev;
>> + old_change->copyfrom_path = apr_pstrdup(pool,
>> + change->copyfrom_path);
>> }
>> break;
>>
>> @@ -3743,34 +3735,49 @@ fold_change(apr_hash_t *changes,
>> new_change->change_kind = change->kind;
>> new_change->text_mod = change->text_mod;
>> new_change->prop_mod = change->prop_mod;
>> + new_change->node_kind = change->node_kind;
>> + /* In FSFS, copyfrom_known is *always* true, since we've always
>> + * stored copyfroms in changed paths lists. */
>> + new_change->copyfrom_known = TRUE;
>> if (change->copyfrom_rev != SVN_INVALID_REVNUM)
>> {
>> - copyfrom_string = apr_psprintf(copyfrom_pool, "%ld %s",
>> - change->copyfrom_rev,
>> - change->copyfrom_path);
>> + new_change->copyfrom_rev = change->copyfrom_rev;
>> + new_change->copyfrom_path = apr_pstrdup(pool, change->copyfrom_path);
>> }
>> else
>> - copyfrom_string = apr_pstrdup(copyfrom_pool, "");
>> + {
>> + new_change->copyfrom_rev = SVN_INVALID_REVNUM;
>> + new_change->copyfrom_path = NULL;
>> + }
>> path = apr_pstrdup(pool, change->path);
>> }
>>
>> /* Add (or update) this path. */
>> apr_hash_set(changes, path, APR_HASH_KEY_STRING, new_change);
>>
>> - /* If copyfrom_path is non-NULL, the key is already present in the
>> - hash, so we don't need to duplicate it in the copyfrom pool. */
>> - if (! copyfrom_path)
>> - {
>> - /* If copyfrom_string is NULL, the hash entry will be deleted,
>> - so we don't need to duplicate the key in the copyfrom
>> - pool. */
>> - copyfrom_path = copyfrom_string ? apr_pstrdup(copyfrom_pool, path)
>> - : path;
>> + /* Update the copyfrom cache, if any. */
>> + if (copyfrom_cache)
>> + {
>> + apr_pool_t *copyfrom_pool = apr_hash_pool_get(copyfrom_cache);
>> + const char *copyfrom_string = NULL, *copyfrom_key = path;
>> + if (new_change)
>> + {
>> + if (SVN_IS_VALID_REVNUM(new_change->copyfrom_rev))
>> + copyfrom_string = apr_psprintf(copyfrom_pool, "%ld %s",
>> + new_change->copyfrom_rev,
>> + new_change->copyfrom_path);
>> + else
>> + copyfrom_string = "";
>> + }
>> + /* We need to allocate a copy of the key in the copyfrom_pool if
>> + * we're not doing a deletion and if it isn't already there. */
>> + if (copyfrom_string && ! apr_hash_get(copyfrom_cache, copyfrom_key,
>> + APR_HASH_KEY_STRING))
>> + copyfrom_key = apr_pstrdup(copyfrom_pool, copyfrom_key);
>> + apr_hash_set(copyfrom_cache, copyfrom_key, APR_HASH_KEY_STRING,
>> + copyfrom_string);
>> }
>>
>> - apr_hash_set(copyfrom_hash, copyfrom_path, APR_HASH_KEY_STRING,
>> - copyfrom_string);
>> -
>> return SVN_NO_ERROR;
>> }
>>
>> @@ -3789,7 +3796,7 @@ read_change(change_t **change_p,
>> char buf[MAX_CHANGE_LINE_LEN];
>> apr_size_t len = sizeof(buf);
>> change_t *change;
>> - char *str, *last_str;
>> + char *str, *last_str, *kind_str;
>> svn_error_t *err;
>>
>> /* Default return value. */
>> @@ -3829,6 +3836,24 @@ read_change(change_t **change_p,
>> return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
>> _("Invalid changes line in rev-file"));
>>
>> + /* Don't bother to check the format number before looking for
>> + * node-kinds: just read them if you find them. */
>> + change->node_kind = svn_node_unknown;
>> + kind_str = strchr(str, '-');
>> + if (kind_str)
>> + {
>> + /* Cap off the end of "str" (the action). */
>> + *kind_str = '\0';
>> + kind_str++;
>> + if (strcmp(kind_str, KIND_FILE) == 0)
>> + change->node_kind = svn_node_file;
>> + else if (strcmp(kind_str, KIND_DIR) == 0)
>> + change->node_kind = svn_node_dir;
>> + else
>> + return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
>> + _("Invalid changes line in rev-file"));
>> + }
>> +
>> if (strcmp(str, ACTION_MODIFY) == 0)
>> {
>> change->kind = svn_fs_path_change_modify;
>> @@ -3945,11 +3970,6 @@ fetch_all_changes(apr_hash_t *changed_pa
>> {
>> change_t *change;
>> apr_pool_t *iterpool = svn_pool_create(pool);
>> - apr_hash_t *my_hash;
>> -
>> - /* If we are passed a NULL copyfrom hash, manufacture one for the
>> - duration of this call. */
>> - my_hash = copyfrom_hash ? copyfrom_hash : apr_hash_make(pool);
>>
>> /* Read in the changes one by one, folding them into our local hash
>> as necessary. */
>> @@ -3958,7 +3978,7 @@ fetch_all_changes(apr_hash_t *changed_pa
>>
>> while (change)
>> {
>> - SVN_ERR(fold_change(changed_paths, change, my_hash));
>> + SVN_ERR(fold_change(changed_paths, change, copyfrom_hash));
>>
>> /* Now, if our change was a deletion or replacement, we have to
>> blow away any changes thus far on paths that are (or, were)
>> @@ -4009,7 +4029,6 @@ svn_error_t *
>> svn_fs_fs__txn_changes_fetch(apr_hash_t **changed_paths_p,
>> svn_fs_t *fs,
>> const char *txn_id,
>> - apr_hash_t *copyfrom_cache,
>> apr_pool_t *pool)
>> {
>> apr_file_t *file;
>> @@ -4018,8 +4037,7 @@ svn_fs_fs__txn_changes_fetch(apr_hash_t
>> SVN_ERR(svn_io_file_open(&file, path_txn_changes(fs, txn_id, pool),
>> APR_READ | APR_BUFFERED, APR_OS_DEFAULT, pool));
>>
>> - SVN_ERR(fetch_all_changes(changed_paths, copyfrom_cache, file, FALSE,
>> - pool));
>> + SVN_ERR(fetch_all_changes(changed_paths, NULL, file, FALSE, pool));
>>
>> SVN_ERR(svn_io_file_close(file, pool));
>>
>> @@ -4641,17 +4659,19 @@ svn_fs_fs__set_entry(svn_fs_t *fs,
>> }
>>
>> /* Write a single change entry, path PATH, change CHANGE, and copyfrom
>> - string COPYFROM, into the file specified by FILE. All temporary
>> + string COPYFROM, into the file specified by FILE. Only include the
>> + node kind field if INCLUDE_NODE_KIND is true. All temporary
>> allocations are in POOL. */
>> static svn_error_t *
>> write_change_entry(apr_file_t *file,
>> const char *path,
>> - svn_fs_path_change_t *change,
>> - const char *copyfrom,
>> + svn_fs_path_change2_t *change,
>> + svn_boolean_t include_node_kind,
>> apr_pool_t *pool)
>> {
>> const char *idstr, *buf;
>> const char *change_string = NULL;
>> + const char *kind_string = "";
>>
>> switch (change->change_kind)
>> {
>> @@ -4680,18 +4700,27 @@ write_change_entry(apr_file_t *file,
>> else
>> idstr = ACTION_RESET;
>>
>> - buf = apr_psprintf(pool, "%s %s %s %s %s\n",
>> - idstr, change_string,
>> + if (include_node_kind)
>> + {
>> + assert(change->node_kind == svn_node_dir
>> + || change->node_kind == svn_node_file);
>> + kind_string = apr_psprintf(pool, "-%s",
>> + change->node_kind == svn_node_dir
>> + ? KIND_DIR : KIND_FILE);
>> + }
>> + buf = apr_psprintf(pool, "%s %s%s %s %s %s\n",
>> + idstr, change_string, kind_string,
>> change->text_mod ? FLAG_TRUE : FLAG_FALSE,
>> change->prop_mod ? FLAG_TRUE : FLAG_FALSE,
>> path);
>>
>> SVN_ERR(svn_io_file_write_full(file, buf, strlen(buf), NULL, pool));
>>
>> - if (copyfrom)
>> + if (SVN_IS_VALID_REVNUM(change->copyfrom_rev))
>> {
>> - SVN_ERR(svn_io_file_write_full(file, copyfrom, strlen(copyfrom),
>> - NULL, pool));
>> + buf = apr_psprintf(pool, "%ld %s", change->copyfrom_rev,
>> + change->copyfrom_path);
>> + SVN_ERR(svn_io_file_write_full(file, buf, strlen(buf), NULL, pool));
>> }
>>
>> return svn_io_file_write_full(file, "\n", 1, NULL, pool);
>> @@ -4705,29 +4734,27 @@ svn_fs_fs__add_change(svn_fs_t *fs,
>> svn_fs_path_change_kind_t change_kind,
>> svn_boolean_t text_mod,
>> svn_boolean_t prop_mod,
>> + svn_node_kind_t node_kind,
>> svn_revnum_t copyfrom_rev,
>> const char *copyfrom_path,
>> apr_pool_t *pool)
>> {
>> apr_file_t *file;
>> - const char *copyfrom;
>> - svn_fs_path_change_t *change = apr_pcalloc(pool, sizeof(*change));
>> + svn_fs_path_change2_t *change = apr_pcalloc(pool, sizeof(*change));
>>
>> SVN_ERR(svn_io_file_open(&file, path_txn_changes(fs, txn_id, pool),
>> APR_APPEND | APR_WRITE | APR_CREATE
>> | APR_BUFFERED, APR_OS_DEFAULT, pool));
>>
>> - if (copyfrom_rev != SVN_INVALID_REVNUM)
>> - copyfrom = apr_psprintf(pool, "%ld %s", copyfrom_rev, copyfrom_path);
>> - else
>> - copyfrom = "";
>> -
>> change->node_rev_id = id;
>> change->change_kind = change_kind;
>> change->text_mod = text_mod;
>> change->prop_mod = prop_mod;
>> + change->node_kind = node_kind;
>> + change->copyfrom_rev = copyfrom_rev;
>> + change->copyfrom_path = apr_pstrdup(pool, copyfrom_path);
>>
>> - SVN_ERR(write_change_entry(file, path, change, copyfrom, pool));
>> + SVN_ERR(write_change_entry(file, path, change, TRUE, pool));
>>
>> return svn_io_file_close(file, pool);
>> }
>> @@ -5353,16 +5380,17 @@ write_final_changed_path_info(apr_off_t
>> const char *txn_id,
>> apr_pool_t *pool)
>> {
>> - const char *copyfrom;
>> - apr_hash_t *changed_paths, *copyfrom_cache = apr_hash_make(pool);
>> + apr_hash_t *changed_paths;
>> apr_off_t offset;
>> apr_hash_index_t *hi;
>> apr_pool_t *iterpool = svn_pool_create(pool);
>> + fs_fs_data_t *ffd = fs->fsap_data;
>> + svn_boolean_t include_node_kinds =
>> + ffd->format >= SVN_FS_FS__MIN_KIND_IN_CHANGED_FORMAT;
>>
>> SVN_ERR(get_file_offset(&offset, file, pool));
>>
>> - SVN_ERR(svn_fs_fs__txn_changes_fetch(&changed_paths, fs, txn_id,
>> - copyfrom_cache, pool));
>> + SVN_ERR(svn_fs_fs__txn_changes_fetch(&changed_paths, fs, txn_id, pool));
>>
>> /* Iterate through the changed paths one at a time, and convert the
>> temporary node-id into a permanent one for each change entry. */
>> @@ -5370,7 +5398,7 @@ write_final_changed_path_info(apr_off_t
>> {
>> node_revision_t *noderev;
>> const svn_fs_id_t *id;
>> - svn_fs_path_change_t *change;
>> + svn_fs_path_change2_t *change;
>> const void *key;
>> void *val;
>>
>> @@ -5394,11 +5422,9 @@ write_final_changed_path_info(apr_off_t
>> change->node_rev_id = noderev->id;
>> }
>>
>> - /* Find the cached copyfrom information. */
>> - copyfrom = apr_hash_get(copyfrom_cache, key, APR_HASH_KEY_STRING);
>> -
>> /* Write out the new entry into the final rev-file. */
>> - SVN_ERR(write_change_entry(file, key, change, copyfrom, iterpool));
>> + SVN_ERR(write_change_entry(file, key, change, include_node_kinds,
>> + iterpool));
>> }
>>
>> svn_pool_destroy(iterpool);
>> @@ -5508,7 +5534,7 @@ verify_locks(svn_fs_t *fs,
>> int i;
>>
>> /* Fetch the changes for this transaction. */
>> - SVN_ERR(svn_fs_fs__txn_changes_fetch(&changes, fs, txn_name, NULL, pool));
>> + SVN_ERR(svn_fs_fs__txn_changes_fetch(&changes, fs, txn_name, pool));
>>
>> /* Make an array of the changed paths, and sort them depth-first-ily. */
>> changed_paths = apr_array_make(pool, apr_hash_count(changes) + 1,
>> @@ -5528,7 +5554,7 @@ verify_locks(svn_fs_t *fs,
>> for (i = 0; i < changed_paths->nelts; i++)
>> {
>> const char *path;
>> - svn_fs_path_change_t *change;
>> + svn_fs_path_change2_t *change;
>> svn_boolean_t recurse = TRUE;
>>
>> svn_pool_clear(subpool);
>>
>> Modified: trunk/subversion/libsvn_fs_fs/fs_fs.h
>> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/libsvn_fs_fs/fs_fs.h?pathrev=35253&r1=35252&r2=35253
>> ==============================================================================
>> --- trunk/subversion/libsvn_fs_fs/fs_fs.h Wed Jan 14 12:59:58 2009 (r35252)
>> +++ trunk/subversion/libsvn_fs_fs/fs_fs.h Wed Jan 14 13:09:17 2009 (r35253)
>> @@ -270,6 +270,7 @@ svn_error_t *svn_fs_fs__add_change(svn_f
>> svn_fs_path_change_kind_t change_kind,
>> svn_boolean_t text_mod,
>> svn_boolean_t prop_mod,
>> + svn_node_kind_t node_kind,
>> svn_revnum_t copyfrom_rev,
>> const char *copyfrom_path,
>> apr_pool_t *pool);
>> @@ -376,13 +377,11 @@ svn_error_t *svn_fs_fs__delete_node_revi
>>
>>
>> /* Find the paths which were changed in transaction TXN_ID of
>> - filesystem FS and store them in *CHANGED_PATHS_P. Cached copyfrom
>> - information will be stored in COPYFROM_CACHE if it is non-NULL.
>> + filesystem FS and store them in *CHANGED_PATHS_P.
>> Get any temporary allocations from POOL. */
>> svn_error_t *svn_fs_fs__txn_changes_fetch(apr_hash_t **changes,
>> svn_fs_t *fs,
>> const char *txn_id,
>> - apr_hash_t *copyfrom_cache,
>> apr_pool_t *pool);
>>
>>
>>
>> Modified: trunk/subversion/libsvn_fs_fs/structure
>> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/libsvn_fs_fs/structure?pathrev=35253&r1=35252&r2=35253
>> ==============================================================================
>> --- trunk/subversion/libsvn_fs_fs/structure Wed Jan 14 12:59:58 2009 (r35252)
>> +++ trunk/subversion/libsvn_fs_fs/structure Wed Jan 14 13:09:17 2009 (r35253)
>> @@ -166,6 +166,10 @@ Mergeinfo metadata:
>> Format 3-4: minfo-here and minfo-count node-revision fields are
>> maintained. svn_fs_get_mergeinfo works.
>>
>> +Revision changed paths list:
>> + Format 1-3: Does not contain the node's kind.
>> + Format 4: Contains the node's kind.
>> +
>>
>> Filesystem format options
>> -------------------------
>> @@ -381,6 +385,10 @@ of the deleted node-rev, and <text-mod>
>> the node-rev's copyfrom information if it has any; if it does not, the
>> second line is blank.
>>
>> +Starting with FS format 4, <action> may contain the kind ("file" or
>> +"dir") of the node, after a hyphen; for example, an added directory
>> +may be represented as "add-dir".
>> +
>> At the very end of a rev file is a pair of lines containing
>> "\n<root-offset> <cp-offset>\n", where <root-offset> is the offset of
>> the root directory node revision and <cp-offset> is the offset of the
>> @@ -433,7 +441,8 @@ the changed-path entries in a rev file,
>> may both be "reset" (in which case <text-mod> and <prop-mod> are both
>> always "false") to indicate that all changes to a path should be
>> considered undone. Reset entries are only used during the final merge
>> -phase of a transaction.
>> +phase of a transaction. Actions in the "changes" file always contain
>> +a node kind, even if the FS format is older than format 4.
>>
>> The node-rev files have the same format as node-revs in a revision
>> file, except that the "text" and "props" fields are augmented as
>>
>> Modified: trunk/subversion/libsvn_fs_fs/tree.c
>> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/libsvn_fs_fs/tree.c?pathrev=35253&r1=35252&r2=35253
>> ==============================================================================
>> --- trunk/subversion/libsvn_fs_fs/tree.c Wed Jan 14 12:59:58 2009 (r35252)
>> +++ trunk/subversion/libsvn_fs_fs/tree.c Wed Jan 14 13:09:17 2009 (r35253)
>> @@ -846,6 +846,7 @@ add_change(svn_fs_t *fs,
>> svn_fs_path_change_kind_t change_kind,
>> svn_boolean_t text_mod,
>> svn_boolean_t prop_mod,
>> + svn_node_kind_t node_kind,
>> svn_revnum_t copyfrom_rev,
>> const char *copyfrom_path,
>> apr_pool_t *pool)
>> @@ -853,7 +854,7 @@ add_change(svn_fs_t *fs,
>> return svn_fs_fs__add_change(fs, txn_id,
>> svn_fs__canonicalize_abspath(path, pool),
>> noderev_id, change_kind, text_mod, prop_mod,
>> - copyfrom_rev, copyfrom_path,
>> + node_kind, copyfrom_rev, copyfrom_path,
>> pool);
>> }
>>
>> @@ -1091,8 +1092,9 @@ fs_change_node_prop(svn_fs_root_t *root,
>> /* Make a record of this modification in the changes table. */
>> return add_change(root->fs, txn_id, path,
>> svn_fs_fs__dag_get_id(parent_path->node),
>> - svn_fs_path_change_modify, FALSE, TRUE, SVN_INVALID_REVNUM,
>> - NULL, pool);
>> + svn_fs_path_change_modify, FALSE, TRUE,
>> + svn_fs_fs__dag_node_kind(parent_path->node),
>> + SVN_INVALID_REVNUM, NULL, pool);
>> }
>>
>>
>> @@ -1881,8 +1883,8 @@ fs_make_dir(svn_fs_root_t *root,
>>
>> /* Make a record of this modification in the changes table. */
>> return add_change(root->fs, txn_id, path, svn_fs_fs__dag_get_id(sub_dir),
>> - svn_fs_path_change_add, FALSE, FALSE, SVN_INVALID_REVNUM,
>> - NULL, pool);
>> + svn_fs_path_change_add, FALSE, FALSE, svn_node_dir,
>> + SVN_INVALID_REVNUM, NULL, pool);
>> }
>>
>>
>> @@ -1896,11 +1898,13 @@ fs_delete_node(svn_fs_root_t *root,
>> parent_path_t *parent_path;
>> const char *txn_id = root->txn;
>> apr_int64_t mergeinfo_count;
>> + svn_node_kind_t node_kind;
>>
>> if (! root->is_txn_root)
>> return SVN_FS__NOT_TXN(root);
>>
>> SVN_ERR(open_path(&parent_path, root, path, 0, txn_id, pool));
>> + node_kind = svn_fs_fs__dag_node_kind(parent_path->node);
>>
>> /* We can't remove the root of the filesystem. */
>> if (! parent_path->parent)
>> @@ -1936,7 +1940,7 @@ fs_delete_node(svn_fs_root_t *root,
>> /* Make a record of this modification in the changes table. */
>> return add_change(root->fs, txn_id, path,
>> svn_fs_fs__dag_get_id(parent_path->node),
>> - svn_fs_path_change_delete, FALSE, FALSE,
>> + svn_fs_path_change_delete, FALSE, FALSE, node_kind,
>> SVN_INVALID_REVNUM, NULL, pool);
>> }
>>
>> @@ -2076,6 +2080,7 @@ copy_helper(svn_fs_root_t *from_root,
>> SVN_ERR(get_dag(&new_node, to_root, to_path, pool));
>> SVN_ERR(add_change(to_root->fs, txn_id, to_path,
>> svn_fs_fs__dag_get_id(new_node), kind, FALSE, FALSE,
>> + svn_fs_fs__dag_node_kind(from_node),
>> from_root->rev, from_canonpath, pool));
>> }
>> else
>> @@ -2229,8 +2234,8 @@ fs_make_file(svn_fs_root_t *root,
>>
>> /* Make a record of this modification in the changes table. */
>> return add_change(root->fs, txn_id, path, svn_fs_fs__dag_get_id(child),
>> - svn_fs_path_change_add, TRUE, FALSE, SVN_INVALID_REVNUM,
>> - NULL, pool);
>> + svn_fs_path_change_add, TRUE, FALSE, svn_node_file,
>> + SVN_INVALID_REVNUM, NULL, pool);
>> }
>>
>>
>> @@ -2475,8 +2480,8 @@ apply_textdelta(void *baton, apr_pool_t
>> /* Make a record of this modification in the changes table. */
>> return add_change(tb->root->fs, txn_id, tb->path,
>> svn_fs_fs__dag_get_id(tb->node),
>> - svn_fs_path_change_modify, TRUE, FALSE, SVN_INVALID_REVNUM,
>> - NULL, pool);
>> + svn_fs_path_change_modify, TRUE, FALSE, svn_node_file,
>> + SVN_INVALID_REVNUM, NULL, pool);
>> }
>>
>>
>> @@ -2619,8 +2624,8 @@ apply_text(void *baton, apr_pool_t *pool
>> /* Make a record of this modification in the changes table. */
>> return add_change(tb->root->fs, txn_id, tb->path,
>> svn_fs_fs__dag_get_id(tb->node),
>> - svn_fs_path_change_modify, TRUE, FALSE, SVN_INVALID_REVNUM,
>> - NULL, pool);
>> + svn_fs_path_change_modify, TRUE, FALSE, svn_node_file,
>> + SVN_INVALID_REVNUM, NULL, pool);
>> }
>>
>>
>> @@ -2725,7 +2730,7 @@ fs_get_file_delta_stream(svn_txdelta_str
>>
>> /* Set *CHANGED_PATHS_P to a newly allocated hash containing
>> descriptions of the paths changed under ROOT. The hash is keyed
>> - with const char * paths an dhas svn_fs_path_change_t * values. Use
>> + with const char * paths and has svn_fs_path_change2_t * values. Use
>> POOL for all allocations. */
>> static svn_error_t *
>> fs_paths_changed(apr_hash_t **changed_paths_p,
>> @@ -2734,7 +2739,7 @@ fs_paths_changed(apr_hash_t **changed_pa
>> {
>> if (root->is_txn_root)
>> return svn_fs_fs__txn_changes_fetch(changed_paths_p, root->fs, root->txn,
>> - NULL, pool);
>> + pool);
>> else
>> {
>> fs_rev_root_data_t *frd = root->fsap_data;
>>
>> Modified: trunk/subversion/libsvn_repos/replay.c
>> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/libsvn_repos/replay.c?pathrev=35253&r1=35252&r2=35253
>> ==============================================================================
>> --- trunk/subversion/libsvn_repos/replay.c Wed Jan 14 12:59:58 2009 (r35252)
>> +++ trunk/subversion/libsvn_repos/replay.c Wed Jan 14 13:09:17 2009 (r35253)
>> @@ -191,7 +191,7 @@ add_subdir(svn_fs_root_t *source_root,
>>
>> for (hi = apr_hash_first(pool, dirents); hi; hi = apr_hash_next(hi))
>> {
>> - svn_fs_path_change_t *change;
>> + svn_fs_path_change2_t *change;
>> svn_boolean_t readable = TRUE;
>> svn_fs_dirent_t *dent;
>> const char *new_path;
>> @@ -316,13 +316,11 @@ path_driver_cb_func(void **dir_baton,
>> const svn_delta_editor_t *editor = cb->editor;
>> void *edit_baton = cb->edit_baton;
>> svn_fs_root_t *root = cb->root;
>> - svn_fs_path_change_t *change;
>> + svn_fs_path_change2_t *change;
>> svn_boolean_t do_add = FALSE, do_delete = FALSE;
>> - svn_node_kind_t kind;
>> void *file_baton = NULL;
>> - const char *copyfrom_path = NULL;
>> - const char *real_copyfrom_path = NULL;
>> svn_revnum_t copyfrom_rev;
>> + const char *copyfrom_path;
>> svn_boolean_t src_readable = TRUE;
>> svn_fs_root_t *source_root = cb->compare_root;
>> const char *source_path = source_root ? path : NULL;
>> @@ -373,23 +371,23 @@ path_driver_cb_func(void **dir_baton,
>> SVN_ERR(editor->delete_entry(path, SVN_INVALID_REVNUM,
>> parent_baton, pool));
>>
>> - /* Fetch the node kind if it makes sense to do so. */
>> - if (! do_delete || do_add)
>> - {
>> - SVN_ERR(svn_fs_check_path(&kind, root, path, pool));
>> - if ((kind != svn_node_dir) && (kind != svn_node_file))
>> - return svn_error_createf
>> - (SVN_ERR_FS_NOT_FOUND, NULL,
>> - _("Filesystem path '%s' is neither a file nor a directory"), path);
>> - }
>> + if ((change->node_kind != svn_node_dir) &&
>> + (change->node_kind != svn_node_file))
>> + return svn_error_createf
>> + (SVN_ERR_FS_NOT_FOUND, NULL,
>> + _("Filesystem path '%s' is neither a file nor a directory"), path);
>>
>> /* Handle any adds/opens. */
>> if (do_add)
>> {
>> svn_fs_root_t *copyfrom_root = NULL;
>> /* Was this node copied? */
>> - SVN_ERR(svn_fs_copied_from(&copyfrom_rev, &copyfrom_path,
>> - root, path, pool));
>> + if (! change->copyfrom_known)
>> + return svn_error_createf
>> + (SVN_ERR_FS_NOT_FOUND, NULL,
>> + _("Filesystem path '%s' does not know if it is copied"), path);
>> + copyfrom_rev = change->copyfrom_rev;
>> + copyfrom_path = change->copyfrom_path;
>>
>> if (copyfrom_path && SVN_IS_VALID_REVNUM(copyfrom_rev))
>> {
>> @@ -405,8 +403,6 @@ path_driver_cb_func(void **dir_baton,
>> }
>> }
>>
>> - /* Save away the copyfrom path in case we null it out below. */
>> - real_copyfrom_path = copyfrom_path;
>> /* If we have a copyfrom path, and we can't read it or we're just
>> ignoring it, or the copyfrom rev is prior to the low water mark
>> then we just null them out and do a raw add with no history at
>> @@ -422,15 +418,15 @@ path_driver_cb_func(void **dir_baton,
>> }
>>
>> /* Do the right thing based on the path KIND. */
>> - if (kind == svn_node_dir)
>> + if (change->node_kind == svn_node_dir)
>> {
>> /* If this is a copy, but we can't represent it as such,
>> then we just do a recursive add of the source path
>> contents. */
>> - if (real_copyfrom_path && ! copyfrom_path)
>> + if (change->copyfrom_path && ! copyfrom_path)
>> {
>> SVN_ERR(add_subdir(copyfrom_root, root, editor, edit_baton,
>> - path, parent_baton, real_copyfrom_path,
>> + path, parent_baton, change->copyfrom_path,
>> cb->authz_read_func, cb->authz_read_baton,
>> cb->changed_paths, pool, dir_baton));
>> }
>> @@ -453,7 +449,7 @@ path_driver_cb_func(void **dir_baton,
>> /* If it is a directory, make sure descendants get the correct
>> delta source by remembering that we are operating inside a
>> (possibly nested) copy operation. */
>> - if (kind == svn_node_dir)
>> + if (change->node_kind == svn_node_dir)
>> {
>> struct copy_info *info = &APR_ARRAY_PUSH(cb->copies,
>> struct copy_info);
>> @@ -473,7 +469,7 @@ path_driver_cb_func(void **dir_baton,
>> /* If an ancestor is added with history, we need to forget about
>> that here, go on with life and repeat all the mistakes of our
>> past... */
>> - if (kind == svn_node_dir && cb->copies->nelts > 0)
>> + if (change->node_kind == svn_node_dir && cb->copies->nelts > 0)
>> {
>> struct copy_info *info = &APR_ARRAY_PUSH(cb->copies,
>> struct copy_info);
>> @@ -489,7 +485,7 @@ path_driver_cb_func(void **dir_baton,
>> {
>> /* Do the right thing based on the path KIND (and the presence
>> of a PARENT_BATON). */
>> - if (kind == svn_node_dir)
>> + if (change->node_kind == svn_node_dir)
>> {
>> if (parent_baton)
>> {
>> @@ -560,10 +556,10 @@ path_driver_cb_func(void **dir_baton,
>> for (i = 0; i < prop_diffs->nelts; ++i)
>> {
>> svn_prop_t *pc = &APR_ARRAY_IDX(prop_diffs, i, svn_prop_t);
>> - if (kind == svn_node_dir)
>> + if (change->node_kind == svn_node_dir)
>> SVN_ERR(editor->change_dir_prop(*dir_baton, pc->name,
>> pc->value, pool));
>> - else if (kind == svn_node_file)
>> + else if (change->node_kind == svn_node_file)
>> SVN_ERR(editor->change_file_prop(file_baton, pc->name,
>> pc->value, pool));
>> }
>> @@ -572,10 +568,10 @@ path_driver_cb_func(void **dir_baton,
>> {
>> /* Just do a dummy prop change to signal that there are *any*
>> propmods. */
>> - if (kind == svn_node_dir)
>> + if (change->node_kind == svn_node_dir)
>> SVN_ERR(editor->change_dir_prop(*dir_baton, "", NULL,
>> pool));
>> - else if (kind == svn_node_file)
>> + else if (change->node_kind == svn_node_file)
>> SVN_ERR(editor->change_file_prop(file_baton, "", NULL,
>> pool));
>> }
>> @@ -587,8 +583,8 @@ path_driver_cb_func(void **dir_baton,
>> aren't allowed to see" case since otherwise the caller will
>> have no way to actually get the new file's contents, which
>> they are apparently allowed to see. */
>> - if (kind == svn_node_file
>> - && (change->text_mod || (real_copyfrom_path && ! copyfrom_path)))
>> + if (change->node_kind == svn_node_file
>> + && (change->text_mod || (change->copyfrom_path && ! copyfrom_path)))
>> {
>> svn_txdelta_window_handler_t delta_handler;
>> void *delta_handler_baton;
>> @@ -659,8 +655,9 @@ svn_repos_replay2(svn_fs_root_t *root,
>> struct path_driver_cb_baton cb_baton;
>> int base_path_len;
>>
>> - /* Fetch the paths changed under ROOT. */
>> - SVN_ERR(svn_fs_paths_changed(&fs_changes, root, pool));
>> + /* Fetch the paths changed under ROOT; we'll need the kinds and
>> + * copyfrom data. */
>> + SVN_ERR(svn_fs_paths_changed2(&fs_changes, root, TRUE, pool));
>>
>> if (! base_path)
>> base_path = "";
>> @@ -680,7 +677,7 @@ svn_repos_replay2(svn_fs_root_t *root,
>> void *val;
>> apr_ssize_t keylen;
>> const char *path;
>> - svn_fs_path_change_t *change;
>> + svn_fs_path_change2_t *change;
>> svn_boolean_t allowed = TRUE;
>>
>> apr_hash_this(hi, &key, &keylen, &val);
>>
>>
>
>
>
> --
> glasser_at_davidglasser.net | langtonlabs.org | flickr.com/photos/glasser/
>

-- 
glasser_at_davidglasser.net | langtonlabs.org | flickr.com/photos/glasser/
Received on 2009-01-14 22:48:59 CET

This is an archived mail posted to the Subversion Dev mailing list.