Author: rhuijben
Date: Thu Jul 8 16:19:52 2010
New Revision: 961831
URL: http://svn.apache.org/viewvc?rev=961831&view=rev
Log:
Resolve issue #3676 for files: Committing a tree copy updates the last modified
revision of all descendants. Add a new test specifically for the directory
behavior.
* subversion/tests/cmdline/copy_tests.py
(changed_data_should_match_checkout): Copy one level deeper to
specifically test files.
(changed_dir_data_should_match_checkout): New function. Copied from
changed_data_should_match_checkout.
(test_list): Remove XFail marking from changed_data_should_match_checkout
and add changed_dir_data_should_match_checkout as XFail.
* subversion/libsvn_wc/workqueue.h
(svn_wc__wq_add_postcommit): Allow passing changed_rev and fix other
argument names to show where they belong.
* subversion/libsvn_wc/workqueue.c
(log_do_committed): Accept and pass changed_rev. Rename arguments.
(run_postcommit): Parse changed_rev from skel.
(svn_wc__wq_add_postcommit): Put changed_rev in the skel.
* subversion/libsvn_wc/wc.h
(svn_wc__process_committed_internal): Add top_of_recurse argument.
* subversion/libsvn_wc/deprecated.c
(svn_wc_process_committed4): Pass TRUE for top_of_recurse.
* subversion/libsvn_wc/adm_ops.c
(process_committed_leaf): Receive information on whether this is a
descendant of an operation and use this to determine if changed_*
must be kept. Remove some obsolete cases that can't happen after
our move to sha based pristines.
(svn_wc__process_committed_internal): Handle top_of_recurse forwarding.
(svn_wc_process_committed_queue2): Update caller.
Modified:
subversion/trunk/subversion/libsvn_wc/adm_ops.c
subversion/trunk/subversion/libsvn_wc/deprecated.c
subversion/trunk/subversion/libsvn_wc/wc.h
subversion/trunk/subversion/libsvn_wc/workqueue.c
subversion/trunk/subversion/libsvn_wc/workqueue.h
subversion/trunk/subversion/tests/cmdline/copy_tests.py
Modified: subversion/trunk/subversion/libsvn_wc/adm_ops.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_ops.c?rev=961831&r1=961830&r2=961831&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/trunk/subversion/libsvn_wc/adm_ops.c Thu Jul 8 16:19:52 2010
@@ -117,9 +117,10 @@ svn_wc__get_committed_queue_pool(const s
static svn_error_t *
process_committed_leaf(svn_wc__db_t *db,
const char *local_abspath,
+ svn_boolean_t via_recurse,
svn_revnum_t new_revnum,
- apr_time_t new_date,
- const char *rev_author,
+ apr_time_t new_changed_date,
+ const char *new_changed_author,
apr_hash_t *new_dav_cache,
svn_boolean_t no_unlock,
svn_boolean_t keep_changelist,
@@ -131,6 +132,7 @@ process_committed_leaf(svn_wc__db_t *db,
const svn_checksum_t *copied_checksum;
const char *adm_abspath;
const char *tmp_text_base_abspath;
+ svn_revnum_t new_changed_rev = new_revnum;
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
@@ -190,27 +192,51 @@ process_committed_leaf(svn_wc__db_t *db,
its checksum already. */
if (checksum == NULL)
{
- /* It was copied and not modified. We should have a text
- base for it. And the entry should have a checksum. */
- if (copied_checksum != NULL)
- {
- checksum = copied_checksum;
- }
-#ifdef SVN_DEBUG
- else
+ /* It was copied and not modified. We must have a text
+ base for it. And the node should have a checksum. */
+ SVN_ERR_ASSERT(copied_checksum != NULL);
+
+ checksum = copied_checksum;
+
+ if (via_recurse)
{
- /* If we copy a deleted file, then it will become scheduled
- for deletion, but there is no base text for it. So we
- cannot get/compute a checksum for this file. */
- SVN_ERR_ASSERT(
- status == svn_wc__db_status_deleted
- || status == svn_wc__db_status_obstructed_delete);
+ /* If a copied node itself is not modified, but the op_root of
+ the copy is committed we have to make sure that changed_rev,
+ changed_date and changed_author don't change or the working
+ copy used for committing will show different last modified
+ information then a clean checkout of exactly the same
+ revisions. (Issue #3676) */
+
+ svn_boolean_t props_modified;
+ svn_revnum_t changed_rev;
+ const char *changed_author;
+ apr_time_t changed_date;
+
+ SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL, NULL, NULL,
+ NULL, &changed_rev, &changed_date,
+ &changed_author, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, &props_modified, NULL,
+ NULL, NULL, NULL,
+ db, local_abspath,
+ scratch_pool, scratch_pool));
- /* checksum will remain NULL in this one case. */
+ if (!props_modified)
+ {
+ /* Unmodified child of copy: We keep changed_rev */
+ new_changed_rev = changed_rev;
+ new_changed_date = changed_date;
+ new_changed_author = changed_author;
+ }
}
-#endif
}
}
+ else
+ {
+ /* ### If we can determine that nothing below this node was changed
+ ### via this commit, we should keep new_changed_rev at its old
+ ### value, like how we handle files. */
+ }
/* Set TMP_TEXT_BASE_ABSPATH to NULL. The new text base will be found in
the pristine store by its checksum. */
@@ -219,7 +245,8 @@ process_committed_leaf(svn_wc__db_t *db,
SVN_ERR(svn_wc__wq_add_postcommit(db, local_abspath, tmp_text_base_abspath,
new_revnum,
- new_date, rev_author, checksum,
+ new_changed_rev, new_changed_date,
+ new_changed_author, checksum,
new_dav_cache, keep_changelist, no_unlock,
scratch_pool));
@@ -231,6 +258,7 @@ svn_error_t *
svn_wc__process_committed_internal(svn_wc__db_t *db,
const char *local_abspath,
svn_boolean_t recurse,
+ svn_boolean_t top_of_recurse,
svn_revnum_t new_revnum,
apr_time_t new_date,
const char *rev_author,
@@ -246,7 +274,7 @@ svn_wc__process_committed_internal(svn_w
SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath, TRUE, scratch_pool));
- SVN_ERR(process_committed_leaf(db, local_abspath,
+ SVN_ERR(process_committed_leaf(db, local_abspath, !top_of_recurse,
new_revnum, new_date, rev_author,
new_dav_cache,
no_unlock, keep_changelist,
@@ -337,6 +365,7 @@ svn_wc__process_committed_internal(svn_w
this one committed item. */
SVN_ERR(svn_wc__process_committed_internal(db, this_abspath,
TRUE /* recurse */,
+ FALSE,
new_revnum, new_date,
rev_author,
NULL,
@@ -496,7 +525,7 @@ svn_wc_process_committed_queue2(svn_wc_c
continue;
SVN_ERR(svn_wc__process_committed_internal(wc_ctx->db,
cqi->local_abspath,
- cqi->recurse, new_revnum,
+ cqi->recurse, TRUE,
new_revnum,
new_date, rev_author,
cqi->new_dav_cache,
cqi->no_unlock,
Modified: subversion/trunk/subversion/libsvn_wc/deprecated.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/deprecated.c?rev=961831&r1=961830&r2=961831&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/deprecated.c (original)
+++ subversion/trunk/subversion/libsvn_wc/deprecated.c Thu Jul 8 16:19:52 2010
@@ -655,7 +655,7 @@ svn_wc_process_committed4(const char *pa
SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
wcprop_changes_hash = svn_wc__prop_array_to_hash(wcprop_changes, pool);
- SVN_ERR(svn_wc__process_committed_internal(db, local_abspath, recurse,
+ SVN_ERR(svn_wc__process_committed_internal(db, local_abspath, recurse, TRUE,
new_revnum, new_date, rev_author,
wcprop_changes_hash,
!remove_lock, !remove_changelist,
Modified: subversion/trunk/subversion/libsvn_wc/wc.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc.h?rev=961831&r1=961830&r2=961831&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc.h Thu Jul 8 16:19:52 2010
@@ -242,11 +242,15 @@ svn_wc__get_committed_queue_pool(const s
* If @a sha1_checksum is non-NULL, use it instead of @a md5_checksum to
* identify the node's pristine text.
* ### NOT YET IMPLEMENTED.
+ *
+ * Set TOP_OF_RECURSE to TRUE to show that this the top of a possibly
+ * recursive commit operation.
*/
svn_error_t *
svn_wc__process_committed_internal(svn_wc__db_t *db,
const char *local_abspath,
svn_boolean_t recurse,
+ svn_boolean_t top_of_recurse,
svn_revnum_t new_revnum,
apr_time_t new_date,
const char *rev_author,
Modified: subversion/trunk/subversion/libsvn_wc/workqueue.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/workqueue.c?rev=961831&r1=961830&r2=961831&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/trunk/subversion/libsvn_wc/workqueue.c Thu Jul 8 16:19:52 2010
@@ -1136,8 +1136,9 @@ log_do_committed(svn_wc__db_t *db,
const char *local_abspath,
const char *tmp_text_base_abspath,
svn_revnum_t new_revision,
- apr_time_t new_date,
- const char *new_author,
+ svn_revnum_t changed_rev,
+ apr_time_t changed_date,
+ const char *changed_author,
const svn_checksum_t *new_checksum,
apr_hash_t *new_dav_cache,
svn_boolean_t keep_changelist,
@@ -1295,8 +1296,8 @@ log_do_committed(svn_wc__db_t *db,
apr_time_t last_mod_time;
SVN_ERR(svn_wc__db_global_commit(db, local_abspath,
- new_revision,
- new_revision, new_date, new_author,
+ new_revision, changed_rev,
+ changed_date, changed_author,
new_checksum,
NULL /* new_children */,
new_dav_cache,
@@ -1380,8 +1381,8 @@ log_do_committed(svn_wc__db_t *db,
/* It's not a file, so it's a directory. */
SVN_ERR(svn_wc__db_global_commit(db, local_abspath,
- new_revision,
- new_revision, new_date, new_author,
+ new_revision, changed_rev,
+ changed_date, changed_author,
NULL /* new_checksum */,
NULL /* new_children */,
new_dav_cache,
@@ -1425,9 +1426,9 @@ run_postcommit(svn_wc__db_t *db,
const svn_skel_t *arg1 = work_item->children->next;
const svn_skel_t *arg5 = work_item->children->next->next->next->next->next;
const char *local_abspath;
- svn_revnum_t new_revision;
- apr_time_t new_date;
- const char *new_author;
+ svn_revnum_t new_revision, changed_rev;
+ apr_time_t changed_date;
+ const char *changed_author;
const svn_checksum_t *new_checksum;
apr_hash_t *new_dav_cache;
svn_boolean_t keep_changelist, no_unlock;
@@ -1436,13 +1437,13 @@ run_postcommit(svn_wc__db_t *db,
local_abspath = apr_pstrmemdup(scratch_pool, arg1->data, arg1->len);
new_revision = (svn_revnum_t)svn_skel__parse_int(arg1->next, scratch_pool);
- new_date = svn_skel__parse_int(arg1->next->next, scratch_pool);
+ changed_date = svn_skel__parse_int(arg1->next->next, scratch_pool);
if (arg1->next->next->next->len == 0)
- new_author = NULL;
+ changed_author = NULL;
else
- new_author = apr_pstrmemdup(scratch_pool,
- arg1->next->next->next->data,
- arg1->next->next->next->len);
+ changed_author = apr_pstrmemdup(scratch_pool,
+ arg1->next->next->next->data,
+ arg1->next->next->next->len);
if (arg5->len == 0)
{
new_checksum = NULL;
@@ -1476,9 +1477,15 @@ run_postcommit(svn_wc__db_t *db,
else
no_unlock = TRUE;
+ if (arg5->next->next->next->next->next)
+ changed_rev = svn_skel__parse_int(arg5->next->next->next->next->next,
+ scratch_pool);
+ else
+ changed_rev = new_revision; /* Behavior before fixing issue #3676 */
+
err = log_do_committed(db, local_abspath, tmp_text_base_abspath,
- new_revision, new_date,
- new_author, new_checksum, new_dav_cache,
+ new_revision, changed_rev, changed_date,
+ changed_author, new_checksum, new_dav_cache,
keep_changelist, no_unlock,
cancel_func, cancel_baton,
scratch_pool);
@@ -1497,8 +1504,9 @@ svn_wc__wq_add_postcommit(svn_wc__db_t *
const char *local_abspath,
const char *tmp_text_base_abspath,
svn_revnum_t new_revision,
- apr_time_t new_date,
- const char *new_author,
+ svn_revnum_t changed_rev,
+ apr_time_t changed_date,
+ const char *changed_author,
const svn_checksum_t *new_checksum,
apr_hash_t *new_dav_cache,
svn_boolean_t keep_changelist,
@@ -1507,6 +1515,7 @@ svn_wc__wq_add_postcommit(svn_wc__db_t *
{
svn_skel_t *work_item = svn_skel__make_empty_list(scratch_pool);
+ svn_skel__prepend_int(changed_rev, work_item, scratch_pool);
svn_skel__prepend_int(no_unlock, work_item, scratch_pool);
svn_skel__prepend_str(tmp_text_base_abspath ? tmp_text_base_abspath : "",
work_item, scratch_pool);
@@ -1528,8 +1537,8 @@ svn_wc__wq_add_postcommit(svn_wc__db_t *
scratch_pool, scratch_pool)
: "",
work_item, scratch_pool);
- svn_skel__prepend_str(new_author ? new_author : "", work_item, scratch_pool);
- svn_skel__prepend_int(new_date, work_item, scratch_pool);
+ svn_skel__prepend_str(changed_author ? changed_author : "", work_item,
scratch_pool);
+ svn_skel__prepend_int(changed_date, work_item, scratch_pool);
svn_skel__prepend_int(new_revision, work_item, scratch_pool);
svn_skel__prepend_str(local_abspath, work_item, scratch_pool);
svn_skel__prepend_str(OP_POSTCOMMIT, work_item, scratch_pool);
Modified: subversion/trunk/subversion/libsvn_wc/workqueue.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/workqueue.h?rev=961831&r1=961830&r2=961831&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/workqueue.h (original)
+++ subversion/trunk/subversion/libsvn_wc/workqueue.h Thu Jul 8 16:19:52 2010
@@ -281,8 +281,9 @@ svn_wc__wq_add_postcommit(svn_wc__db_t *
const char *local_abspath,
const char *tmp_text_base_abspath,
svn_revnum_t new_revision,
- apr_time_t new_date,
- const char *new_author,
+ svn_revnum_t changed_rev,
+ apr_time_t changed_date,
+ const char *changed_author,
const svn_checksum_t *new_checksum,
apr_hash_t *new_dav_cache,
svn_boolean_t keep_changelist,
Modified: subversion/trunk/subversion/tests/cmdline/copy_tests.py
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/copy_tests.py?rev=961831&r1=961830&r2=961831&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/copy_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/copy_tests.py Thu Jul 8 16:19:52
2010
@@ -4633,6 +4633,35 @@ def changed_data_should_match_checkout(s
sbox.build()
wc_dir = sbox.wc_dir
+ A_B_E = os.path.join(wc_dir, 'A', 'B', 'E')
+ E_new = os.path.join(wc_dir, 'E_new')
+
+ verify_dir = sbox.add_wc_path('verify')
+
+ svntest.actions.run_and_verify_svn(None, None, [], 'copy', A_B_E, E_new)
+
+ sbox.simple_commit(wc_dir)
+
+ svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir)
+
+ svntest.actions.run_and_verify_svn(None, None, [], 'co', sbox.repo_url,
verify_dir)
+
+ was_cwd = os.getcwd()
+ os.chdir(verify_dir)
+
+ rv, verify_out, err = main.run_svn(None, 'status', '-v')
+
+ os.chdir(was_cwd)
+ os.chdir(wc_dir)
+ svntest.actions.run_and_verify_svn(None, verify_out, [], 'status', '-v')
+ os.chdir(was_cwd)
+
+# Regression test for issue #3676 for copies including directories
+def changed_dir_data_should_match_checkout(sbox):
+ """changed dir after commit should match checkout"""
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
A_B = os.path.join(wc_dir, 'A', 'B')
B_new = os.path.join(wc_dir, 'B_new')
@@ -4747,7 +4776,8 @@ test_list = [ None,
SkipUnless(copy_broken_symlink, svntest.main.is_posix_os),
move_dir_containing_move,
copy_dir_with_space,
- XFail(changed_data_should_match_checkout),
+ changed_data_should_match_checkout,
+ XFail(changed_dir_data_should_match_checkout),
]
if __name__ == '__main__':