Merge r16344, r16347, r16358, r16375, and r16494 (into the merge
branch created from r16495 of the 1.3.x branch).
git-svn-id: https://svn.apache.org/repos/asf/subversion/branches/status-from-repos-enhancements@856571 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/subversion/include/svn_wc.h b/subversion/include/svn_wc.h
index ba9913f..6b37085 100644
--- a/subversion/include/svn_wc.h
+++ b/subversion/include/svn_wc.h
@@ -1559,6 +1559,46 @@
/** 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 Repository out of date info
+ * @{
+ *
+ * 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 not out of
+ * date, the fields are set as described below.
+ */
+
+ /** Set to the youngest committed revision, or @c SVN_INVALID_REVNUM
+ * if 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 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 @c
+ * svn_wc_status_none if 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 out
+ * of date.
+ * @since New in 1.3
+ */
+ const char *ood_last_cmt_author;
+
+ /** @} */
+
} svn_wc_status2_t;
diff --git a/subversion/libsvn_wc/status.c b/subversion/libsvn_wc/status.c
index 52bac1b..60be316 100644
--- a/subversion/libsvn_wc/status.c
+++ b/subversion/libsvn_wc/status.c
@@ -33,6 +33,7 @@
#include "svn_io.h"
#include "svn_wc.h"
#include "svn_config.h"
+#include "svn_time.h"
#include "svn_private_config.h"
#include "wc.h"
@@ -132,6 +133,15 @@
/* The pool in which this baton itself is allocated. */
apr_pool_t *pool;
+
+ /* The URI to this item in the repository. */
+ const char *url;
+
+ /* Out of date info corresponding to ood_* fields in svn_wc_status2_t. */
+ svn_revnum_t ood_last_cmt_rev;
+ apr_time_t ood_last_cmt_date;
+ svn_node_kind_t ood_kind;
+ const char *ood_last_cmt_author;
};
@@ -166,6 +176,14 @@
the code that syncs up the adm dir and working copy. */
svn_boolean_t prop_changed;
+ /* The URI to this item in the repository. */
+ const char *url;
+
+ /* Out of date info corresponding to ood_* fields in svn_wc_status2_t. */
+ svn_revnum_t ood_last_cmt_rev;
+ apr_time_t ood_last_cmt_date;
+ svn_node_kind_t ood_kind;
+ const char *ood_last_cmt_author;
};
@@ -282,6 +300,11 @@
}
stat->repos_lock = repos_lock;
+ stat->url = NULL;
+ stat->ood_last_cmt_rev = SVN_INVALID_REVNUM;
+ stat->ood_last_cmt_date = 0;
+ stat->ood_kind = svn_wc_status_none;
+ stat->ood_last_cmt_author = NULL;
*status = stat;
return SVN_NO_ERROR;
@@ -466,6 +489,11 @@
stat->switched = switched_p;
stat->copied = entry->copied;
stat->repos_lock = repos_lock;
+ stat->url = (entry->url ? entry->url : NULL);
+ stat->ood_last_cmt_rev = SVN_INVALID_REVNUM;
+ stat->ood_last_cmt_date = 0;
+ stat->ood_kind = svn_wc_status_none;
+ stat->ood_last_cmt_author = NULL;
*status = stat;
@@ -952,14 +980,16 @@
}
-/* Look up the key PATH in STATUSHASH. If the value doesn't yet
- exist, and the REPOS_TEXT_STATUS indicates that this is an
+/* Look up the key PATH in BATON->STATII. IS_DIR_BATON indicates whether
+ baton is a struct *dir_baton or struct *file_baton. If the value doesn't
+ yet exist, and the REPOS_TEXT_STATUS indicates that this is an
addition, create a new status struct using the hash's pool. Merge
REPOS_TEXT_STATUS and REPOS_PROP_STATUS into the status structure's
"network" fields.
If a new struct was added, set the repos_lock to REPOS_LOCK. */
static svn_error_t *
-tweak_statushash (apr_hash_t *statushash,
+tweak_statushash (void *baton,
+ svn_boolean_t is_dir_baton,
svn_wc_adm_access_t *adm_access,
const char *path,
svn_boolean_t is_dir,
@@ -968,7 +998,14 @@
svn_lock_t *repos_lock)
{
svn_wc_status2_t *statstruct;
- apr_pool_t *pool = apr_hash_pool_get (statushash);
+ apr_pool_t *pool;
+ apr_hash_t *statushash;
+
+ if (is_dir_baton)
+ statushash = ((struct dir_baton *) baton)->statii;
+ else
+ statushash = ((struct file_baton *) baton)->dir_baton->statii;
+ pool = apr_hash_pool_get (statushash);
/* Is PATH already a hash-key? */
statstruct = apr_hash_get (statushash, path, APR_HASH_KEY_STRING);
@@ -1008,9 +1045,59 @@
if (repos_prop_status)
statstruct->repos_prop_status = repos_prop_status;
+ /* Copy out of date info. */
+ if (is_dir_baton)
+ {
+ struct dir_baton *b = baton;
+ if (b->url)
+ statstruct->url = b->url;
+ statstruct->ood_kind = b->ood_kind;
+ /* The last committed rev, date, and author for deleted items
+ isn't available. */
+ if (statstruct->repos_text_status != svn_wc_status_deleted)
+ {
+ statstruct->ood_last_cmt_rev = b->ood_last_cmt_rev;
+ statstruct->ood_last_cmt_date = b->ood_last_cmt_date;
+ statstruct->ood_last_cmt_author = b->ood_last_cmt_author;
+ }
+ }
+ else
+ {
+ struct file_baton *b = baton;
+ if (b->url)
+ statstruct->url = b->url;
+ statstruct->ood_last_cmt_rev = b->ood_last_cmt_rev;
+ statstruct->ood_last_cmt_date = b->ood_last_cmt_date;
+ statstruct->ood_kind = b->ood_kind;
+ statstruct->ood_last_cmt_author = b->ood_last_cmt_author;
+ }
return SVN_NO_ERROR;
}
+/* Returns the URL for DB, or NULL: */
+static const char *
+find_dir_url (const struct dir_baton *db, apr_pool_t *pool)
+{
+ /* If we have no name, we're the root, return the anchor URL. */
+ if (! db->name)
+ return db->edit_baton->anchor_status->entry->url;
+ else
+ {
+ const char *url;
+ struct dir_baton *pb = db->parent_baton;
+ svn_wc_status2_t *status = apr_hash_get (pb->statii, db->name,
+ APR_HASH_KEY_STRING);
+ if (status && status->entry)
+ return status->entry->url;
+
+ url = find_dir_url (pb, pool);
+ if (url)
+ return svn_path_url_add_component (url, db->name, pool);
+ else
+ return NULL;
+ }
+}
+
/* Create a new dir_baton for subdir PATH. */
@@ -1038,12 +1125,17 @@
full_path = apr_pstrdup (pool, eb->anchor);
/* Finish populating the baton members. */
- d->path = full_path;
- d->name = path ? (svn_path_basename (path, pool)) : NULL;
- d->edit_baton = edit_baton;
+ d->path = full_path;
+ d->name = path ? (svn_path_basename (path, pool)) : NULL;
+ d->edit_baton = edit_baton;
d->parent_baton = parent_baton;
- d->pool = pool;
- d->statii = apr_hash_make (pool);
+ d->pool = pool;
+ d->statii = apr_hash_make (pool);
+ d->url = apr_pstrdup (pool, find_dir_url (d, pool));
+ d->ood_last_cmt_rev = SVN_INVALID_REVNUM;
+ d->ood_last_cmt_date = 0;
+ d->ood_kind = svn_node_dir;
+ d->ood_last_cmt_author = NULL;
/* Get the status for this path's children. Of course, we only want
to do this if the path is versioned as a directory. */
@@ -1098,39 +1190,21 @@
full_path = apr_pstrdup (pool, eb->anchor);
/* Finish populating the baton members. */
- f->path = full_path;
- f->name = svn_path_basename (path, pool);
- f->pool = pool;
- f->dir_baton = pb;
+ f->path = full_path;
+ f->name = svn_path_basename (path, pool);
+ f->pool = pool;
+ f->dir_baton = pb;
f->edit_baton = eb;
-
+ f->url = svn_path_url_add_component (find_dir_url (pb, pool),
+ svn_path_basename (full_path, pool),
+ pool);
+ f->ood_last_cmt_rev = SVN_INVALID_REVNUM;
+ f->ood_last_cmt_date = 0;
+ f->ood_kind = svn_node_file;
+ f->ood_last_cmt_author = NULL;
return f;
}
-/* Returns the URL for DB, or NULL: */
-static const char *
-find_dir_url (const struct dir_baton *db, apr_pool_t *pool)
-{
- /* If we have no name, we're the root, return the anchor URL. */
- if (! db->name)
- return db->edit_baton->anchor_status->entry->url;
- else
- {
- const char *url;
- struct dir_baton *pb = db->parent_baton;
- svn_wc_status2_t *status = apr_hash_get (pb->statii, db->name,
- APR_HASH_KEY_STRING);
- if (status && status->entry)
- return status->entry->url;
-
- url = find_dir_url (pb, pool);
- if (url)
- return svn_path_url_add_component (url, db->name, pool);
- else
- return NULL;
- }
-}
-
/* Return a boolean answer to the question "Is STATUS something that
should be reported?". EB is the edit baton. */
static svn_boolean_t
@@ -1369,7 +1443,7 @@
SVN_ERR (svn_wc_entries_read (&entries, adm_access, FALSE, pool));
if (apr_hash_get (entries, hash_key, APR_HASH_KEY_STRING))
- SVN_ERR (tweak_statushash (db->statii, eb->adm_access,
+ SVN_ERR (tweak_statushash (db, TRUE, eb->adm_access,
full_path, kind == svn_node_dir,
svn_wc_status_deleted, 0, NULL));
@@ -1377,7 +1451,7 @@
is the root node and we're not supposed to report on the root
node). */
if (db->parent_baton && (! *eb->target))
- SVN_ERR (tweak_statushash (db->parent_baton->statii, eb->adm_access,
+ SVN_ERR (tweak_statushash (db->parent_baton, TRUE, eb->adm_access,
db->path, kind == svn_node_dir,
svn_wc_status_modified, 0, NULL));
@@ -1431,6 +1505,19 @@
struct dir_baton *db = dir_baton;
if (svn_wc_is_normal_prop (name))
db->prop_changed = TRUE;
+
+ /* Note any changes to the repository. */
+ if (strcmp (name, SVN_PROP_ENTRY_COMMITTED_REV) == 0)
+ db->ood_last_cmt_rev = SVN_STR_TO_REV (value->data);
+ else if (strcmp (name, SVN_PROP_ENTRY_LAST_AUTHOR) == 0)
+ db->ood_last_cmt_author = apr_pstrdup (db->pool, value->data);
+ else if (strcmp (name, SVN_PROP_ENTRY_COMMITTED_DATE) == 0)
+ {
+ apr_time_t tm;
+ SVN_ERR (svn_time_from_cstring (&tm, value->data, db->pool));
+ db->ood_last_cmt_date = tm;
+ }
+
return SVN_NO_ERROR;
}
@@ -1469,7 +1556,7 @@
if (pb)
/* NOTE: When we add directory locking, we need to find a directory
lock here. */
- SVN_ERR (tweak_statushash (pb->statii,
+ SVN_ERR (tweak_statushash (pb, TRUE,
eb->adm_access,
db->path, TRUE,
repos_text_status,
@@ -1608,6 +1695,20 @@
struct file_baton *fb = file_baton;
if (svn_wc_is_normal_prop (name))
fb->prop_changed = TRUE;
+
+ /* Note any changes to the repository. */
+ if (strcmp (name, SVN_PROP_ENTRY_COMMITTED_REV) == 0)
+ fb->ood_last_cmt_rev = SVN_STR_TO_REV (value->data);
+ else if (strcmp (name, SVN_PROP_ENTRY_LAST_AUTHOR) == 0)
+ fb->ood_last_cmt_author = apr_pstrdup (fb->dir_baton->pool,
+ value->data);
+ else if (strcmp (name, SVN_PROP_ENTRY_COMMITTED_DATE) == 0)
+ {
+ apr_time_t tm;
+ SVN_ERR (svn_time_from_cstring (&tm, value->data, fb->dir_baton->pool));
+ fb->ood_last_cmt_date = tm;
+ }
+
return SVN_NO_ERROR;
}
@@ -1653,7 +1754,7 @@
repos_prop_status = fb->prop_changed ? svn_wc_status_modified : 0;
}
- SVN_ERR (tweak_statushash (fb->dir_baton->statii,
+ SVN_ERR (tweak_statushash (fb, FALSE,
fb->edit_baton->adm_access,
fb->path, FALSE,
repos_text_status,