Index: subversion/libsvn_ra_neon/fetch.c =================================================================== --- subversion/libsvn_ra_neon/fetch.c (revision 1060528) +++ subversion/libsvn_ra_neon/fetch.c (working copy) @@ -188,10 +188,11 @@ /* Use an intermediate tmpfile for the REPORT response. */ svn_boolean_t spool_response; - /* A modern server will understand our "send-all" attribute on the - update report request, and will put a "send-all" attribute on - its response. If we see that attribute, we set this to true, - otherwise, it stays false (i.e., it's not a modern server). */ + /* If this report is for a switch, update, or status (but not a + merge/diff), then we made the update report request with the "send-all" + attribute. The server reponds to this by putting a "send-all" attribute + in its response. If we see that attribute, we set this to true, + otherwise, it stays false. */ svn_boolean_t receiving_all; /* Hash mapping 'const char *' paths -> 'const char *' lock tokens. */ @@ -1588,19 +1589,16 @@ /* push the new baton onto the directory baton stack */ push_dir(rb, new_dir_baton, pathbuf, subpool); - /* Property fetching is implied in addition. This flag is only - for parsing old-style reports; it is ignored when talking to - a modern server. */ + /* Property fetching is implied in addition. */ TOP_DIR(rb).fetch_props = TRUE; bc_url = svn_xml_get_attr_value("bc-url", atts); - /* In non-modern report responses, we're just told to fetch the + /* If we are not in send-all mode, we're just told to fetch the props later. In that case, we can at least do a pre-emptive depth-1 propfind on the directory right now; this prevents individual propfinds on added-files later on, thus reducing - the number of network turnarounds (though not by as much as - simply getting a modern report response!). */ + the number of network turnarounds. */ if ((! rb->receiving_all) && bc_url) { apr_hash_t *bc_children; @@ -1711,9 +1709,7 @@ crev, rb->file_pool, &rb->file_baton)); - /* Property fetching is implied in addition. This flag is only - for parsing old-style reports; it is ignored when talking to - a modern server. */ + /* Property fetching is implied in addition. */ rb->fetch_props = TRUE; break; Index: subversion/mod_dav_svn/reports/update.c =================================================================== --- subversion/mod_dav_svn/reports/update.c (revision 1060528) +++ subversion/mod_dav_svn/reports/update.c (working copy) @@ -98,14 +98,8 @@ svn_boolean_t text_changed; /* Did the file's contents change? */ svn_boolean_t added; /* File added? (Implies text_changed.) */ svn_boolean_t copyfrom; /* File copied? */ - apr_array_header_t *changed_props; /* array of const char * prop names */ apr_array_header_t *removed_props; /* array of const char * prop names */ - /* "entry props" */ - const char *committed_rev; - const char *committed_date; - const char *last_author; - } item_baton_t; @@ -413,8 +407,16 @@ return SVN_NO_ERROR; /* ### ack! binary names won't float here! */ - /* If this is a copied file/dir, we can have removed props. */ - if (baton->removed_props && (! baton->added || baton->copyfrom)) + /* If this is a copied file/dir, we can have removed props. + + Old features never die: 1.7+ clients don't require this block because + they never ask for copyfrom information from the server when adding + files created by a copy, but 1.5-1.6 clients will ask for it so we + have to keep sending it. + + See http://svn.haxx.se/dev/archive-2010-09/0265.shtml and + http://subversion.tigris.org/issues/show_bug.cgi?id=3711. */ + if (baton->removed_props && baton->copyfrom) { const char *qname; int i; @@ -429,61 +431,6 @@ } } - if ((! baton->uc->send_all) && baton->changed_props && (! baton->added)) - { - /* Tell the client to fetch all the props */ - SVN_ERR(dav_svn__brigade_puts(baton->uc->bb, baton->uc->output, - "" DEBUG_CR)); - } - - SVN_ERR(dav_svn__brigade_puts(baton->uc->bb, baton->uc->output, "")); - - /* Both modern and non-modern clients need the checksum... */ - if (baton->text_checksum) - { - SVN_ERR(dav_svn__brigade_printf(baton->uc->bb, baton->uc->output, - "%s", - baton->text_checksum)); - } - - /* ...but only non-modern clients want the 3 CR-related properties - sent like here, because they can't handle receiving these special - props inline like any other prop. - ### later on, compress via the 'scattered table' solution as - discussed with gstein. -bmcs */ - if (! baton->uc->send_all) - { - /* ### grrr, these DAV: property names are already #defined in - ra_dav.h, and statically defined in liveprops.c. And now - they're hardcoded here. Isn't there some header file that both - sides of the network can share?? */ - - /* ### special knowledge: svn_repos_dir_delta2 will never send - *removals* of the commit-info "entry props". */ - if (baton->committed_rev) - SVN_ERR(dav_svn__brigade_printf(baton->uc->bb, baton->uc->output, - "%s", - baton->committed_rev)); - - if (baton->committed_date) - SVN_ERR(dav_svn__brigade_printf(baton->uc->bb, baton->uc->output, - "%s", - baton->committed_date)); - - if (baton->last_author) - SVN_ERR(dav_svn__brigade_printf(baton->uc->bb, baton->uc->output, - "%s" - "", - apr_xml_quote_string(baton->pool, - baton->last_author, - 1))); - - } - - /* Close unconditionally, because we sent checksum unconditionally. */ - SVN_ERR(dav_svn__brigade_puts(baton->uc->bb, baton->uc->output, - "" DEBUG_CR)); - if (baton->added) SVN_ERR(dav_svn__brigade_printf(baton->uc->bb, baton->uc->output, "" DEBUG_CR, @@ -646,8 +593,10 @@ if (qname == name) qname = apr_pstrdup(b->pool, name); - - if (b->uc->send_all) + /* Even if we are not in send-all mode we have the prop changes already, + so send them to the client now instead of telling the client to fetch + them later. */ + if (b->uc->send_all || !b->added) { if (value) { @@ -683,56 +632,16 @@ qname)); } } - else /* don't do inline response, just cache prop names for close_helper */ + else if (!value) /* This is an addition in 'skelta' mode so there is no + need for an inline response since property fetching + is implied in addition. We shouldn't need to do + anything, but we must cache property removals, see + note re issue #3711 in close_helper(). */ { - /* For now, store certain entry props, because we'll need to send - them later as standard DAV ("D:") props. ### this should go - away and we should just tunnel those props on through for the - client to deal with. */ -#define NSLEN (sizeof(SVN_PROP_ENTRY_PREFIX) - 1) - if (! strncmp(name, SVN_PROP_ENTRY_PREFIX, NSLEN)) - { - if (strcmp(name, SVN_PROP_ENTRY_COMMITTED_REV) == 0) - { - b->committed_rev = value ? - apr_pstrdup(b->pool, value->data) : NULL; - } - else if (strcmp(name, SVN_PROP_ENTRY_COMMITTED_DATE) == 0) - { - b->committed_date = value ? - apr_pstrdup(b->pool, value->data) : NULL; - } - else if (strcmp(name, SVN_PROP_ENTRY_LAST_AUTHOR) == 0) - { - b->last_author = value ? - apr_pstrdup(b->pool, value->data) : NULL; - } - else if ((strcmp(name, SVN_PROP_ENTRY_LOCK_TOKEN) == 0) - && (! value)) - { - /* We only support delete of lock tokens, not add/modify. */ - if (! b->removed_props) - b->removed_props = apr_array_make(b->pool, 1, sizeof(name)); - APR_ARRAY_PUSH(b->removed_props, const char *) = qname; - } - return SVN_NO_ERROR; - } -#undef NSLEN + if (! b->removed_props) + b->removed_props = apr_array_make(b->pool, 1, sizeof(name)); - if (value) - { - if (! b->changed_props) - b->changed_props = apr_array_make(b->pool, 1, sizeof(name)); - - APR_ARRAY_PUSH(b->changed_props, const char *) = qname; - } - else - { - if (! b->removed_props) - b->removed_props = apr_array_make(b->pool, 1, sizeof(name)); - - APR_ARRAY_PUSH(b->removed_props, const char *) = qname; - } + APR_ARRAY_PUSH(b->removed_props, const char *) = qname; } return SVN_NO_ERROR;