You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by pb...@apache.org on 2010/03/16 19:03:41 UTC
svn commit: r923910 [3/9] - in /subversion/branches/1.6.x-issue3432: ./
build/ build/ac-macros/ build/generator/ contrib/cgi/
contrib/client-side/emacs/ contrib/client-side/svn_load_dirs/
contrib/hook-scripts/ contrib/server-side/ doc/user/ notes/ pack...
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_client/repos_diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_client/repos_diff.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_client/repos_diff.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_client/repos_diff.c Tue Mar 16 18:03:37 2010
@@ -548,7 +548,6 @@ add_directory(const char *path,
struct dir_baton *b;
svn_wc_adm_access_t *adm_access;
svn_wc_notify_state_t state;
- svn_wc_notify_action_t action;
/* ### TODO: support copyfrom? */
@@ -571,47 +570,56 @@ add_directory(const char *path,
(adm_access, &state, &b->tree_conflicted, b->wcpath,
eb->target_revision, eb->diff_cmd_baton));
- if (b->tree_conflicted)
- action = svn_wc_notify_tree_conflict;
- else
- if ((state == svn_wc_notify_state_missing)
- || (state == svn_wc_notify_state_obstructed))
- action = svn_wc_notify_skip;
- else
- action = svn_wc_notify_update_add;
-
+ /* Notifications for directories are done at close_directory time.
+ * But for paths at which the editor drive adds directories, we make an
+ * exception to this rule, so that the path appears in the output before
+ * any children of the newly added directory. Since a deletion at this path
+ * must have happened before this addition, we can safely notify about
+ * replaced directories here, too. */
if (eb->notify_func)
{
+ deleted_path_notify_t *dpn;
svn_wc_notify_t *notify;
- svn_boolean_t is_replace = FALSE;
- deleted_path_notify_t *dpn = apr_hash_get(eb->deleted_paths, b->wcpath,
- APR_HASH_KEY_STRING);
+ svn_wc_notify_action_t action;
+ svn_node_kind_t kind = svn_node_dir;
+
+ /* Find out if a pending delete notification for this path is
+ * still around. */
+ dpn = apr_hash_get(eb->deleted_paths, b->wcpath, APR_HASH_KEY_STRING);
if (dpn)
{
- svn_wc_notify_action_t new_action;
- if (dpn->action == svn_wc_notify_update_delete
- && action == svn_wc_notify_update_add)
- {
- is_replace = TRUE;
- new_action = svn_wc_notify_update_replace;
- }
- else
- new_action = dpn->action;
- notify = svn_wc_create_notify(b->wcpath, new_action, pool);
- notify->kind = dpn->kind;
- notify->content_state = notify->prop_state = dpn->state;
- notify->lock_state = svn_wc_notify_lock_state_inapplicable;
- (*eb->notify_func)(eb->notify_baton, notify, pool);
+ /* If any was found, we will handle the pending 'deleted path
+ * notification' (DPN) here. Remove it from the list. */
apr_hash_set(eb->deleted_paths, b->wcpath,
APR_HASH_KEY_STRING, NULL);
+
+ /* the pending delete might be on a different node kind. */
+ kind = dpn->kind;
+ state = dpn->state;
}
- if (!is_replace)
+ /* Determine what the notification (ACTION) should be.
+ * In case of a pending 'delete', this might become a 'replace'. */
+ if (b->tree_conflicted)
+ action = svn_wc_notify_tree_conflict;
+ else if (dpn)
{
- notify = svn_wc_create_notify(b->wcpath, action, pool);
- notify->kind = svn_node_dir;
- (*eb->notify_func)(eb->notify_baton, notify, pool);
+ if (dpn->action == svn_wc_notify_update_delete)
+ action = svn_wc_notify_update_replace;
+ else
+ /* Note: dpn->action might be svn_wc_notify_tree_conflict */
+ action = dpn->action;
}
+ else if (state == svn_wc_notify_state_missing ||
+ state == svn_wc_notify_state_obstructed)
+ action = svn_wc_notify_skip;
+ else
+ action = svn_wc_notify_update_add;
+
+ notify = svn_wc_create_notify(b->wcpath, action, pool);
+ notify->kind = kind;
+ notify->content_state = notify->prop_state = state;
+ (*eb->notify_func)(eb->notify_baton, notify, pool);
}
return SVN_NO_ERROR;
@@ -803,7 +811,6 @@ close_file(void *file_baton,
struct edit_baton *eb = b->edit_baton;
svn_wc_adm_access_t *adm_access;
svn_error_t *err;
- svn_wc_notify_action_t action;
svn_wc_notify_state_t content_state = svn_wc_notify_state_unknown;
svn_wc_notify_state_t prop_state = svn_wc_notify_state_unknown;
@@ -871,50 +878,54 @@ close_file(void *file_baton,
}
- if (b->tree_conflicted)
- action = svn_wc_notify_tree_conflict;
- else if ((content_state == svn_wc_notify_state_missing)
- || (content_state == svn_wc_notify_state_obstructed))
- action = svn_wc_notify_skip;
- else if (b->added)
- action = svn_wc_notify_update_add;
- else
- action = svn_wc_notify_update_update;
-
if (eb->notify_func)
{
+ deleted_path_notify_t *dpn;
svn_wc_notify_t *notify;
- svn_boolean_t is_replace = FALSE;
- deleted_path_notify_t *dpn = apr_hash_get(eb->deleted_paths, b->wcpath,
- APR_HASH_KEY_STRING);
+ svn_wc_notify_action_t action;
+ svn_node_kind_t kind = svn_node_file;
+
+ /* Find out if a pending delete notification for this path is
+ * still around. */
+ dpn = apr_hash_get(eb->deleted_paths, b->wcpath, APR_HASH_KEY_STRING);
if (dpn)
{
- svn_wc_notify_action_t new_action;
- if (dpn->action == svn_wc_notify_update_delete
- && action == svn_wc_notify_update_add)
- {
- is_replace = TRUE;
- new_action = svn_wc_notify_update_replace;
- }
- else
- new_action = dpn->action;
- notify = svn_wc_create_notify(b->wcpath, new_action, pool);
- notify->kind = dpn->kind;
- notify->content_state = notify->prop_state = dpn->state;
- notify->lock_state = svn_wc_notify_lock_state_inapplicable;
- (*eb->notify_func)(eb->notify_baton, notify, pool);
+ /* If any was found, we will handle the pending 'deleted path
+ * notification' (DPN) here. Remove it from the list. */
apr_hash_set(eb->deleted_paths, b->wcpath,
APR_HASH_KEY_STRING, NULL);
+
+ /* the pending delete might be on a different node kind. */
+ kind = dpn->kind;
+ content_state = prop_state = dpn->state;
}
- if (!is_replace)
+ /* Determine what the notification (ACTION) should be.
+ * In case of a pending 'delete', this might become a 'replace'. */
+ if (b->tree_conflicted)
+ action = svn_wc_notify_tree_conflict;
+ else if (dpn)
{
- notify = svn_wc_create_notify(b->wcpath, action, pool);
- notify->kind = svn_node_file;
- notify->content_state = content_state;
- notify->prop_state = prop_state;
- (*eb->notify_func)(eb->notify_baton, notify, pool);
+ if (dpn->action == svn_wc_notify_update_delete
+ && b->added)
+ action = svn_wc_notify_update_replace;
+ else
+ /* Note: dpn->action might be svn_wc_notify_tree_conflict */
+ action = dpn->action;
}
+ else if ((content_state == svn_wc_notify_state_missing)
+ || (content_state == svn_wc_notify_state_obstructed))
+ action = svn_wc_notify_skip;
+ else if (b->added)
+ action = svn_wc_notify_update_add;
+ else
+ action = svn_wc_notify_update_update;
+
+ notify = svn_wc_create_notify(b->wcpath, action, pool);
+ notify->kind = kind;
+ notify->content_state = content_state;
+ notify->prop_state = prop_state;
+ (*eb->notify_func)(eb->notify_baton, notify, pool);
}
return SVN_NO_ERROR;
@@ -945,8 +956,10 @@ close_directory(void *dir_baton,
if (err && err->apr_err == SVN_ERR_WC_NOT_LOCKED)
{
/* ### maybe try to stat the local b->wcpath? */
- /* If the path doesn't exist, then send a 'skipped' notification. */
- if (eb->notify_func)
+ /* If the path doesn't exist, then send a 'skipped' notification.
+ Don't notify added directories as they triggered notification
+ in add_directory. */
+ if (! b->added && eb->notify_func)
{
svn_wc_notify_t *notify
= svn_wc_create_notify(b->wcpath,
@@ -984,9 +997,8 @@ close_directory(void *dir_baton,
(adm_access, NULL, NULL, NULL,
b->wcpath, b->edit_baton->diff_cmd_baton));
- /* ### Don't notify added directories as they triggered notification
- in add_directory. Does this mean that directory notification
- isn't getting all the information? */
+ /* Don't notify added directories as they triggered notification
+ in add_directory. */
if (!b->added && eb->notify_func)
{
svn_wc_notify_t *notify;
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_client/revisions.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_client/revisions.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_client/revisions.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_client/revisions.c Tue Mar 16 18:03:37 2010
@@ -129,9 +129,12 @@ svn_client__get_revision_number(svn_revn
}
/* Final check -- if our caller provided a youngest revision, and
- the number we wound up with is younger than that revision, we need
- to stick to our caller's idea of "youngest". */
+ the number we wound up with (after talking to the server) is younger
+ than that revision, we need to stick to our caller's idea of "youngest".
+ */
if (youngest_rev
+ && (revision->kind == svn_opt_revision_head
+ || revision->kind == svn_opt_revision_date)
&& SVN_IS_VALID_REVNUM(*youngest_rev)
&& SVN_IS_VALID_REVNUM(*revnum)
&& (*revnum > *youngest_rev))
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_delta/svndiff.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_delta/svndiff.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_delta/svndiff.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_delta/svndiff.c Tue Mar 16 18:03:37 2010
@@ -55,10 +55,23 @@ struct encoder_baton {
apr_pool_t *pool;
};
+/* This is at least as big as the largest size of an integer that
+ encode_int can generate; it is sufficient for creating buffers for
+ it to write into. This assumes that integers are at most 64 bits,
+ and so 10 bytes (with 7 bits of information each) are sufficient to
+ represent them. */
+#define MAX_ENCODED_INT_LEN 10
+/* This is at least as big as the largest size for a single instruction. */
+#define MAX_INSTRUCTION_LEN (2*MAX_ENCODED_INT_LEN+1)
+/* This is at least as big as the largest possible instructions
+ section: in theory, the instructions could be SVN_DELTA_WINDOW_SIZE
+ 1-byte copy-from-source instructions (though this is very unlikely). */
+#define MAX_INSTRUCTION_SECTION_LEN (SVN_DELTA_WINDOW_SIZE*MAX_INSTRUCTION_LEN)
/* Encode VAL into the buffer P using the variable-length svndiff
integer format. Return the incremented value of P after the
- encoded bytes have been written.
+ encoded bytes have been written. P must point to a buffer of size
+ at least MAX_ENCODED_INT_LEN.
This encoding uses the high bit of each byte as a continuation bit
and the other seven bits as data bits. High-order data bits are
@@ -80,7 +93,7 @@ encode_int(char *p, svn_filesize_t val)
svn_filesize_t v;
unsigned char cont;
- assert(val >= 0);
+ SVN_ERR_ASSERT_NO_RETURN(val >= 0);
/* Figure out how many bytes we'll need. */
v = val >> 7;
@@ -91,6 +104,8 @@ encode_int(char *p, svn_filesize_t val)
n++;
}
+ SVN_ERR_ASSERT_NO_RETURN(n <= MAX_ENCODED_INT_LEN);
+
/* Encode the remaining bytes; n is always the number of bytes
coming after the one we're encoding. */
while (--n >= 0)
@@ -107,7 +122,7 @@ encode_int(char *p, svn_filesize_t val)
static void
append_encoded_int(svn_stringbuf_t *header, svn_filesize_t val)
{
- char buf[128], *p;
+ char buf[MAX_ENCODED_INT_LEN], *p;
p = encode_int(buf, val);
svn_stringbuf_appendbytes(header, buf, p - buf);
@@ -163,7 +178,7 @@ window_handler(svn_txdelta_window_t *win
svn_stringbuf_t *i1 = svn_stringbuf_create("", pool);
svn_stringbuf_t *header = svn_stringbuf_create("", pool);
const svn_string_t *newdata;
- char ibuf[128], *ip;
+ char ibuf[MAX_INSTRUCTION_LEN], *ip;
const svn_txdelta_op_t *op;
apr_size_t len;
@@ -341,6 +356,8 @@ decode_file_offset(svn_filesize_t *val,
const unsigned char *p,
const unsigned char *end)
{
+ if (p + MAX_ENCODED_INT_LEN < end)
+ end = p + MAX_ENCODED_INT_LEN;
/* Decode bytes until we're done. */
*val = 0;
while (p < end)
@@ -360,6 +377,8 @@ decode_size(apr_size_t *val,
const unsigned char *p,
const unsigned char *end)
{
+ if (p + MAX_ENCODED_INT_LEN < end)
+ end = p + MAX_ENCODED_INT_LEN;
/* Decode bytes until we're done. */
*val = 0;
while (p < end)
@@ -377,7 +396,7 @@ decode_size(apr_size_t *val,
data is not compressed. */
static svn_error_t *
-zlib_decode(svn_stringbuf_t *in, svn_stringbuf_t *out)
+zlib_decode(svn_stringbuf_t *in, svn_stringbuf_t *out, apr_size_t limit)
{
apr_size_t len;
char *oldplace = in->data;
@@ -385,6 +404,13 @@ zlib_decode(svn_stringbuf_t *in, svn_str
/* First thing in the string is the original length. */
in->data = (char *)decode_size(&len, (unsigned char *)in->data,
(unsigned char *)in->data+in->len);
+ if (in->data == NULL)
+ return svn_error_create(SVN_ERR_SVNDIFF_INVALID_COMPRESSED_DATA, NULL,
+ _("Decompression of svndiff data failed: no size"));
+ if (len > limit)
+ return svn_error_create(SVN_ERR_SVNDIFF_INVALID_COMPRESSED_DATA, NULL,
+ _("Decompression of svndiff data failed: "
+ "size too large"));
/* We need to subtract the size of the encoded original length off the
* still remaining input length. */
in->len -= (in->data - oldplace);
@@ -482,10 +508,10 @@ count_and_verify_instructions(int *ninst
return svn_error_createf
(SVN_ERR_SVNDIFF_INVALID_OPS, NULL,
_("Invalid diff stream: insn %d cannot be decoded"), n);
- else if (op.length <= 0)
+ else if (op.length == 0)
return svn_error_createf
(SVN_ERR_SVNDIFF_INVALID_OPS, NULL,
- _("Invalid diff stream: insn %d has non-positive length"), n);
+ _("Invalid diff stream: insn %d has length zero"), n);
else if (op.length > tview_len - tpos)
return svn_error_createf
(SVN_ERR_SVNDIFF_INVALID_OPS, NULL,
@@ -494,7 +520,8 @@ count_and_verify_instructions(int *ninst
switch (op.action_code)
{
case svn_txdelta_source:
- if (op.length > sview_len - op.offset)
+ if (op.length > sview_len - op.offset ||
+ op.offset > sview_len)
return svn_error_createf
(SVN_ERR_SVNDIFF_INVALID_OPS, NULL,
_("Invalid diff stream: "
@@ -560,11 +587,11 @@ decode_window(svn_txdelta_window_t *wind
instin = svn_stringbuf_ncreate((const char *)data, insend - data, pool);
instout = svn_stringbuf_create("", pool);
- SVN_ERR(zlib_decode(instin, instout));
+ SVN_ERR(zlib_decode(instin, instout, MAX_INSTRUCTION_SECTION_LEN));
ndin = svn_stringbuf_ncreate((const char *)insend, newlen, pool);
ndout = svn_stringbuf_create("", pool);
- SVN_ERR(zlib_decode(ndin, ndout));
+ SVN_ERR(zlib_decode(ndin, ndout, SVN_DELTA_WINDOW_SIZE));
newlen = ndout->len;
data = (unsigned char *)instout->data;
@@ -680,6 +707,14 @@ write_handler(void *baton,
if (p == NULL)
return SVN_NO_ERROR;
+ if (tview_len > SVN_DELTA_WINDOW_SIZE ||
+ sview_len > SVN_DELTA_WINDOW_SIZE ||
+ /* for svndiff1, newlen includes the original length */
+ newlen > SVN_DELTA_WINDOW_SIZE + MAX_ENCODED_INT_LEN ||
+ inslen > MAX_INSTRUCTION_SECTION_LEN)
+ return svn_error_create(SVN_ERR_SVNDIFF_CORRUPT_WINDOW, NULL,
+ _("Svndiff contains a too-large window"));
+
/* Check for integer overflow. */
if (sview_offset < 0 || inslen + newlen < inslen
|| sview_len + tview_len < sview_len
@@ -836,6 +871,14 @@ read_window_header(svn_stream_t *stream,
SVN_ERR(read_one_size(inslen, stream));
SVN_ERR(read_one_size(newlen, stream));
+ if (*tview_len > SVN_DELTA_WINDOW_SIZE ||
+ *sview_len > SVN_DELTA_WINDOW_SIZE ||
+ /* for svndiff1, newlen includes the original length */
+ *newlen > SVN_DELTA_WINDOW_SIZE + MAX_ENCODED_INT_LEN ||
+ *inslen > MAX_INSTRUCTION_SECTION_LEN)
+ return svn_error_create(SVN_ERR_SVNDIFF_CORRUPT_WINDOW, NULL,
+ _("Svndiff contains a too-large window"));
+
/* Check for integer overflow. */
if (*sview_offset < 0 || *inslen + *newlen < *inslen
|| *sview_len + *tview_len < *sview_len
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_delta/text_delta.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_delta/text_delta.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_delta/text_delta.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_delta/text_delta.c Tue Mar 16 18:03:37 2010
@@ -543,7 +543,7 @@ svn_txdelta_target_push(svn_txdelta_wind
/* Functions for applying deltas. */
/* Ensure that BUF has enough space for VIEW_LEN bytes. */
-static APR_INLINE void
+static APR_INLINE svn_error_t *
size_buffer(char **buf, apr_size_t *buf_size,
apr_size_t view_len, apr_pool_t *pool)
{
@@ -552,8 +552,11 @@ size_buffer(char **buf, apr_size_t *buf_
*buf_size *= 2;
if (*buf_size < view_len)
*buf_size = view_len;
+ SVN_ERR_ASSERT(APR_ALIGN_DEFAULT(*buf_size) >= *buf_size);
*buf = apr_palloc(pool, *buf_size);
}
+
+ return SVN_NO_ERROR;
}
@@ -654,7 +657,7 @@ apply_window(svn_txdelta_window_t *windo
>= ab->sbuf_offset + ab->sbuf_len)));
/* Make sure there's enough room in the target buffer. */
- size_buffer(&ab->tbuf, &ab->tbuf_size, window->tview_len, ab->pool);
+ SVN_ERR(size_buffer(&ab->tbuf, &ab->tbuf_size, window->tview_len, ab->pool));
/* Prepare the source buffer for reading from the input stream. */
if (window->sview_offset != ab->sbuf_offset
@@ -663,7 +666,8 @@ apply_window(svn_txdelta_window_t *windo
char *old_sbuf = ab->sbuf;
/* Make sure there's enough room. */
- size_buffer(&ab->sbuf, &ab->sbuf_size, window->sview_len, ab->pool);
+ SVN_ERR(size_buffer(&ab->sbuf, &ab->sbuf_size, window->sview_len,
+ ab->pool));
/* If the existing view overlaps with the new view, copy the
* overlap to the beginning of the new buffer. */
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_fs_fs/fs_fs.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_fs_fs/fs_fs.c Tue Mar 16 18:03:37 2010
@@ -790,7 +790,7 @@ get_writable_proto_rev_body(svn_fs_t *fs
if (!err)
{
apr_off_t offset = 0;
- err = svn_io_file_seek(*file, APR_END, &offset, 0);
+ err = svn_io_file_seek(*file, APR_END, &offset, pool);
}
if (err)
@@ -1419,6 +1419,9 @@ svn_fs_fs__hotcopy(const char *src_path,
/* Copy the uuid. */
SVN_ERR(svn_io_dir_file_copy(src_path, dst_path, PATH_UUID, pool));
+ /* Copy the config. */
+ SVN_ERR(svn_io_dir_file_copy(src_path, dst_path, PATH_CONFIG, pool));
+
/* Copy the min unpacked rev, and read its value. */
if (format >= SVN_FS_FS__MIN_PACKED_FORMAT)
{
@@ -4375,7 +4378,8 @@ svn_fs_fs__change_txn_props(svn_fs_txn_t
apr_array_header_t *props,
apr_pool_t *pool)
{
- apr_file_t *txn_prop_file;
+ const char *txn_prop_filename;
+ svn_stringbuf_t *buf;
svn_stream_t *stream;
apr_hash_t *txn_prop = apr_hash_make(pool);
int i;
@@ -4400,15 +4404,19 @@ svn_fs_fs__change_txn_props(svn_fs_txn_t
/* Create a new version of the file and write out the new props. */
/* Open the transaction properties file. */
- SVN_ERR(svn_io_file_open(&txn_prop_file,
- path_txn_props(txn->fs, txn->id, pool),
- APR_WRITE | APR_CREATE | APR_TRUNCATE
- | APR_BUFFERED, APR_OS_DEFAULT, pool));
-
- stream = svn_stream_from_aprfile2(txn_prop_file, FALSE, pool);
+ buf = svn_stringbuf_create_ensure(1024, pool);
+ stream = svn_stream_from_stringbuf(buf, pool);
SVN_ERR(svn_hash_write2(txn_prop, stream, SVN_HASH_TERMINATOR, pool));
-
- return svn_stream_close(stream);
+ SVN_ERR(svn_stream_close(stream));
+ SVN_ERR(svn_io_write_unique(&txn_prop_filename,
+ path_txn_dir(txn->fs, txn->id, pool),
+ buf->data,
+ buf->len,
+ svn_io_file_del_none,
+ pool));
+ return svn_io_file_rename(txn_prop_filename,
+ path_txn_props(txn->fs, txn->id, pool),
+ pool);
}
svn_error_t *
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_neon/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_neon/commit.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_neon/commit.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_neon/commit.c Tue Mar 16 18:03:37 2010
@@ -42,6 +42,7 @@
#include "ra_neon.h"
+#define APPLY_TO_VERSION "<D:apply-to-version/>"
/*
** version_rsrc_t: identify the relevant pieces of a resource on the server
**
@@ -393,6 +394,7 @@ static svn_error_t * do_checkout(commit_
const char *vsn_url,
svn_boolean_t allow_404,
const char *token,
+ svn_boolean_t is_vcc,
int *code,
const char **locn,
apr_pool_t *pool)
@@ -417,7 +419,9 @@ static svn_error_t * do_checkout(commit_
"<D:checkout xmlns:D=\"DAV:\">"
"<D:activity-set>"
"<D:href>%s</D:href>"
- "</D:activity-set></D:checkout>", cc->activity_url);
+ "</D:activity-set>%s</D:checkout>",
+ cc->activity_url,
+ is_vcc ? APPLY_TO_VERSION: "");
if (token)
{
@@ -453,6 +457,7 @@ static svn_error_t * checkout_resource(c
version_rsrc_t *rsrc,
svn_boolean_t allow_404,
const char *token,
+ svn_boolean_t is_vcc,
apr_pool_t *pool)
{
int code;
@@ -467,7 +472,8 @@ static svn_error_t * checkout_resource(c
}
/* check out the Version Resource */
- err = do_checkout(cc, rsrc->vsn_url, allow_404, token, &code, &locn, pool);
+ err = do_checkout(cc, rsrc->vsn_url, allow_404, token,
+ is_vcc, &code, &locn, pool);
/* possibly run the request again, with a re-fetched Version Resource */
if (err == NULL && allow_404 && code == 404)
@@ -478,7 +484,8 @@ static svn_error_t * checkout_resource(c
SVN_ERR(get_version_url(cc, NULL, rsrc, TRUE, pool));
/* do it again, but don't allow a 404 this time */
- err = do_checkout(cc, rsrc->vsn_url, FALSE, token, &code, &locn, pool);
+ err = do_checkout(cc, rsrc->vsn_url, FALSE, token,
+ is_vcc, &code, &locn, pool);
}
/* special-case when conflicts occur */
@@ -705,7 +712,8 @@ static svn_error_t * commit_delete_entry
}
/* get the URL to the working collection */
- SVN_ERR(checkout_resource(parent->cc, parent->rsrc, TRUE, NULL, pool));
+ SVN_ERR(checkout_resource(parent->cc, parent->rsrc, TRUE,
+ NULL, FALSE, pool));
/* create the URL for the child resource */
child = svn_path_url_add_component(parent->rsrc->wr_url, name, pool);
@@ -841,7 +849,8 @@ static svn_error_t * commit_add_dir(cons
/* check out the parent resource so that we can create the new collection
as one of its children. */
- SVN_ERR(checkout_resource(parent->cc, parent->rsrc, TRUE, NULL, dir_pool));
+ SVN_ERR(checkout_resource(parent->cc, parent->rsrc, TRUE,
+ NULL, FALSE, dir_pool));
/* create a child object that contains all the resource urls */
child = apr_pcalloc(dir_pool, sizeof(*child));
@@ -953,7 +962,7 @@ static svn_error_t * commit_change_dir_p
record_prop_change(dir->pool, dir, name, value);
/* do the CHECKOUT sooner rather than later */
- SVN_ERR(checkout_resource(dir->cc, dir->rsrc, TRUE, NULL, pool));
+ SVN_ERR(checkout_resource(dir->cc, dir->rsrc, TRUE, NULL, FALSE, pool));
/* Add this path to the valid targets hash. */
add_valid_target(dir->cc, dir->rsrc->local_path, svn_nonrecursive);
@@ -994,7 +1003,8 @@ static svn_error_t * commit_add_file(con
*/
/* Do the parent CHECKOUT first */
- SVN_ERR(checkout_resource(parent->cc, parent->rsrc, TRUE, NULL, workpool));
+ SVN_ERR(checkout_resource(parent->cc, parent->rsrc, TRUE,
+ NULL, FALSE, workpool));
/* Construct a file_baton that contains all the resource urls. */
file = apr_pcalloc(file_pool, sizeof(*file));
@@ -1133,7 +1143,7 @@ static svn_error_t * commit_open_file(co
/* do the CHECKOUT now. we'll PUT the new file contents later on. */
SVN_ERR(checkout_resource(parent->cc, file->rsrc, TRUE,
- file->token, workpool));
+ file->token, FALSE, workpool));
/* ### wait for apply_txdelta before doing a PUT. it might arrive a
### "long time" from now. certainly after many other operations, so
@@ -1240,7 +1250,8 @@ static svn_error_t * commit_change_file_
record_prop_change(file->pool, file, name, value);
/* do the CHECKOUT sooner rather than later */
- SVN_ERR(checkout_resource(file->cc, file->rsrc, TRUE, file->token, pool));
+ SVN_ERR(checkout_resource(file->cc, file->rsrc, TRUE,
+ file->token, FALSE, pool));
/* Add this path to the valid targets hash. */
add_valid_target(file->cc, file->rsrc->local_path, svn_nonrecursive);
@@ -1376,8 +1387,7 @@ static svn_error_t * apply_revprops(comm
apr_pool_t *pool)
{
const char *vcc;
- const svn_string_t *baseline_url;
- version_rsrc_t baseline_rsrc = { SVN_INVALID_REVNUM };
+ version_rsrc_t vcc_rsrc = { SVN_INVALID_REVNUM };
svn_error_t *err = NULL;
int retry_count = 5;
@@ -1387,24 +1397,17 @@ static svn_error_t * apply_revprops(comm
/* fetch the DAV:version-controlled-configuration from the session's URL */
SVN_ERR(svn_ra_neon__get_vcc(&vcc, cc->ras, cc->ras->root.path, pool));
- /* ### we should use DAV:apply-to-version on the CHECKOUT so we can skip
- ### retrieval of the baseline */
do {
svn_error_clear(err);
- /* Get the latest baseline from VCC's DAV:checked-in property.
- This should give us the HEAD revision of the moment. */
- SVN_ERR(svn_ra_neon__get_one_prop(&baseline_url, cc->ras,
- vcc, NULL,
- &svn_ra_neon__checked_in_prop, pool));
- baseline_rsrc.pool = pool;
- baseline_rsrc.vsn_url = baseline_url->data;
+ vcc_rsrc.pool = pool;
+ vcc_rsrc.vsn_url = vcc;
/* To set the revision properties, we must checkout the latest baseline
and get back a mutable "working" baseline. */
- err = checkout_resource(cc, &baseline_rsrc, FALSE, NULL, pool);
+ err = checkout_resource(cc, &vcc_rsrc, FALSE, NULL, TRUE, pool);
/* There's a small chance of a race condition here, if apache is
experiencing heavy commit concurrency or if the network has
@@ -1424,7 +1427,7 @@ static svn_error_t * apply_revprops(comm
if (err)
return err;
- return svn_ra_neon__do_proppatch(cc->ras, baseline_rsrc.wr_url, revprop_table,
+ return svn_ra_neon__do_proppatch(cc->ras, vcc_rsrc.wr_url, revprop_table,
NULL, NULL, pool);
}
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/blame.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/blame.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/blame.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/blame.c Tue Mar 16 18:03:37 2010
@@ -432,8 +432,8 @@ svn_ra_serf__get_file_revs(svn_ra_sessio
svn_ra_serf__add_close_tag_buckets(buckets, session->bkt_alloc,
"S:file-revs-report");
- SVN_ERR(svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url,
- session, session->repos_url.path,
+ SVN_ERR(svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url, session,
+ NULL, session->repos_url.path,
end, NULL, pool));
req_url = svn_path_url_add_component(basecoll_url, relative_url, pool);
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/commit.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/commit.c Tue Mar 16 18:03:37 2010
@@ -82,8 +82,8 @@ typedef struct {
/* The checked-in root to base CHECKOUTs from */
const char *checked_in_url;
- /* The root baseline collection */
- const char *baseline_url;
+ /* vcc url */
+ const char *vcc_url;
/* Deleted files - so we can detect delete+add (replace) ops. */
apr_hash_t *deleted_entries;
@@ -248,6 +248,7 @@ create_checkout_body(void *baton,
svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:href");
svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:activity-set");
+ svn_ra_serf__add_tag_buckets(body_bkt, "D:apply-to-version", NULL, alloc);
svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:checkout");
return body_bkt;
@@ -376,7 +377,7 @@ checkout_dir(dir_context_t *dir)
*/
if (!dir->parent_dir && !dir->commit->baseline)
{
- checkout_ctx->checkout_url = dir->commit->baseline_url;
+ checkout_ctx->checkout_url = dir->commit->vcc_url;
dir->commit->baseline = checkout_ctx;
}
else
@@ -469,13 +470,33 @@ get_version_url(const char **checked_in_
{
svn_ra_serf__propfind_context_t *propfind_ctx;
apr_hash_t *props;
+ const char *propfind_url;
props = apr_hash_make(pool);
propfind_ctx = NULL;
- svn_ra_serf__deliver_props(&propfind_ctx, props, session,
- conn, session->repos_url.path,
- base_revision, "0",
+ if (SVN_IS_VALID_REVNUM(base_revision))
+ {
+ const char *bc_url, *bc_relpath;
+
+ /* mod_dav_svn can't handle the "Label:" header that
+ svn_ra_serf__deliver_props() is going to try to use for
+ this lookup, so we'll do things the hard(er) way, by
+ looking up the version URL from a resource in the
+ baseline collection. */
+ SVN_ERR(svn_ra_serf__get_baseline_info(&bc_url, &bc_relpath,
+ session, conn,
+ session->repos_url.path,
+ base_revision, NULL, pool));
+ propfind_url = svn_path_url_add_component2(bc_url, bc_relpath, pool);
+ }
+ else
+ {
+ propfind_url = session->repos_url.path;
+ }
+
+ svn_ra_serf__deliver_props(&propfind_ctx, props, session, conn,
+ propfind_url, base_revision, "0",
checked_in_props, FALSE, NULL, pool);
SVN_ERR(svn_ra_serf__wait_for_props(propfind_ctx, session, pool));
@@ -483,7 +504,7 @@ get_version_url(const char **checked_in_
/* We wouldn't get here if the url wasn't found (404), so the checked-in
property should have been set. */
root_checkout =
- svn_ra_serf__get_ver_prop(props, session->repos_url.path,
+ svn_ra_serf__get_ver_prop(props, propfind_url,
base_revision, "DAV:", "checked-in");
if (!root_checkout)
@@ -966,14 +987,11 @@ open_root(void *edit_baton,
{
commit_context_t *ctx = edit_baton;
svn_ra_serf__options_context_t *opt_ctx;
- svn_ra_serf__propfind_context_t *propfind_ctx;
svn_ra_serf__handler_t *handler;
svn_ra_serf__simple_request_context_t *mkact_ctx;
proppatch_context_t *proppatch_ctx;
dir_context_t *dir;
const char *activity_str;
- const char *vcc_url;
- apr_hash_t *props;
apr_hash_index_t *hi;
svn_error_t *err;
@@ -1036,31 +1054,11 @@ open_root(void *edit_baton,
ctx->session->repos_url.hostinfo);
}
- SVN_ERR(svn_ra_serf__discover_root(&vcc_url, NULL,
+ SVN_ERR(svn_ra_serf__discover_root(&(ctx->vcc_url), NULL,
ctx->session, ctx->conn,
ctx->session->repos_url.path,
ctx->pool));
- /* Now go fetch our VCC and baseline so we can do a CHECKOUT. */
- props = apr_hash_make(ctx->pool);
- propfind_ctx = NULL;
- svn_ra_serf__deliver_props(&propfind_ctx, props, ctx->session,
- ctx->conn, vcc_url, SVN_INVALID_REVNUM, "0",
- checked_in_props, FALSE, NULL, ctx->pool);
-
- SVN_ERR(svn_ra_serf__wait_for_props(propfind_ctx, ctx->session, ctx->pool));
-
- ctx->baseline_url = svn_ra_serf__get_ver_prop(props, vcc_url,
- SVN_INVALID_REVNUM,
- "DAV:", "checked-in");
-
- if (!ctx->baseline_url)
- {
- return svn_error_create(SVN_ERR_RA_DAV_OPTIONS_REQ_FAILED, NULL,
- _("The OPTIONS response did not include the "
- "requested checked-in value"));
- }
-
dir = apr_pcalloc(dir_pool, sizeof(*dir));
dir->pool = dir_pool;
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/get_deleted_rev.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/get_deleted_rev.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/get_deleted_rev.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/get_deleted_rev.c Tue Mar 16 18:03:37 2010
@@ -197,7 +197,7 @@ svn_ra_serf__get_deleted_rev(svn_ra_sess
drev_ctx->done = FALSE;
SVN_ERR(svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url,
- ras, NULL, peg_revision, NULL,
+ ras, NULL, NULL, peg_revision, NULL,
pool));
req_url = svn_path_url_add_component(basecoll_url, relative_url, pool);
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/getlocations.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/getlocations.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/getlocations.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/getlocations.c Tue Mar 16 18:03:37 2010
@@ -225,8 +225,8 @@ svn_ra_serf__get_locations(svn_ra_sessio
svn_ra_serf__add_close_tag_buckets(buckets, session->bkt_alloc,
"S:get-locations");
- SVN_ERR(svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url,
- session, NULL, peg_revision, NULL,
+ SVN_ERR(svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url, session,
+ NULL, NULL, peg_revision, NULL,
pool));
req_url = svn_path_url_add_component(basecoll_url, relative_url, pool);
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/getlocationsegments.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/getlocationsegments.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/getlocationsegments.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/getlocationsegments.c Tue Mar 16 18:03:37 2010
@@ -173,9 +173,8 @@ svn_ra_serf__get_location_segments(svn_r
svn_ra_serf__add_close_tag_buckets(buckets, session->bkt_alloc,
"S:get-location-segments");
- SVN_ERR(svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url,
- session, NULL, peg_revision, NULL,
- pool));
+ SVN_ERR(svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url, session,
+ NULL, NULL, peg_revision, NULL, pool));
req_url = svn_path_url_add_component(basecoll_url, relative_url, pool);
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/log.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/log.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/log.c Tue Mar 16 18:03:37 2010
@@ -573,9 +573,8 @@ svn_ra_serf__get_log(svn_ra_session_t *r
*/
peg_rev = (start > end) ? start : end;
- SVN_ERR(svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url,
- session, NULL, peg_rev, NULL,
- pool));
+ SVN_ERR(svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url, session,
+ NULL, NULL, peg_rev, NULL, pool));
req_url = svn_path_url_add_component(basecoll_url, relative_url, pool);
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/mergeinfo.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/mergeinfo.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/mergeinfo.c Tue Mar 16 18:03:37 2010
@@ -237,9 +237,8 @@ svn_ra_serf__get_mergeinfo(svn_ra_sessio
const char *relative_url, *basecoll_url;
const char *path;
- SVN_ERR(svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url,
- session, NULL, revision,
- NULL, pool));
+ SVN_ERR(svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url, session,
+ NULL, NULL, revision, NULL, pool));
path = svn_path_url_add_component(basecoll_url, relative_url, pool);
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/property.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/property.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/property.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/property.c Tue Mar 16 18:03:37 2010
@@ -928,6 +928,7 @@ svn_error_t *
svn_ra_serf__get_baseline_info(const char **bc_url,
const char **bc_relative,
svn_ra_serf__session_t *session,
+ svn_ra_serf__connection_t *conn,
const char *url,
svn_revnum_t revision,
svn_revnum_t *latest_revnum,
@@ -940,12 +941,17 @@ svn_ra_serf__get_baseline_info(const cha
if (! url)
url = session->repos_url.path;
+ /* If the caller didn't provide a specific connection for us to use,
+ we'll use the default one. */
+ if (! conn)
+ conn = session->conns[0];
+
SVN_ERR(svn_ra_serf__discover_root(&vcc_url, &relative_url,
- session, session->conns[0], url, pool));
+ session, conn, url, pool));
if (revision != SVN_INVALID_REVNUM)
{
- SVN_ERR(svn_ra_serf__retrieve_props(props, session, session->conns[0],
+ SVN_ERR(svn_ra_serf__retrieve_props(props, session, conn,
vcc_url, revision, "0",
baseline_props, pool));
basecoll_url = svn_ra_serf__get_ver_prop(props, vcc_url, revision,
@@ -953,7 +959,7 @@ svn_ra_serf__get_baseline_info(const cha
}
else
{
- SVN_ERR(svn_ra_serf__retrieve_props(props, session, session->conns[0],
+ SVN_ERR(svn_ra_serf__retrieve_props(props, session, conn,
vcc_url, revision, "0",
checked_in_props, pool));
baseline_url = svn_ra_serf__get_ver_prop(props, vcc_url, revision,
@@ -965,7 +971,7 @@ svn_ra_serf__get_baseline_info(const cha
"requested checked-in value"));
}
- SVN_ERR(svn_ra_serf__retrieve_props(props, session, session->conns[0],
+ SVN_ERR(svn_ra_serf__retrieve_props(props, session, conn,
baseline_url, revision, "0",
baseline_props, pool));
basecoll_url = svn_ra_serf__get_ver_prop(props, baseline_url, revision,
@@ -979,6 +985,8 @@ svn_ra_serf__get_baseline_info(const cha
"requested baseline-collection value"));
}
+ basecoll_url = svn_path_canonicalize(basecoll_url, pool);
+
if (latest_revnum)
{
const char *version_name;
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/ra_serf.h?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/ra_serf.h Tue Mar 16 18:03:37 2010
@@ -1041,12 +1041,16 @@ svn_ra_serf__discover_root(const char **
* REVISION was set to SVN_INVALID_REVNUM, this will return the current
* HEAD revision.
*
+ * If non-NULL, use CONN for communications with the server;
+ * otherwise, use the default connection.
+ *
* Use POOL for all allocations.
*/
svn_error_t *
svn_ra_serf__get_baseline_info(const char **bc_url,
const char **bc_relative,
svn_ra_serf__session_t *session,
+ svn_ra_serf__connection_t *conn,
const char *url,
svn_revnum_t revision,
svn_revnum_t *latest_revnum,
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/serf.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_serf/serf.c Tue Mar 16 18:03:37 2010
@@ -628,8 +628,8 @@ svn_ra_serf__get_latest_revnum(svn_ra_se
const char *relative_url, *basecoll_url;
svn_ra_serf__session_t *session = ra_session->priv;
- return svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url,
- session, session->repos_url.path,
+ return svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url, session,
+ NULL, session->repos_url.path,
SVN_INVALID_REVNUM, latest_revnum,
pool);
}
@@ -717,7 +717,7 @@ fetch_path_props(svn_ra_serf__propfind_c
const char *relative_url, *basecoll_url;
SVN_ERR(svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url,
- session, path,
+ session, NULL, path,
revision, NULL, pool));
/* We will try again with our new path; however, we're now
@@ -988,7 +988,7 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
const char *relative_url, *basecoll_url;
SVN_ERR(svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url,
- session, path, revision,
+ session, NULL, path, revision,
fetched_rev, pool));
path = svn_path_url_add_component(basecoll_url, relative_url, pool);
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_svn/client.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_svn/client.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_svn/client.c Tue Mar 16 18:03:37 2010
@@ -373,7 +373,16 @@ static svn_error_t *find_tunnel_agent(co
/* We have one predefined tunnel scheme, if it isn't overridden by config. */
if (!val && strcmp(tunnel, "ssh") == 0)
- val = "$SVN_SSH ssh";
+ {
+ /* Killing the tunnel agent with SIGTERM leads to unsightly
+ * stderr output from ssh, unless we pass -q.
+ * The "-q" option to ssh is widely supported: all versions of
+ * OpenSSH have it, the old ssh-1.x and the 2.x, 3.x ssh.com
+ * versions have it too. If the user is using some other ssh
+ * implementation that doesn't accept it, they can override it
+ * in the [tunnels] section of the config. */
+ val = "$SVN_SSH ssh -q";
+ }
if (!val || !*val)
return svn_error_createf(SVN_ERR_BAD_URL, NULL,
@@ -448,6 +457,7 @@ static svn_error_t *make_tunnel(const ch
apr_status_t status;
apr_proc_t *proc;
apr_procattr_t *attr;
+ svn_error_t *err;
status = apr_procattr_create(&attr, pool);
if (status == APR_SUCCESS)
@@ -462,6 +472,37 @@ static svn_error_t *make_tunnel(const ch
if (status != APR_SUCCESS)
return svn_error_wrap_apr(status, _("Can't create tunnel"));
+ /* Arrange for the tunnel agent to get a SIGTERM on pool
+ * cleanup. This is a little extreme, but the alternatives
+ * weren't working out.
+ *
+ * Closing the pipes and waiting for the process to die
+ * was prone to mysterious hangs which are difficult to
+ * diagnose (e.g. svnserve dumps core due to unrelated bug;
+ * sshd goes into zombie state; ssh connection is never
+ * closed; ssh never terminates).
+ * See also the long dicussion in issue #2580 if you really
+ * want to know various reasons for these problems and
+ * the different opinions on this issue.
+ *
+ * On Win32, APR does not support KILL_ONLY_ONCE. It only has
+ * KILL_ALWAYS and KILL_NEVER. Other modes are converted to
+ * KILL_ALWAYS, which immediately calls TerminateProcess().
+ * This instantly kills the tunnel, leaving sshd and svnserve
+ * on a remote machine running indefinitely. These processes
+ * accumulate. The problem is most often seen with a fast client
+ * machine and a modest internet connection, as the tunnel
+ * is killed before being able to gracefully complete the
+ * session. In that case, svn is unusable 100% of the time on
+ * the windows machine. Thus, on Win32, we use KILL_NEVER and
+ * take the lesser of two evils.
+ */
+#ifdef WIN32
+ apr_pool_note_subprocess(pool, proc, APR_KILL_NEVER);
+#else
+ apr_pool_note_subprocess(pool, proc, APR_KILL_ONLY_ONCE);
+#endif
+
/* APR pipe objects inherit by default. But we don't want the
* tunnel agent's pipes held open by future child processes
* (such as other ra_svn sessions), so turn that off. */
@@ -470,7 +511,14 @@ static svn_error_t *make_tunnel(const ch
/* Guard against dotfile output to stdout on the server. */
*conn = svn_ra_svn_create_conn(NULL, proc->out, proc->in, pool);
- SVN_ERR(svn_ra_svn_skip_leading_garbage(*conn, pool));
+ err = svn_ra_svn_skip_leading_garbage(*conn, pool);
+ if (err)
+ return svn_error_quick_wrap(
+ err,
+ _("To better debug SSH connection problems, remove the -q "
+ "option from 'ssh' in the [tunnels] section of your "
+ "Subversion configuration file."));
+
return SVN_NO_ERROR;
}
@@ -2202,6 +2250,7 @@ ra_svn_replay_range(svn_ra_session_t *se
svn_ra_svn__session_baton_t *sess = session->priv;
apr_pool_t *iterpool;
svn_revnum_t rev;
+ svn_boolean_t drive_aborted = FALSE;
SVN_ERR(svn_ra_svn_write_cmd(sess->conn, pool, "replay-range", "rrrb",
start_revision, end_revision,
@@ -2237,7 +2286,14 @@ ra_svn_replay_range(svn_ra_session_t *se
iterpool));
SVN_ERR(svn_ra_svn_drive_editor2(sess->conn, iterpool,
editor, edit_baton,
- NULL, TRUE));
+ &drive_aborted, TRUE));
+ /* If drive_editor2() aborted the commit, do NOT try to call
+ revfinish_func and commit the transaction! */
+ if (drive_aborted) {
+ svn_pool_destroy(iterpool);
+ return svn_error_create(SVN_ERR_RA_SVN_IO_ERROR, NULL,
+ _("Error while replaying commit"));
+ }
SVN_ERR(revfinish_func(rev, replay_baton,
editor, edit_baton,
rev_props,
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_svn/cyrus_auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_svn/cyrus_auth.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_svn/cyrus_auth.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_svn/cyrus_auth.c Tue Mar 16 18:03:37 2010
@@ -351,10 +351,8 @@ static svn_error_t *new_sasl_ctx(sasl_co
sasl_errdetail(*sasl_ctx));
}
- /* Set security properties. Don't allow PLAIN or LOGIN, since we
- don't support TLS yet. */
+ /* Set security properties. */
svn_ra_svn__default_secprops(&secprops);
- secprops.security_flags = SASL_SEC_NOPLAINTEXT;
sasl_setprop(*sasl_ctx, SASL_SEC_PROPS, &secprops);
return SVN_NO_ERROR;
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_svn/marshal.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_svn/marshal.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_svn/marshal.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_ra_svn/marshal.c Tue Mar 16 18:03:37 2010
@@ -997,17 +997,24 @@ svn_error_t *svn_ra_svn_write_cmd_respon
svn_error_t *svn_ra_svn_write_cmd_failure(svn_ra_svn_conn_t *conn,
apr_pool_t *pool, svn_error_t *err)
{
+ char buffer[128];
SVN_ERR(svn_ra_svn_start_list(conn, pool));
SVN_ERR(svn_ra_svn_write_word(conn, pool, "failure"));
SVN_ERR(svn_ra_svn_start_list(conn, pool));
for (; err; err = err->child)
{
+ const char *msg = err->message;
+
+ if (msg == NULL)
+ msg = svn_strerror(err->apr_err, buffer, sizeof(buffer));
+
/* The message string should have been optional, but we can't
easily change that, so marshal nonexistent messages as "". */
SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "nccn",
(apr_uint64_t) err->apr_err,
- err->message ? err->message : "",
- err->file, (apr_uint64_t) err->line));
+ msg ? msg : "",
+ err->file ? err->file : "",
+ (apr_uint64_t) err->line));
}
SVN_ERR(svn_ra_svn_end_list(conn, pool));
SVN_ERR(svn_ra_svn_end_list(conn, pool));
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_repos/dump.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_repos/dump.c Tue Mar 16 18:03:37 2010
@@ -1213,6 +1213,7 @@ svn_repos_verify_fs(svn_repos_t *repos,
const svn_delta_editor_t *cancel_editor;
void *cancel_edit_baton;
svn_fs_root_t *to_root;
+ apr_hash_t *props;
svn_pool_clear(iterpool);
@@ -1234,6 +1235,7 @@ svn_repos_verify_fs(svn_repos_t *repos,
SVN_ERR(svn_repos_replay2(to_root, "", SVN_INVALID_REVNUM, FALSE,
cancel_editor, cancel_edit_baton,
NULL, NULL, iterpool));
+ SVN_ERR(svn_fs_revision_proplist(&props, fs, rev, iterpool));
SVN_ERR(svn_stream_printf(feedback_stream, iterpool,
_("* Verified revision %ld.\n"),
rev));
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_repos/load.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_repos/load.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_repos/load.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_repos/load.c Tue Mar 16 18:03:37 2010
@@ -229,10 +229,20 @@ prefix_mergeinfo_paths(svn_string_t **me
prefixed_mergeinfo = apr_hash_make(pool);
for (hi = apr_hash_first(NULL, mergeinfo); hi; hi = apr_hash_next(hi))
{
- const char *path;
- const void *merge_source;
- apr_hash_this(hi, &merge_source, NULL, &rangelist);
- path = svn_path_join(parent_dir, (const char*)merge_source+1, pool);
+ const void *key;
+ const char *path, *merge_source;
+
+ apr_hash_this(hi, &key, NULL, &rangelist);
+ merge_source = key;
+
+ /* The svn:mergeinfo property syntax demands absolute repository
+ paths, so prepend a leading slash if PARENT_DIR lacks one. */
+ if (*parent_dir != '/')
+ path = svn_path_join_many(pool, "/", parent_dir,
+ merge_source + 1, NULL);
+ else
+ path = svn_path_join(parent_dir, merge_source + 1, pool);
+
apr_hash_set(prefixed_mergeinfo, path, APR_HASH_KEY_STRING, rangelist);
}
return svn_mergeinfo_to_string(mergeinfo_val, prefixed_mergeinfo, pool);
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_repos/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_repos/repos.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_repos/repos.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_repos/repos.c Tue Mar 16 18:03:37 2010
@@ -267,8 +267,8 @@ create_locks(svn_repos_t *repos, apr_poo
#define PREWRITTEN_HOOKS_TEXT \
"# For more examples and pre-written hooks, see those in" NL \
"# the Subversion repository at" NL \
- "# http://svn.collab.net/repos/svn/trunk/tools/hook-scripts/ and" NL \
- "# http://svn.collab.net/repos/svn/trunk/contrib/hook-scripts/" NL
+ "# http://svn.apache.org/repos/asf/subversion/trunk/tools/hook-scripts/ and" NL \
+ "# http://svn.apache.org/repos/asf/subversion/trunk/contrib/hook-scripts/" NL
static svn_error_t *
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_subr/config_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_subr/config_file.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_subr/config_file.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_subr/config_file.c Tue Mar 16 18:03:37 2010
@@ -502,7 +502,7 @@ svn_config_ensure(const char *config_dir
if (! path)
return SVN_NO_ERROR;
- err = svn_io_check_path(path, &kind, pool);
+ err = svn_io_check_resolved_path(path, &kind, pool);
if (err)
{
/* Don't throw an error, but don't continue. */
@@ -1009,7 +1009,7 @@ svn_config_ensure(const char *config_dir
"### passed to the tunnel agent as <user>@<hostname>.) If the" NL
"### built-in ssh scheme were not predefined, it could be defined" NL
"### as:" NL
- "# ssh = $SVN_SSH ssh" NL
+ "# ssh = $SVN_SSH ssh -q" NL
"### If you wanted to define a new 'rsh' scheme, to be used with" NL
"### 'svn+rsh:' URLs, you could do so as follows:" NL
"# rsh = rsh" NL
@@ -1064,11 +1064,11 @@ svn_config_ensure(const char *config_dir
"### 'enable-auto-props' option." NL
"# *.c = svn:eol-style=native" NL
"# *.cpp = svn:eol-style=native" NL
- "# *.h = svn:eol-style=native" NL
+ "# *.h = svn:keywords=Author Date Id Rev URL;svn:eol-style=native" NL
"# *.dsp = svn:eol-style=CRLF" NL
"# *.dsw = svn:eol-style=CRLF" NL
"# *.sh = svn:eol-style=native;svn:executable" NL
- "# *.txt = svn:eol-style=native" NL
+ "# *.txt = svn:eol-style=native;svn:keywords=Author Date Id Rev URL;"NL
"# *.png = svn:mime-type=image/png" NL
"# *.jpg = svn:mime-type=image/jpeg" NL
"# Makefile = svn:eol-style=native" NL
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_subr/io.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_subr/io.c Tue Mar 16 18:03:37 2010
@@ -1862,17 +1862,12 @@ svn_io_remove_dir(const char *path, apr_
Similar problem has been observed on FreeBSD.
- See http://subversion.tigris.org/issues/show_bug.cgi?id=1896 for more
- discussion and an initial solution.
+ The workaround is to delete the files only _after_ the initial
+ directory scan. A previous workaround involving rewinddir is
+ problematic on Win32 and some NFS clients, notably NetBSD.
- To work around the problem, we do a rewinddir after we delete all files
- and see if there's anything left. We repeat the steps untill there's
- nothing left to delete.
-
- This workaround causes issues on Windows where delete's are asynchronous,
- however, so we never rewind if we're on Windows (the delete says it is
- complete, we rewind, we see the same file and try to delete it again,
- we fail.
+ See http://subversion.tigris.org/issues/show_bug.cgi?id=1896 and
+ http://subversion.tigris.org/issues/show_bug.cgi?id=3501.
*/
/* Neither windows nor unix allows us to delete a non-empty
@@ -1884,13 +1879,10 @@ svn_io_remove_dir2(const char *path, svn
svn_cancel_func_t cancel_func, void *cancel_baton,
apr_pool_t *pool)
{
- apr_status_t status;
- apr_dir_t *this_dir;
- apr_finfo_t this_entry;
+ svn_error_t *err;
apr_pool_t *subpool;
- apr_int32_t flags = APR_FINFO_TYPE | APR_FINFO_NAME;
- const char *path_apr;
- int need_rewind;
+ apr_hash_t *dirents;
+ apr_hash_index_t *ent;
/* Check for pending cancellation request.
If we need to bail out, do so early. */
@@ -1898,112 +1890,50 @@ svn_io_remove_dir2(const char *path, svn
if (cancel_func)
SVN_ERR((*cancel_func)(cancel_baton));
- /* Convert path to native here and call apr_dir_open directly,
- instead of just using svn_io_dir_open, because we're going to
- need path_apr later anyway when we remove the dir itself. */
-
- if (path[0] == '\0')
- /* APR doesn't like "" directories; use "." instead. */
- SVN_ERR(cstring_from_utf8(&path_apr, ".", pool));
- else
- SVN_ERR(cstring_from_utf8(&path_apr, path, pool));
+ subpool = svn_pool_create(pool);
- status = apr_dir_open(&this_dir, path_apr, pool);
- if (status)
+ err = svn_io_get_dirents2(&dirents, path, subpool);
+ if (err)
{
/* if the directory doesn't exist, our mission is accomplished */
- if (ignore_enoent && APR_STATUS_IS_ENOENT(status))
- return SVN_NO_ERROR;
- else
- return svn_error_wrap_apr(status,
- _("Can't open directory '%s'"),
- svn_path_local_style(path, pool));
+ if (ignore_enoent && APR_STATUS_IS_ENOENT(err->apr_err))
+ {
+ svn_error_clear(err);
+ return SVN_NO_ERROR;
+ }
+ return err;
}
- subpool = svn_pool_create(pool);
-
- do
+ for (ent = apr_hash_first(subpool, dirents); ent; ent = apr_hash_next(ent))
{
- need_rewind = FALSE;
-
- for (status = apr_dir_read(&this_entry, flags, this_dir);
- status == APR_SUCCESS;
- status = apr_dir_read(&this_entry, flags, this_dir))
+ const void *key;
+ void *val;
+ char *fullpath;
+
+ apr_hash_this(ent, &key, NULL, &val);
+ fullpath = svn_path_join(path, key, subpool);
+ if (((svn_io_dirent_t *)val)->kind == svn_node_dir)
{
- svn_pool_clear(subpool);
- if ((this_entry.filetype == APR_DIR)
- && ((this_entry.name[0] == '.')
- && ((this_entry.name[1] == '\0')
- || ((this_entry.name[1] == '.')
- && (this_entry.name[2] == '\0')))))
- {
- continue;
- }
- else /* something other than "." or "..", so proceed */
- {
- const char *fullpath, *entry_utf8;
-
-#ifndef WIN32
- need_rewind = TRUE;
-#endif
-
- SVN_ERR(entry_name_to_utf8(&entry_utf8, this_entry.name,
- path_apr, subpool));
-
- fullpath = svn_path_join(path, entry_utf8, subpool);
-
- if (this_entry.filetype == APR_DIR)
- {
- /* Don't check for cancellation, the callee
- will immediately do so */
- SVN_ERR(svn_io_remove_dir2(fullpath, FALSE,
- cancel_func, cancel_baton,
- subpool));
- }
- else
- {
- svn_error_t *err;
-
- if (cancel_func)
- SVN_ERR((*cancel_func)(cancel_baton));
-
- err = svn_io_remove_file(fullpath, subpool);
- if (err)
- return svn_error_createf
- (err->apr_err, err, _("Can't remove '%s'"),
- svn_path_local_style(fullpath, subpool));
- }
- }
+ /* Don't check for cancellation, the callee will immediately do so */
+ SVN_ERR(svn_io_remove_dir2(fullpath, FALSE, cancel_func,
+ cancel_baton, subpool));
}
-
- if (need_rewind)
+ else
{
- status = apr_dir_rewind(this_dir);
- if (status)
- return svn_error_wrap_apr(status, _("Can't rewind directory '%s'"),
- svn_path_local_style (path, pool));
+ if (cancel_func)
+ SVN_ERR((*cancel_func)(cancel_baton));
+
+ err = svn_io_remove_file(fullpath, subpool);
+ if (err)
+ return svn_error_createf
+ (err->apr_err, err, _("Can't remove '%s'"),
+ svn_path_local_style(fullpath, subpool));
}
}
- while (need_rewind);
svn_pool_destroy(subpool);
- if (!APR_STATUS_IS_ENOENT(status))
- return svn_error_wrap_apr(status, _("Can't read directory '%s'"),
- svn_path_local_style(path, pool));
-
- status = apr_dir_close(this_dir);
- if (status)
- return svn_error_wrap_apr(status, _("Error closing directory '%s'"),
- svn_path_local_style(path, pool));
-
- status = apr_dir_remove(path_apr, pool);
- WIN32_RETRY_LOOP(status, apr_dir_remove(path_apr, pool));
- if (status)
- return svn_error_wrap_apr(status, _("Can't remove '%s'"),
- svn_path_local_style(path, pool));
-
- return APR_SUCCESS;
+ return svn_io_dir_remove_nonrecursive(path, pool);
}
svn_error_t *
@@ -2522,6 +2452,18 @@ svn_io_run_diff3_3(int *exitcode,
return SVN_NO_ERROR;
}
+
+/* Canonicalize a string for hashing. Modifies KEY in place. */
+static APR_INLINE char *
+fileext_tolower(char *key)
+{
+ register char *p;
+ for (p = key; *p != 0; ++p)
+ *p = apr_tolower(*p);
+ return key;
+}
+
+
svn_error_t *
svn_io_parse_mimetypes_file(apr_hash_t **type_map,
const char *mimetypes_file,
@@ -2570,6 +2512,7 @@ svn_io_parse_mimetypes_file(apr_hash_t *
for (i = 1; i < tokens->nelts; i++)
{
const char *ext = APR_ARRAY_IDX(tokens, i, const char *);
+ fileext_tolower((char *)ext);
apr_hash_set(types, ext, APR_HASH_KEY_STRING, type);
}
}
@@ -2611,13 +2554,6 @@ svn_io_detect_mimetype2(const char **mim
/* Default return value is NULL. */
*mimetype = NULL;
- /* See if this file even exists, and make sure it really is a file. */
- SVN_ERR(svn_io_check_path(file, &kind, pool));
- if (kind != svn_node_file)
- return svn_error_createf(SVN_ERR_BAD_FILENAME, NULL,
- _("Can't detect MIME type of non-file '%s'"),
- svn_path_local_style(file, pool));
-
/* If there is a mimetype_map provided, we'll first try to look up
our file's extension in the map. Failing that, we'll run the
heuristic. */
@@ -2625,6 +2561,7 @@ svn_io_detect_mimetype2(const char **mim
{
const char *type_from_map, *path_ext;
svn_path_splitext(NULL, &path_ext, file, pool);
+ fileext_tolower((char *)path_ext);
if ((type_from_map = apr_hash_get(mimetype_map, path_ext,
APR_HASH_KEY_STRING)))
{
@@ -2633,6 +2570,13 @@ svn_io_detect_mimetype2(const char **mim
}
}
+ /* See if this file even exists, and make sure it really is a file. */
+ SVN_ERR(svn_io_check_path(file, &kind, pool));
+ if (kind != svn_node_file)
+ return svn_error_createf(SVN_ERR_BAD_FILENAME, NULL,
+ _("Can't detect MIME type of non-file '%s'"),
+ svn_path_local_style(file, pool));
+
SVN_ERR(svn_io_file_open(&fh, file, APR_READ, 0, pool));
/* Read a block of data from FILE. */