You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by da...@apache.org on 2010/04/23 20:58:02 UTC
svn commit: r937468 - in /subversion/trunk/subversion:
include/private/svn_wc_private.h include/svn_wc.h libsvn_wc/node.c
libsvn_wc/status.c svn/status-cmd.c svn/status.c
tests/cmdline/copy_tests.py tests/cmdline/merge_tests.py
tests/cmdline/svntest/wc.py
Author: dannas
Date: Fri Apr 23 18:58:01 2010
New Revision: 937468
URL: http://svn.apache.org/viewvc?rev=937468&view=rev
Log:
As part of WC-NG, replace entry calls for revisions from
svn_wc_status3_t related code. While doing that, we define a strict
idea of what a revision in svn_wc_status3_t means. The revision returned
from libsvn_wc is:
"The revision of the unmodified (BASE) node, or SVN_INVALID_REVNUM if
any (structural) changes have been made to that node."
We have three compability concerns to address:
1) svn_wc_status3_t only gives us the revision information for BASE.
svn_wc__node_get_working_rev_info() is used for returning the WORKING
state as the entries code would have done it.
2) The entries code set the revision of newly added nodes to 0 but the
db sets them to -1. Since too many tests needs to be changed and 'svn
info' also uses 0, I'll change those values in a follow-up patch
instead.
3) Despite the attempt to mimic the semantics of the entries code, we
have two changes in behaviour. An entry_rev field has been added to
StateItem to allow the testsuite to handle those differences.
* subversion/tests/cmdline/copy_tests.py
(repos_to_wc): Change revision to 0 since the node is added. Don't
check against entries since the behavior differs.
* subversion/tests/cmdline/svntest/wc.py
(tweak_for_entries_compare): Set wc_rev to entry_rev when the later
exists. Clear entry_rev afterwards to avoid it interfering when
doing the compare between the output from entries-dump and our
state.
(StateItem): Add new member entry_rev for tracking differences in
behaviour between WC-1 code and WC-NG.
* subversion/tests/cmdline/merge_tests.py
(merge_into_missing): Add revision to status output for missing dir.
Previously, missing dirs did not have a revision, only files had.
Don't check entries since the behavior differs.
* subversion/svn/status.c
(print_status): Replace checks for revisions using entries with the
direct fields in svn_wc_status3_t. Set the revision for added and
replaced nodes to 0. WC-NG sets those revisions to -1, but changing
all the involved tests is for a follow-up.
* subversion/include/svn_wc.h
(svn_wc_status2_t): Add fields revision, changed_rev, changed_date and
changed_author.
* subversion/include/private/svn_wc_private.h
(svn_wc__node_get_working_rev_info): Declare. New.
* subversion/libsvn_wc/node.c
(svn_wc__node__get_working_rev_info): New.
* subversion/libsvn_wc/status.c
(assemble_status): Fill in the new fields with data from the wc db.
(svn_wc_dup_status3): Copy the changed_author field.
* subversion/svn/status-cmd.c
(status_baton): Add svn_client_ctx member.
(print_status): Fetch revision information about WORKING nodes with
svn_wc__node_get_working_rev(). It's a temporary thing until we've
decided what behaviour we prefer and the means for detecting what
state the wc is in.
(svn_cl__status): Set ctx member of status_baton.
Modified:
subversion/trunk/subversion/include/private/svn_wc_private.h
subversion/trunk/subversion/include/svn_wc.h
subversion/trunk/subversion/libsvn_wc/node.c
subversion/trunk/subversion/libsvn_wc/status.c
subversion/trunk/subversion/svn/status-cmd.c
subversion/trunk/subversion/svn/status.c
subversion/trunk/subversion/tests/cmdline/copy_tests.py
subversion/trunk/subversion/tests/cmdline/merge_tests.py
subversion/trunk/subversion/tests/cmdline/svntest/wc.py
Modified: subversion/trunk/subversion/include/private/svn_wc_private.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_wc_private.h?rev=937468&r1=937467&r2=937468&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_wc_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_wc_private.h Fri Apr 23 18:58:01 2010
@@ -487,6 +487,41 @@ svn_wc__node_get_base_rev(svn_revnum_t *
const char *local_abspath,
apr_pool_t *scratch_pool);
+
+/* Get the working revision of @a local_abspath using @a wc_ctx. If @a
+ * local_abspath is not in the working copy, return @c
+ * SVN_ERR_WC_PATH_NOT_FOUND.
+ *
+ * This function is meant as a temporary solution for using the old-style
+ * semantics of entries. It will handle any uncommitted changes (delete,
+ * replace and/or copy-here/move-here).
+ *
+ * For a delete the @a revision is the BASE node of the operation root, e.g
+ * the path that was deleted. But if the delete is below an add, the
+ * revision is set to SVN_INVALID_REVNUM. For an add, copy or move we return
+ * SVN_INVALID_REVNUM. In case of a replacement, we return the BASE
+ * revision.
+ *
+ * The @changed_rev is set to the latest committed change to @a
+ * local_abspath before or equal to @a revision, unless the node is
+ * copied-here or moved-here. Then it is the revision of the latest committed
+ * change before or equal to the copyfrom_rev. NOTE, that we use
+ * SVN_INVALID_REVNUM for a scheduled copy or move.
+ *
+ * The @a changed_date and @a changed_author are the ones associated with @a
+ * changed_rev.
+ */
+svn_error_t *
+svn_wc__node_get_working_rev_info(svn_revnum_t *revision,
+ svn_revnum_t *changed_rev,
+ apr_time_t *changed_date,
+ const char **changed_author,
+ svn_wc_context_t *wc_ctx,
+ const char *local_abspath,
+ apr_pool_t *scratch_pool,
+ apr_pool_t *result_pool);
+
+
/** This whole function is for legacy, and it sucks. It does not really
* make sense to get the copy-from revision number without the copy-from
* URL, but higher level code currently wants that. This should go away.
Modified: subversion/trunk/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_wc.h?rev=937468&r1=937467&r2=937468&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_wc.h (original)
+++ subversion/trunk/subversion/include/svn_wc.h Fri Apr 23 18:58:01 2010
@@ -3617,6 +3617,18 @@ typedef struct svn_wc_status3_t
*/
enum svn_wc_status_kind pristine_prop_status;
+ /** Base revision. */
+ svn_revnum_t revision;
+
+ /** Last revision this was changed */
+ svn_revnum_t changed_rev;
+
+ /** Last commit author of this item */
+ const char *changed_author;
+
+ /** Date of last commit. */
+ apr_time_t changed_date;
+
/* NOTE! Please update svn_wc_dup_status3() when adding new fields here. */
} svn_wc_status3_t;
Modified: subversion/trunk/subversion/libsvn_wc/node.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/node.c?rev=937468&r1=937467&r2=937468&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/node.c (original)
+++ subversion/trunk/subversion/libsvn_wc/node.c Fri Apr 23 18:58:01 2010
@@ -754,6 +754,68 @@ svn_wc__node_get_base_rev(svn_revnum_t *
}
svn_error_t *
+svn_wc__node_get_working_rev_info(svn_revnum_t *revision,
+ svn_revnum_t *changed_rev,
+ apr_time_t *changed_date,
+ const char **changed_author,
+ svn_wc_context_t *wc_ctx,
+ const char *local_abspath,
+ apr_pool_t *scratch_pool,
+ apr_pool_t *result_pool)
+{
+ svn_wc__db_status_t status;
+ svn_boolean_t base_shadowed;
+
+ SVN_ERR(svn_wc__db_read_info(&status, NULL, revision, NULL, NULL, NULL,
+ changed_rev, changed_date, changed_author,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, &base_shadowed, NULL,
+ NULL, wc_ctx->db, local_abspath, result_pool,
+ scratch_pool));
+
+ if (status == svn_wc__db_status_deleted)
+ {
+ const char *work_del_abspath = NULL;
+ const char *base_del_abspath = NULL;
+
+ SVN_ERR(svn_wc__db_scan_deletion(&base_del_abspath, NULL,
+ NULL, &work_del_abspath, wc_ctx->db,
+ local_abspath, scratch_pool,
+ result_pool));
+ if (work_del_abspath)
+ {
+ SVN_ERR(svn_wc__db_read_info(&status, NULL, revision, NULL, NULL,
+ NULL, changed_rev, changed_date,
+ changed_author, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, &base_shadowed,
+ NULL, NULL, wc_ctx->db, work_del_abspath,
+ result_pool, scratch_pool));
+ }
+ else
+ {
+ SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, revision, NULL,
+ NULL, NULL, changed_rev,
+ changed_date, changed_author,
+ NULL, NULL, NULL, NULL, NULL,
+ NULL, wc_ctx->db,
+ base_del_abspath, result_pool,
+ scratch_pool));
+ }
+ }
+ else if (base_shadowed)
+ {
+ SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, revision, NULL, NULL,
+ NULL, changed_rev, changed_date,
+ changed_author, NULL, NULL, NULL,
+ NULL, NULL, NULL, wc_ctx->db, local_abspath,
+ result_pool, scratch_pool));
+ }
+ return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
svn_wc__node_get_commit_base_rev(svn_revnum_t *commit_base_revision,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
Modified: subversion/trunk/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/status.c?rev=937468&r1=937467&r2=937468&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/status.c (original)
+++ subversion/trunk/subversion/libsvn_wc/status.c Fri Apr 23 18:58:01 2010
@@ -297,6 +297,11 @@ assemble_status(svn_wc_status3_t **statu
svn_boolean_t switched_p = FALSE;
const svn_wc_conflict_description2_t *tree_conflict;
svn_boolean_t file_external_p = FALSE;
+ svn_revnum_t revision;
+ svn_revnum_t changed_rev;
+ const char *changed_author;
+ apr_time_t changed_date;
+ svn_boolean_t base_shadowed;
#ifdef HAVE_SYMLINK
svn_boolean_t wc_special;
#endif /* HAVE_SYMLINK */
@@ -376,6 +381,10 @@ assemble_status(svn_wc_status3_t **statu
stat->repos_lock = repos_lock;
stat->url = NULL;
+ stat->revision = SVN_INVALID_REVNUM;
+ stat->changed_rev = SVN_INVALID_REVNUM;
+ stat->changed_author = NULL;
+ stat->changed_date = 0;
stat->ood_last_cmt_rev = SVN_INVALID_REVNUM;
stat->ood_last_cmt_date = 0;
stat->ood_kind = svn_node_none;
@@ -385,6 +394,13 @@ assemble_status(svn_wc_status3_t **statu
return SVN_NO_ERROR;
}
+ SVN_ERR(svn_wc__db_read_info(NULL, NULL, &revision, NULL, NULL, NULL,
+ &changed_rev, &changed_date, &changed_author,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, &base_shadowed, NULL,
+ NULL, db, local_abspath, result_pool,
+ scratch_pool));
+
/* Someone either deleted the administrative directory in the versioned
subdir, or deleted the directory altogether and created a new one.
In any case, what is currently there is in the way.
@@ -606,6 +622,10 @@ assemble_status(svn_wc_status3_t **statu
stat->copied = entry->copied;
stat->repos_lock = repos_lock;
stat->url = (entry->url ? entry->url : NULL);
+ stat->revision = revision;
+ stat->changed_rev = changed_rev;
+ stat->changed_author = changed_author;
+ stat->changed_date = changed_date;
stat->ood_last_cmt_rev = SVN_INVALID_REVNUM;
stat->ood_last_cmt_date = 0;
stat->ood_kind = svn_node_none;
@@ -2459,6 +2479,9 @@ svn_wc_dup_status3(const svn_wc_status3_
if (orig_stat->url)
new_stat->url = apr_pstrdup(pool, orig_stat->url);
+ if (orig_stat->changed_author)
+ new_stat->changed_author = apr_pstrdup(pool, orig_stat->changed_author);
+
if (orig_stat->ood_last_cmt_author)
new_stat->ood_last_cmt_author
= apr_pstrdup(pool, orig_stat->ood_last_cmt_author);
Modified: subversion/trunk/subversion/svn/status-cmd.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/status-cmd.c?rev=937468&r1=937467&r2=937468&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/status-cmd.c (original)
+++ subversion/trunk/subversion/svn/status-cmd.c Fri Apr 23 18:58:01 2010
@@ -40,6 +40,7 @@
#include "cl.h"
#include "svn_private_config.h"
+#include "private/svn_wc_private.h"
@@ -65,6 +66,8 @@ struct status_baton
unsigned int text_conflicts;
unsigned int prop_conflicts;
unsigned int tree_conflicts;
+
+ svn_client_ctx_t *ctx;
};
@@ -167,6 +170,35 @@ print_status(void *baton,
apr_pool_t *pool)
{
struct status_baton *sb = baton;
+ svn_wc_status3_t *tweaked_status;
+ svn_revnum_t revision;
+ svn_revnum_t changed_rev;
+ apr_time_t changed_date;
+ const char *changed_author;
+ const char *local_abspath;
+
+ SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, sb->cl_pool));
+ tweaked_status = svn_wc_dup_status3(status, sb->cl_pool);
+
+ /* ### The revision information with associates are based on what
+ * ### _read_info() returns. The svn_wc_status_func4_t callback is
+ * ### suppposed to handle the gathering of additional information from the
+ * ### WORKING nodes on its own. Until we've agreed on how the CLI should
+ * ### handle the revision information, we use this appproach to stay compat
+ * ### with our testsuite. */
+ if (status->entry)
+ {
+ SVN_ERR(svn_wc__node_get_working_rev_info(&revision, &changed_rev,
+ &changed_date,
+ &changed_author,
+ sb->ctx->wc_ctx,
+ local_abspath, sb->cl_pool,
+ pool));
+ tweaked_status->revision = revision;
+ tweaked_status->changed_rev = changed_rev;
+ tweaked_status->changed_date = changed_date;
+ tweaked_status->changed_author = changed_author;
+ }
/* If there's a changelist attached to the entry, then we don't print
the item, but instead dup & cache the status structure for later. */
@@ -178,7 +210,7 @@ print_status(void *baton,
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_status3(status, sb->cl_pool);
+ scache->status = svn_wc_dup_status3(tweaked_status, sb->cl_pool);
path_array =
apr_hash_get(sb->cached_changelists, cl_key, APR_HASH_KEY_STRING);
@@ -194,7 +226,7 @@ print_status(void *baton,
return SVN_NO_ERROR;
}
- return print_status_normal_or_xml(baton, path, status, pool);
+ return print_status_normal_or_xml(baton, path, tweaked_status, pool);
}
/* This implements the `svn_opt_subcommand_t' interface. */
@@ -255,6 +287,7 @@ svn_cl__status(apr_getopt_t *os,
sb.text_conflicts = 0;
sb.prop_conflicts = 0;
sb.tree_conflicts = 0;
+ sb.ctx = ctx;
SVN_ERR(svn_opt_eat_peg_revisions(&targets, targets, scratch_pool));
Modified: subversion/trunk/subversion/svn/status.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/status.c?rev=937468&r1=937467&r2=937468&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/status.c (original)
+++ subversion/trunk/subversion/svn/status.c Fri Apr 23 18:58:01 2010
@@ -142,12 +142,20 @@ print_status(const char *path,
if (! status->entry)
working_rev = "";
- else if (! SVN_IS_VALID_REVNUM(status->entry->revision))
- working_rev = " ? ";
+ else if (! SVN_IS_VALID_REVNUM(status->revision))
+ {
+ if (status->copied)
+ working_rev = "-";
+ else if (text_status == svn_wc_status_added
+ || text_status == svn_wc_status_replaced)
+ working_rev = "0";
+ else
+ working_rev = " ? ";
+ }
else if (status->copied)
working_rev = "-";
else
- working_rev = apr_psprintf(pool, "%ld", status->entry->revision);
+ working_rev = apr_psprintf(pool, "%ld", status->revision);
if (status->repos_text_status != svn_wc_status_none
|| status->repos_prop_status != svn_wc_status_none)
@@ -183,15 +191,15 @@ print_status(const char *path,
const char *commit_rev;
const char *commit_author;
- if (status->entry && SVN_IS_VALID_REVNUM(status->entry->cmt_rev))
- commit_rev = apr_psprintf(pool, "%ld", status->entry->cmt_rev);
+ if (SVN_IS_VALID_REVNUM(status->changed_rev))
+ commit_rev = apr_psprintf(pool, "%ld", status->changed_rev);
else if (status->entry)
commit_rev = " ? ";
else
commit_rev = "";
- if (status->entry && status->entry->cmt_author)
- commit_author = status->entry->cmt_author;
+ if (status->changed_author)
+ commit_author = status->changed_author;
else if (status->entry)
commit_author = " ? ";
else
@@ -277,17 +285,17 @@ svn_cl__print_status_xml(const char *pat
apr_hash_set(att_hash, "file-external", APR_HASH_KEY_STRING, "true");
if (status->entry && ! status->entry->copied)
apr_hash_set(att_hash, "revision", APR_HASH_KEY_STRING,
- apr_psprintf(pool, "%ld", status->entry->revision));
+ apr_psprintf(pool, "%ld", status->revision));
if (status->tree_conflict)
apr_hash_set(att_hash, "tree-conflicted", APR_HASH_KEY_STRING,
"true");
svn_xml_make_open_tag_hash(&sb, pool, svn_xml_normal, "wc-status",
att_hash);
- if (status->entry && SVN_IS_VALID_REVNUM(status->entry->cmt_rev))
+ if (SVN_IS_VALID_REVNUM(status->changed_rev))
{
- svn_cl__print_xml_commit(&sb, status->entry->cmt_rev,
- status->entry->cmt_author,
+ svn_cl__print_xml_commit(&sb, status->changed_rev,
+ status->changed_author,
svn_time_to_cstring(status->entry->cmt_date,
pool),
pool);
Modified: subversion/trunk/subversion/tests/cmdline/copy_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/copy_tests.py?rev=937468&r1=937467&r2=937468&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/copy_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/copy_tests.py Fri Apr 23 18:58:01 2010
@@ -980,7 +980,7 @@ def repos_to_wc(sbox):
expected_output = svntest.actions.get_virginal_state(wc_dir, 1)
expected_output.add({
- 'pi' : Item(status='A ', wc_rev='1'),
+ 'pi' : Item(status='A ', wc_rev='0', entry_rev='1'),
})
svntest.actions.run_and_verify_status(wc_dir, expected_output)
Modified: subversion/trunk/subversion/tests/cmdline/merge_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/merge_tests.py?rev=937468&r1=937467&r2=937468&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/merge_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/merge_tests.py Fri Apr 23 18:58:01 2010
@@ -2161,7 +2161,7 @@ def merge_into_missing(sbox):
expected_status = wc.State(F_path, {
'' : Item(status=' ', wc_rev=1),
'foo' : Item(status='! ', wc_rev=2),
- 'Q' : Item(status='! ', wc_rev='?'),
+ 'Q' : Item(status='! ', wc_rev='2', entry_rev='?'),
})
expected_skip = wc.State(F_path, {
'Q' : Item(),
@@ -2183,7 +2183,7 @@ def merge_into_missing(sbox):
expected_status = wc.State(F_path, {
'' : Item(status=' M', wc_rev=1),
'foo' : Item(status='!M', wc_rev=2),
- 'Q' : Item(status='! ', wc_rev='?'),
+ 'Q' : Item(status='! ', wc_rev='2', entry_rev='?'),
})
expected_mergeinfo_output = wc.State(F_path, {
'' : Item(status=' U'),
@@ -2214,7 +2214,7 @@ def merge_into_missing(sbox):
expected_status.add({
'A/B/F' : Item(status=' M', wc_rev=1),
'A/B/F/foo' : Item(status='!M', wc_rev=2),
- 'A/B/F/Q' : Item(status='! ', wc_rev='?'),
+ 'A/B/F/Q' : Item(status='! ', wc_rev='2', entry_rev='?'),
})
svntest.actions.run_and_verify_status(wc_dir, expected_status)
Modified: subversion/trunk/subversion/tests/cmdline/svntest/wc.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/svntest/wc.py?rev=937468&r1=937467&r2=937468&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/svntest/wc.py (original)
+++ subversion/trunk/subversion/tests/cmdline/svntest/wc.py Fri Apr 23 18:58:01 2010
@@ -317,6 +317,9 @@ class State:
item.status = ' ' + item.status[1]
if item.status[1] == 'M':
item.status = item.status[0] + ' '
+ if item.entry_rev is not None:
+ item.wc_rev = item.entry_rev
+ item.entry_rev = None
if item.writelocked:
# we don't contact the repository, so our only information is what
# is in the working copy. 'K' means we have one and it matches the
@@ -615,7 +618,7 @@ class StateItem:
"""
def __init__(self, contents=None, props=None,
- status=None, verb=None, wc_rev=None,
+ status=None, verb=None, wc_rev=None, entry_rev=None,
locked=None, copied=None, switched=None, writelocked=None,
treeconflict=None):
# provide an empty prop dict if it wasn't provided
@@ -638,6 +641,9 @@ class StateItem:
self.verb = verb
# The base revision number of the node in the WC, as a string.
self.wc_rev = wc_rev
+ # This one will be set when we expect the wc_rev to differ from the one
+ # found ni the entries code.
+ self.entry_rev = entry_rev
# For the following attributes, the value is the status character of that
# field from 'svn status', except using value None instead of status ' '.
self.locked = locked