Index: subversion/svn/cl.h =================================================================== --- subversion/svn/cl.h (revision 932402) +++ subversion/svn/cl.h (working copy) @@ -388,7 +388,7 @@ */ svn_error_t * svn_cl__print_status(const char *path, - const svn_wc_status2_t *status, + const svn_wc_status3_t *status, svn_boolean_t detailed, svn_boolean_t show_last_committed, svn_boolean_t skip_unrecognized, @@ -403,7 +403,7 @@ allocations. */ svn_error_t * svn_cl__print_status_xml(const char *path, - const svn_wc_status2_t *status, + const svn_wc_status3_t *status, apr_pool_t *pool); Index: subversion/svn/status.c =================================================================== --- subversion/svn/status.c (revision 932402) +++ subversion/svn/status.c (working copy) @@ -62,7 +62,7 @@ /* Return the single character representation of the switched column status. */ static char -generate_switch_column_code(const svn_wc_status2_t *status) +generate_switch_column_code(const svn_wc_status3_t *status) { if (status->switched) return 'S'; @@ -104,7 +104,7 @@ svn_boolean_t detailed, svn_boolean_t show_last_committed, svn_boolean_t repos_locks, - const svn_wc_status2_t *status, + const svn_wc_status3_t *status, unsigned int *text_conflicts, unsigned int *prop_conflicts, unsigned int *tree_conflicts, @@ -249,7 +249,7 @@ svn_error_t * svn_cl__print_status_xml(const char *path, - const svn_wc_status2_t *status, + const svn_wc_status3_t *status, apr_pool_t *pool) { svn_stringbuf_t *sb = svn_stringbuf_create("", pool); @@ -369,7 +369,7 @@ /* Called by status-cmd.c */ svn_error_t * svn_cl__print_status(const char *path, - const svn_wc_status2_t *status, + const svn_wc_status3_t *status, svn_boolean_t detailed, svn_boolean_t show_last_committed, svn_boolean_t skip_unrecognized, Index: subversion/svn/status-cmd.c =================================================================== --- subversion/svn/status-cmd.c (revision 932402) +++ subversion/svn/status-cmd.c (working copy) @@ -71,7 +71,7 @@ struct status_cache { const char *path; - svn_wc_status2_t *status; + svn_wc_status3_t *status; }; /* Print conflict stats accumulated in status baton SB. @@ -140,7 +140,7 @@ static svn_error_t * print_status_normal_or_xml(void *baton, const char *path, - const svn_wc_status2_t *status, + const svn_wc_status3_t *status, apr_pool_t *pool) { struct status_baton *sb = baton; @@ -163,7 +163,7 @@ static svn_error_t * print_status(void *baton, const char *path, - const svn_wc_status2_t *status, + const svn_wc_status3_t *status, apr_pool_t *pool) { struct status_baton *sb = baton; @@ -178,7 +178,7 @@ const char *cl_key = apr_pstrdup(sb->cl_pool, status->entry->changelist); struct status_cache *scache = apr_pcalloc(sb->cl_pool, sizeof(*scache)); scache->path = apr_pstrdup(sb->cl_pool, path); - scache->status = svn_wc_dup_status2(status, sb->cl_pool); + scache->status = svn_wc_dup_status3(status, sb->cl_pool); path_array = apr_hash_get(sb->cached_changelists, cl_key, APR_HASH_KEY_STRING); Index: subversion/include/svn_wc.h =================================================================== --- subversion/include/svn_wc.h (revision 932402) +++ subversion/include/svn_wc.h (working copy) @@ -3520,6 +3520,113 @@ svn_wc_status_incomplete }; +typedef struct svn_wc_status3_t +{ + /** Can be @c NULL if not under version control. */ + const svn_wc_entry_t *entry; + + /** The status of the entry itself, including its text if it is a file. */ + enum svn_wc_status_kind text_status; + + /** The status of the entry's properties. */ + enum svn_wc_status_kind prop_status; + + /** a directory can be 'locked' if a working copy update was interrupted. */ + svn_boolean_t locked; + + /** a file or directory can be 'copied' if it's scheduled for + * addition-with-history (or part of a subtree that is scheduled as such.). + */ + svn_boolean_t copied; + + /** a file or directory can be 'switched' if the switch command has been + * used. If this is TRUE, then file_external will be FALSE. + */ + svn_boolean_t switched; + + /** The entry's text status in the repository. */ + enum svn_wc_status_kind repos_text_status; + + /** The entry's property status in the repository. */ + enum svn_wc_status_kind repos_prop_status; + + /** The entry's lock in the repository, if any. */ + svn_lock_t *repos_lock; + + /** Set to the URI (actual or expected) of the item. + * @since New in 1.3 + */ + const char *url; + + /** + * @defgroup svn_wc_status_ood WC out-of-date info from the repository + * @{ + * + * When the working copy item is out-of-date compared to the + * repository, the following fields represent the state of the + * youngest revision of the item in the repository. If the working + * copy is not out of date, the fields are initialized as described + * below. + */ + + /** Set to the youngest committed revision, or #SVN_INVALID_REVNUM + * if not out of date. + * @since New in 1.3 + */ + svn_revnum_t ood_last_cmt_rev; + + /** Set to the most recent commit date, or @c 0 if not out of date. + * @since New in 1.3 + */ + apr_time_t ood_last_cmt_date; + + /** Set to the node kind of the youngest commit, or #svn_node_none + * if not out of date. + * @since New in 1.3 + */ + svn_node_kind_t ood_kind; + + /** Set to the user name of the youngest commit, or @c NULL if not + * out of date or non-existent. Because a non-existent @c + * svn:author property has the same behavior as an out-of-date + * working copy, examine @c ood_last_cmt_rev to determine whether + * the working copy is out of date. + * @since New in 1.3 + */ + const char *ood_last_cmt_author; + + /** @} */ + + /** Non-NULL if the entry is the victim of a tree conflict. + * @since New in 1.6 + */ + svn_wc_conflict_description_t *tree_conflict; + + /** If the item is a file that was added to the working copy with an + * svn:externals; if file_external is TRUE, then switched is always + * FALSE. + * @since New in 1.6 + */ + svn_boolean_t file_external; + + /** The actual status of the text compared to the pristine base of the + * file. This value isn't masked by other working copy statuses. + * @c pristine_text_status is #svn_wc_status_none if this value was + * not calculated during the status walk. + * @since New in 1.6 + */ + enum svn_wc_status_kind pristine_text_status; + + /** The actual status of the properties compared to the pristine base of + * the node. This value isn't masked by other working copy statuses. + * @c pristine_prop_status is #svn_wc_status_none if this value was + * not calculated during the status walk. + * @since New in 1.6 + */ + enum svn_wc_status_kind pristine_prop_status; + + /* NOTE! Please update svn_wc_dup_status3() when adding new fields here. */ +} svn_wc_status3_t; /** * Structure for holding the "status" of a working copy item. * @@ -3531,7 +3638,7 @@ * versions. Therefore, to preserve binary compatibility, users * should not directly allocate structures of this type. * - * @since New in 1.2. + * @deprecated Provided for backward compatibility with the 1.2 API. */ typedef struct svn_wc_status2_t { @@ -3681,13 +3788,22 @@ } svn_wc_status_t; - /** * Return a deep copy of the @a orig_stat status structure, allocated * in @a pool. * - * @since New in 1.2. + * @since New in 1.7. */ +svn_wc_status3_t * +svn_wc_dup_status3(const svn_wc_status3_t *orig_stat, + apr_pool_t *pool); + +/** + * Same as svn_wc_dup_status2(), but for older svn_wc_status_t structures. + * + * @deprecated Provided for backward compatibility with the 1.2 API. + */ +SVN_DEPRECATED svn_wc_status2_t * svn_wc_dup_status2(const svn_wc_status2_t *orig_stat, apr_pool_t *pool); @@ -3732,7 +3848,7 @@ * @since New in 1.7. */ svn_error_t * -svn_wc_status3(svn_wc_status2_t **status, +svn_wc_status3(svn_wc_status3_t **status, svn_wc_context_t *wc_ctx, const char *local_abspath, apr_pool_t *result_pool, @@ -3784,7 +3900,7 @@ */ typedef svn_error_t *(*svn_wc_status_func4_t)(void *baton, const char *local_abspath, - const svn_wc_status2_t *status, + const svn_wc_status3_t *status, apr_pool_t *scratch_pool); /** @@ -3821,7 +3937,7 @@ /** * Walk the working copy status of @a local_abspath using @a wc_ctx, by - * creating #svn_wc_status2_t structures and sending these through + * creating #svn_wc_status3_t structures and sending these through * @a status_func / @a status_baton. * * * Assuming the target is a directory, then: @@ -3881,7 +3997,7 @@ /** * Set @a *editor and @a *edit_baton to an editor that generates - * #svn_wc_status2_t structures and sends them through @a status_func / + * #svn_wc_status3_t structures and sends them through @a status_func / * @a status_baton. @a anchor_abspath is a working copy directory * directory which will be used as the root of our editor. If @a * target_basename is not "", it represents a node in the @a anchor_abspath Index: subversion/include/private/svn_wc_private.h =================================================================== --- subversion/include/private/svn_wc_private.h (revision 932402) +++ subversion/include/private/svn_wc_private.h (working copy) @@ -130,7 +130,7 @@ * svn_wc_get_status_editor4(). */ svn_boolean_t -svn_wc__is_sendable_status(const svn_wc_status2_t *status, +svn_wc__is_sendable_status(const svn_wc_status3_t *status, svn_boolean_t no_ignore, svn_boolean_t get_all); Index: subversion/libsvn_wc/deprecated.c =================================================================== --- subversion/libsvn_wc/deprecated.c (revision 932402) +++ subversion/libsvn_wc/deprecated.c (working copy) @@ -2230,13 +2230,15 @@ static svn_error_t * status4_wrapper_func(void *baton, const char *local_abspath, - const svn_wc_status2_t *status, + const svn_wc_status3_t *status, apr_pool_t *scratch_pool) { struct status4_wrapper_baton *swb = baton; - svn_wc_status2_t *dup = svn_wc_dup_status2(status, scratch_pool); + svn_wc_status2_t *dup; const char *path = local_abspath; + dup = (svn_wc_status2_t *) svn_wc_dup_status3(status, scratch_pool); + if (swb->anchor_abspath != NULL) { path = svn_dirent_join( @@ -2468,6 +2470,37 @@ return SVN_NO_ERROR; } +svn_wc_status2_t * +svn_wc_dup_status2(const svn_wc_status2_t *orig_stat, + apr_pool_t *pool) +{ + svn_wc_status2_t *new_stat = apr_palloc(pool, sizeof(*new_stat)); + + /* Shallow copy all members. */ + *new_stat = *orig_stat; + + /* Now go back and dup the deep items into this pool. */ + if (orig_stat->entry) + new_stat->entry = svn_wc_entry_dup(orig_stat->entry, pool); + + if (orig_stat->repos_lock) + new_stat->repos_lock = svn_lock_dup(orig_stat->repos_lock, pool); + + if (orig_stat->url) + new_stat->url = apr_pstrdup(pool, orig_stat->url); + + if (orig_stat->ood_last_cmt_author) + new_stat->ood_last_cmt_author + = apr_pstrdup(pool, orig_stat->ood_last_cmt_author); + + if (orig_stat->tree_conflict) + new_stat->tree_conflict + = svn_wc__conflict_description_dup(orig_stat->tree_conflict, pool); + + /* Return the new hotness. */ + return new_stat; +} + svn_wc_status_t * svn_wc_dup_status(const svn_wc_status_t *orig_stat, apr_pool_t *pool) @@ -2515,13 +2548,15 @@ { const char *local_abspath; svn_wc_context_t *wc_ctx; + svn_wc_status3_t *stat3; SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */, svn_wc__adm_get_db(adm_access), pool)); - SVN_ERR(svn_wc_status3(status, wc_ctx, local_abspath, pool, pool)); + SVN_ERR(svn_wc_status3(&stat3, wc_ctx, local_abspath, pool, pool)); + *status = (svn_wc_status2_t *) stat3; return svn_error_return(svn_wc_context_destroy(wc_ctx)); } Index: subversion/libsvn_wc/status.c =================================================================== --- subversion/libsvn_wc/status.c (revision 932402) +++ subversion/libsvn_wc/status.c (working copy) @@ -126,7 +126,7 @@ const apr_array_header_t *ignores; /* Status item for the path represented by the anchor of the edit. */ - svn_wc_status2_t *anchor_status; + svn_wc_status3_t *anchor_status; /* Was open_root() called for this edit drive? */ svn_boolean_t root_opened; @@ -178,7 +178,7 @@ svn_boolean_t text_changed; /* Working copy status structures for children of this directory. - This hash maps const char * abspaths to svn_wc_status2_t * + This hash maps const char * abspaths to svn_wc_status3_t * status items. */ apr_hash_t *statii; @@ -188,7 +188,7 @@ /* The URI to this item in the repository. */ const char *url; - /* out-of-date info corresponding to ood_* fields in svn_wc_status2_t. */ + /* out-of-date info corresponding to ood_* fields in svn_wc_status3_t. */ svn_revnum_t ood_last_cmt_rev; apr_time_t ood_last_cmt_date; svn_node_kind_t ood_kind; @@ -230,7 +230,7 @@ /* The URI to this item in the repository. */ const char *url; - /* out-of-date info corresponding to ood_* fields in svn_wc_status2_t. */ + /* out-of-date info corresponding to ood_* fields in svn_wc_status3_t. */ svn_revnum_t ood_last_cmt_rev; apr_time_t ood_last_cmt_date; svn_node_kind_t ood_kind; @@ -240,7 +240,7 @@ /** Code **/ static svn_error_t * -internal_status(svn_wc_status2_t **status, +internal_status(svn_wc_status3_t **status, svn_wc__db_t *db, const char *local_abspath, apr_pool_t *result_pool, @@ -278,7 +278,7 @@ non-NULL, REPOS_ROOT must contain the repository root URL of the entry. */ static svn_error_t * -assemble_status(svn_wc_status2_t **status, +assemble_status(svn_wc_status3_t **status, svn_wc__db_t *db, const char *local_abspath, const svn_wc_entry_t *entry, @@ -292,7 +292,7 @@ apr_pool_t *result_pool, apr_pool_t *scratch_pool) { - svn_wc_status2_t *stat; + svn_wc_status3_t *stat; svn_boolean_t locked_p = FALSE; svn_boolean_t switched_p = FALSE; const svn_wc_conflict_description2_t *tree_conflict; @@ -636,7 +636,7 @@ void *status_baton, apr_pool_t *pool) { - svn_wc_status2_t *statstruct; + svn_wc_status3_t *statstruct; SVN_ERR(assemble_status(&statstruct, wb->db, local_abspath, entry, parent_entry, path_kind, path_special, get_all, @@ -763,7 +763,7 @@ apr_pool_t *pool) { svn_boolean_t ignore, is_external; - svn_wc_status2_t *status; + svn_wc_status3_t *status; ignore = svn_wc_match_ignore_list(svn_dirent_basename(local_abspath, NULL), patterns, pool); @@ -918,7 +918,7 @@ } -/* Send svn_wc_status2_t * structures for the directory LOCAL_ABSPATH and +/* Send svn_wc_status3_t * structures for the directory LOCAL_ABSPATH and for all its entries through STATUS_FUNC/STATUS_BATON, or, if SELECTED is non-NULL, only for that directory entry. @@ -1184,14 +1184,14 @@ static svn_error_t * hash_stash(void *baton, const char *path, - const svn_wc_status2_t *status, + const svn_wc_status3_t *status, apr_pool_t *scratch_pool) { apr_hash_t *stat_hash = baton; apr_pool_t *hash_pool = apr_hash_pool_get(stat_hash); assert(! apr_hash_get(stat_hash, path, APR_HASH_KEY_STRING)); apr_hash_set(stat_hash, apr_pstrdup(hash_pool, path), - APR_HASH_KEY_STRING, svn_wc_dup_status2(status, hash_pool)); + APR_HASH_KEY_STRING, svn_wc_dup_status3(status, hash_pool)); return SVN_NO_ERROR; } @@ -1239,7 +1239,7 @@ svn_lock_t *repos_lock, apr_pool_t *scratch_pool) { - svn_wc_status2_t *statstruct; + svn_wc_status3_t *statstruct; apr_pool_t *pool; apr_hash_t *statushash; @@ -1363,7 +1363,7 @@ { const char *url; struct dir_baton *pb = db->parent_baton; - const svn_wc_status2_t *status = apr_hash_get(pb->statii, + const svn_wc_status3_t *status = apr_hash_get(pb->statii, db->local_abspath, APR_HASH_KEY_STRING); /* Note that status->entry->url is NULL in the case of a missing @@ -1394,7 +1394,7 @@ struct edit_baton *eb = edit_baton; struct dir_baton *d = apr_pcalloc(pool, sizeof(*d)); const char *local_abspath; - const svn_wc_status2_t *status_in_parent; + const svn_wc_status3_t *status_in_parent; SVN_ERR_ASSERT(path || (! pb)); @@ -1463,7 +1463,7 @@ || d->depth == svn_depth_immediates) ) { - const svn_wc_status2_t *this_dir_status; + const svn_wc_status3_t *this_dir_status; const apr_array_header_t *ignores = eb->ignores; SVN_ERR(get_dir_status(&eb->wb, local_abspath, @@ -1518,7 +1518,7 @@ svn_boolean_t -svn_wc__is_sendable_status(const svn_wc_status2_t *status, +svn_wc__is_sendable_status(const svn_wc_status3_t *status, svn_boolean_t no_ignore, svn_boolean_t get_all) { @@ -1590,11 +1590,11 @@ static svn_error_t * mark_deleted(void *baton, const char *local_abspath, - const svn_wc_status2_t *status, + const svn_wc_status3_t *status, apr_pool_t *scratch_pool) { struct status_baton *sb = baton; - svn_wc_status2_t *new_status = svn_wc_dup_status2(status, scratch_pool); + svn_wc_status3_t *new_status = svn_wc_dup_status3(status, scratch_pool); new_status->repos_text_status = svn_wc_status_deleted; return sb->real_status_func(sb->real_status_baton, local_abspath, new_status, scratch_pool); @@ -1634,7 +1634,7 @@ for (hi = apr_hash_first(pool, statii); hi; hi = apr_hash_next(hi)) { const char *path = svn__apr_hash_index_key(hi); - svn_wc_status2_t *status = svn__apr_hash_index_val(hi); + svn_wc_status3_t *status = svn__apr_hash_index_val(hi); /* Clear the subpool. */ svn_pool_clear(subpool); @@ -1880,7 +1880,7 @@ if (pb && ! db->excluded) { svn_boolean_t was_deleted = FALSE; - const svn_wc_status2_t *dir_status; + const svn_wc_status3_t *dir_status; /* See if the directory was deleted or replaced. */ dir_status = apr_hash_get(pb->statii, db->local_abspath, @@ -1905,7 +1905,7 @@ target, we should only report the target. */ if (*eb->target_basename) { - const svn_wc_status2_t *tgt_status; + const svn_wc_status3_t *tgt_status; tgt_status = apr_hash_get(db->statii, eb->target_abspath, APR_HASH_KEY_STRING); @@ -2360,7 +2360,7 @@ /* */ static svn_error_t * -internal_status(svn_wc_status2_t **status, +internal_status(svn_wc_status3_t **status, svn_wc__db_t *db, const char *local_abspath, apr_pool_t *result_pool, @@ -2422,7 +2422,7 @@ svn_error_t * -svn_wc_status3(svn_wc_status2_t **status, +svn_wc_status3(svn_wc_status3_t **status, svn_wc_context_t *wc_ctx, const char *local_abspath, apr_pool_t *result_pool, @@ -2433,12 +2433,11 @@ scratch_pool)); } - -svn_wc_status2_t * -svn_wc_dup_status2(const svn_wc_status2_t *orig_stat, +svn_wc_status3_t * +svn_wc_dup_status3(const svn_wc_status3_t *orig_stat, apr_pool_t *pool) { - svn_wc_status2_t *new_stat = apr_palloc(pool, sizeof(*new_stat)); + svn_wc_status3_t *new_stat = apr_palloc(pool, sizeof(*new_stat)); /* Shallow copy all members. */ *new_stat = *orig_stat; Index: subversion/libsvn_client/deprecated.c =================================================================== --- subversion/libsvn_client/deprecated.c (revision 932402) +++ subversion/libsvn_client/deprecated.c (working copy) @@ -1433,11 +1433,12 @@ static svn_error_t * status4_wrapper_func(void *baton, const char *path, - const svn_wc_status2_t *status, + const svn_wc_status3_t *status, apr_pool_t *scratch_pool) { struct status4_wrapper_baton *swb = baton; - svn_wc_status2_t *dup = svn_wc_dup_status2(status, scratch_pool); + svn_wc_status2_t *dup; + dup = (svn_wc_status2_t *) svn_wc_dup_status3(status, scratch_pool); return (*swb->old_func)(swb->old_baton, path, dup, scratch_pool); } Index: subversion/libsvn_client/delete.c =================================================================== --- subversion/libsvn_client/delete.c (revision 932402) +++ subversion/libsvn_client/delete.c (working copy) @@ -50,7 +50,7 @@ static svn_error_t * find_undeletables(void *baton, const char *path, - const svn_wc_status2_t *status, + const svn_wc_status3_t *status, apr_pool_t *pool) { /* Check for error-ful states. */ Index: subversion/libsvn_client/export.c =================================================================== --- subversion/libsvn_client/export.c (revision 932402) +++ subversion/libsvn_client/export.c (working copy) @@ -170,7 +170,7 @@ } else { - svn_wc_status2_t *status; + svn_wc_status3_t *status; /* ### hmm. this isn't always a specialfile. this will simply open ### the file readonly if it is a regular file. */ Index: subversion/libsvn_client/status.c =================================================================== --- subversion/libsvn_client/status.c (revision 932402) +++ subversion/libsvn_client/status.c (working copy) @@ -68,7 +68,7 @@ static svn_error_t * tweak_status(void *baton, const char *local_abspath, - const svn_wc_status2_t *status, + const svn_wc_status3_t *status, apr_pool_t *scratch_pool) { struct status_baton *sb = baton; @@ -79,7 +79,7 @@ through here. */ if (sb->deleted_in_repos) { - svn_wc_status2_t *new_status = svn_wc_dup_status2(status, scratch_pool); + svn_wc_status3_t *new_status = svn_wc_dup_status3(status, scratch_pool); new_status->repos_text_status = svn_wc_status_deleted; status = new_status; } Index: subversion/libsvn_client/patch.c =================================================================== --- subversion/libsvn_client/patch.c (revision 932402) +++ subversion/libsvn_client/patch.c (working copy) @@ -219,7 +219,7 @@ apr_pool_t *scratch_pool) { const char *stripped_path; - svn_wc_status2_t *status; + svn_wc_status3_t *status; target->canon_path_from_patchfile = svn_dirent_internal_style( path_from_patchfile, result_pool); Index: subversion/libsvn_client/merge.c =================================================================== --- subversion/libsvn_client/merge.c (revision 932402) +++ subversion/libsvn_client/merge.c (working copy) @@ -4429,7 +4429,7 @@ hi = apr_hash_next(hi)) { const char *skipped_abspath = svn__apr_hash_index_key(hi); - svn_wc_status2_t *status; + svn_wc_status3_t *status; /* Before we override, make sure this is a versioned path, it might be an unversioned obstruction. */ Index: subversion/libsvn_client/cat.c =================================================================== --- subversion/libsvn_client/cat.c (revision 932402) +++ subversion/libsvn_client/cat.c (working copy) @@ -97,7 +97,7 @@ } else { - svn_wc_status2_t *status; + svn_wc_status3_t *status; SVN_ERR(svn_stream_open_readonly(&input, local_abspath, scratch_pool, scratch_pool)); Index: subversion/libsvn_client/blame.c =================================================================== --- subversion/libsvn_client/blame.c (revision 932402) +++ subversion/libsvn_client/blame.c (working copy) @@ -680,7 +680,7 @@ { /* If the local file is modified we have to call the handler on the working copy file with keywords unexpanded */ - svn_wc_status2_t *status; + svn_wc_status3_t *status; SVN_ERR(svn_wc_status3(&status, ctx->wc_ctx, target_abspath_or_url, pool, pool)); Index: subversion/libsvn_client/commit.c =================================================================== --- subversion/libsvn_client/commit.c (revision 932402) +++ subversion/libsvn_client/commit.c (working copy) @@ -1051,7 +1051,7 @@ { if (kind == svn_node_dir) { - svn_wc_status2_t *status; + svn_wc_status3_t *status; /* ### Looking at schedule is probably enough, no need for pristine compare etc. */