Merging some changes from /trunk into the issue-654-dev branch.
--
Author: striker
New Revision: 2063
* build/buildcheck.sh
Update the check for the neon version.
* subversion/libsvn_ra_dav/ra_dav.h
(svn_ra_session_t): 'uri -> ne_uri'
* subversion/libsvn_ra_dav/session.c
(svn_ra_dav__open): 'uri' -> 'ne_uri', 'uri_free' -> 'ne_uri_free',
'parse_uri' -> 'ne_uri_parse'. changed the default port logic a bit
per Joe Ortons suggestion.
* subversion/libsvn_ra_dav/props.c
(create_private, svn_ra_dav__get_baseline_info): 'uri' -> 'ne_uri',
'uri_free' -> 'ne_uri_free', 'parse_uri' -> 'ne_uri_parse'.
* subversion/libsvn_ra_dav/commit.c
(checkout_resource): Same.
* subversion/libsvn_ra_dav/fetch.c
(fetch_dirents): Same.
* subversion/libsvn_ra_dav/util.c
(svn_ra_dav__copy_href): Same.
--
Author: striker
New Revision: 2064
* subversion/libsvn_ra_dav/util.c
(ra_dav_error_accepter): Remove a newly introduced warning by
constifying an argument.
--
Author: striker
New Revision: 2078
* build/buildcheck.sh
Change the neon requirement to 0.21.1. This is to avoid our
users getting: 'Compressed response was truncated'.
--
Author: cmpilato
New Revision: 2090
* subversion/mod_dav_svn/mod_dav_svn.c
(SVN_DEFAULT_SPECIAL_URI): change to !svn, effectively invalidating
any opaque url coming from existing working copies.
* subversion/mod_dav_svn/dav_svn.h
(dav_svn_build_uri): grow new rev_root argument.
(dav_svn_uri_info): remove node_id and node_id_str fields; plain old
rev field suffices.
(struct dav_resource_private): same.
(DAV_SVN_REPOS_PATH): remove this macro, don't need it. ALL callers
changed to just 'resource->info->repos_path'.
* subversion/mod_dav_svn/util.c
(dav_svn_build_uri): grow new rev_root argument; construct 'version'
urls as "CR/path", instead of taking already-constructed unparsed
id_t's. Change ALL callers to this func, usually passing NULL for
the new rev_root arg.
(dav_svn_simple_parse_uri): parse created_rev instead of id_t.
* subversion/mod_dav_svn/liveprops.c
(dav_svn_insert_prop): simplify -- don't generate an fs_id_t, just
pass rev_root and path to build_uri.
* subversion/mod_dav_svn/merge.c
(send_response): same.
* subversion/mod_dav_svn/repos.c
(dav_svn_parse_version_uri): parse created_rev instead of id_t.
(dav_svn_getetag): generate unique tag based on CR/path instead of id.
(dav_svn_prep_version): do existence (type) check based on rev and
rev-root; no need for potential lookup by id-root anymore. Create
a revision root in the private struct if not already there
(previously, an id-root was created.)
(is_our_resource): no need to regenerate an id-root anymore.
(dav_svn_deliver): open a rev-root instead of id-root.
* subversion/mod_dav_svn/deadprops.c
(get_repos_path): just return repos_path field.
* subversion/mod_dav_svn/version.c
(dav_svn_checkout): check info->root.rev instead of node_id field.
New out-of-dateness check: the CR of the version-resource being
changed must be exactly equal to the CR of the node in the txn.
(This matches ra_local's commit technique.)
* subversion/mod_dav_svn/update.c
(dav_svn__update_report): The docs say that uc.dst_path, in the case
of an update, is the same as the anchor, not the anchor+target.
Fix this old(er) bug of mine that has lain obcured until now...
git-svn-id: https://svn.apache.org/repos/asf/subversion/branches/issue-654-dev@842165 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/build/buildcheck.sh b/build/buildcheck.sh
index d8a218c..993d644 100644
--- a/build/buildcheck.sh
+++ b/build/buildcheck.sh
@@ -56,8 +56,8 @@
#--------------------------------------------------------------------------
# check for the correct version of Neon
#
-NEON_WANTED_REGEX=0.19.4
-NEON_LATEST_WORKING_VER=0.19.4
+NEON_WANTED_REGEX=0.21.1
+NEON_LATEST_WORKING_VER=0.21.1
NEON_URL="http://www.webdav.org/neon/neon-${NEON_LATEST_WORKING_VER}.tar.gz"
NEON_TEST_REGEX="$NEON_WANTED_REGEX"
if test "$NEON_CHECK_CONTROL" = "--disable-neon-version-check"; then
diff --git a/subversion/libsvn_ra_dav/commit.c b/subversion/libsvn_ra_dav/commit.c
index 1d4f677..57af3b2 100644
--- a/subversion/libsvn_ra_dav/commit.c
+++ b/subversion/libsvn_ra_dav/commit.c
@@ -449,7 +449,7 @@
{
int code;
const char *locn = NULL;
- struct uri parse;
+ ne_uri parse;
svn_error_t *err;
if (res->wr_url != NULL)
@@ -493,9 +493,9 @@
/* The location is an absolute URI. We want just the path portion. */
/* ### what to do with the rest? what if it points somewhere other
### than the current session? */
- uri_parse(locn, &parse, NULL);
+ ne_uri_parse(locn, &parse);
res->wr_url = apr_pstrdup(cc->ras->pool, parse.path);
- uri_free(&parse);
+ ne_uri_free(&parse);
free((void *)locn);
return SVN_NO_ERROR;
diff --git a/subversion/libsvn_ra_dav/fetch.c b/subversion/libsvn_ra_dav/fetch.c
index 42eb5fa..39138a5 100644
--- a/subversion/libsvn_ra_dav/fetch.c
+++ b/subversion/libsvn_ra_dav/fetch.c
@@ -352,7 +352,7 @@
apr_pool_t *pool)
{
apr_hash_t *dirents;
- struct uri parsed_url;
+ ne_uri parsed_url;
apr_hash_index_t *hi;
/* Fetch all properties so we can snarf ones out of the svn:custom
@@ -383,7 +383,7 @@
* :-)
*/
- uri_parse(url, &parsed_url, NULL);
+ ne_uri_parse(url, &parsed_url);
for (hi = apr_hash_first(pool, dirents); hi; hi = apr_hash_next(hi))
{
@@ -395,7 +395,7 @@
if (r->is_collection)
{
- if (uri_compare(parsed_url.path, r->url) == 0)
+ if (ne_path_compare(parsed_url.path, r->url) == 0)
{
/* don't insert "this dir" into the set of subdirs */
@@ -422,7 +422,7 @@
}
}
- uri_free(&parsed_url);
+ ne_uri_free(&parsed_url);
return SVN_NO_ERROR;
}
diff --git a/subversion/libsvn_ra_dav/props.c b/subversion/libsvn_ra_dav/props.c
index b799bc6..193814c 100644
--- a/subversion/libsvn_ra_dav/props.c
+++ b/subversion/libsvn_ra_dav/props.c
@@ -132,7 +132,7 @@
static void *create_private(void *userdata, const char *url)
{
prop_ctx_t *pc = userdata;
- struct uri parsed_url;
+ ne_uri parsed_url;
char *url_path;
svn_ra_dav_resource_t *r = apr_pcalloc(pc->pool, sizeof(*r));
apr_size_t len;
@@ -150,9 +150,9 @@
Note: mod_dav does not (currently) use an absolute URL, but simply a
server-relative path (i.e. this uri_parse is effectively a no-op).
*/
- (void) uri_parse(url_str->data, &parsed_url, NULL);
+ (void) ne_uri_parse(url_str->data, &parsed_url);
url_path = apr_pstrdup(pc->pool, parsed_url.path);
- uri_free(&parsed_url);
+ ne_uri_free(&parsed_url);
/* clean up trailing slashes from the URL */
len = strlen(url_path);
@@ -467,7 +467,7 @@
{
svn_ra_dav_resource_t *rsrc;
const char *vcc;
- struct uri parsed_url;
+ ne_uri parsed_url;
const char *my_bc_url, *my_bc_relative;
const char *lopped_path = "";
@@ -496,7 +496,7 @@
/* Split the url into it's component pieces (schema, host, path,
etc). We want the path part. */
- uri_parse (url, &parsed_url, NULL);
+ ne_uri_parse (url, &parsed_url);
/* ### do we want to optimize the props we fetch, based on what the
### user has requested? i.e. omit resourcetype when is_dir is NULL
@@ -509,7 +509,7 @@
starting_props from parent directories. */
svn_error_t *err;
svn_stringbuf_t *path_s = svn_stringbuf_create (parsed_url.path, pool);
- uri_free(&parsed_url);
+ ne_uri_free(&parsed_url);
while (! svn_path_is_empty (path_s))
{
diff --git a/subversion/libsvn_ra_dav/ra_dav.h b/subversion/libsvn_ra_dav/ra_dav.h
index de92922..dc3867f 100644
--- a/subversion/libsvn_ra_dav/ra_dav.h
+++ b/subversion/libsvn_ra_dav/ra_dav.h
@@ -44,7 +44,7 @@
apr_pool_t *pool;
const char *url; /* original, unparsed url for this session */
- struct uri root; /* parsed version of above */
+ ne_uri root; /* parsed version of above */
ne_session *sess; /* HTTP session to server */
ne_session *sess2;
diff --git a/subversion/libsvn_ra_dav/session.c b/subversion/libsvn_ra_dav/session.c
index 0514a8e..23354e9 100644
--- a/subversion/libsvn_ra_dav/session.c
+++ b/subversion/libsvn_ra_dav/session.c
@@ -317,22 +317,22 @@
const char *repository = repos_URL->data;
apr_size_t len;
ne_session *sess, *sess2;
- struct uri uri = { 0 };
+ ne_uri uri = { 0 };
svn_ra_session_t *ras;
int is_ssl_session;
/* Sanity check the URI */
- if (uri_parse(repository, &uri, NULL)
+ if (ne_uri_parse(repository, &uri)
|| uri.host == NULL || uri.path == NULL)
{
- uri_free(&uri);
+ ne_uri_free(&uri);
return svn_error_create(SVN_ERR_RA_ILLEGAL_URL, 0, NULL, pool,
"illegal URL for repository");
}
/* Can we initialize network? */
- if (sock_init() != 0) {
- uri_free(&uri);
+ if (ne_sock_init() != 0) {
+ ne_uri_free(&uri);
return svn_error_create(SVN_ERR_RA_SOCK_INIT, 0, NULL, pool,
"network socket initialization failed");
}
@@ -348,13 +348,9 @@
is_ssl_session = (strcasecmp(uri.scheme, "https") == 0);
if (is_ssl_session)
{
- if (uri.port == -1)
- {
- uri.port = 443;
- }
if (ne_supports_ssl() == 0)
{
- uri_free(&uri);
+ ne_uri_free(&uri);
return svn_error_create(SVN_ERR_RA_SOCK_INIT, 0, NULL, pool,
"SSL is not supported");
}
@@ -368,9 +364,9 @@
}
#endif
- if (uri.port == -1)
+ if (uri.port == 0)
{
- uri.port = 80;
+ uri.port = ne_uri_defaultport(uri.scheme);
}
/* Create two neon session objects, and set their properties... */
diff --git a/subversion/libsvn_ra_dav/util.c b/subversion/libsvn_ra_dav/util.c
index e327437..5fd3ae8 100644
--- a/subversion/libsvn_ra_dav/util.c
+++ b/subversion/libsvn_ra_dav/util.c
@@ -32,7 +32,7 @@
void svn_ra_dav__copy_href(svn_stringbuf_t *dst, const char *src)
{
- struct uri parsed_url;
+ ne_uri parsed_url;
/* parse the PATH element out of the URL and store it.
@@ -41,9 +41,9 @@
Note: mod_dav does not (currently) use an absolute URL, but simply a
server-relative path (i.e. this uri_parse is effectively a no-op).
*/
- (void) uri_parse(src, &parsed_url, NULL);
+ (void) ne_uri_parse(src, &parsed_url);
svn_stringbuf_set(dst, parsed_url.path);
- uri_free(&parsed_url);
+ ne_uri_free(&parsed_url);
}
svn_error_t *svn_ra_dav__convert_error(ne_session *sess,
@@ -98,7 +98,7 @@
/* Custom function of type ne_accept_response. */
static int ra_dav_error_accepter(void *userdata,
ne_request *req,
- ne_status *st)
+ const ne_status *st)
{
/* Only accept the body-response if the HTTP status code is *not* 2XX. */
return (st->klass != 2);
diff --git a/subversion/mod_dav_svn/dav_svn.h b/subversion/mod_dav_svn/dav_svn.h
index e62ca60..ffd9a36 100644
--- a/subversion/mod_dav_svn/dav_svn.h
+++ b/subversion/mod_dav_svn/dav_svn.h
@@ -177,13 +177,6 @@
/* what FS root this resource occurs within */
dav_svn_root root;
- /* for VERSION resources: the node ID. may be NULL if the resource was
- fetched via a Baseline Collection (so use root.rev and repos_path). if
- the VERSION refers to a Baseline (.baselined==1), then node_id and
- repos_path will be NULL. */
- const svn_fs_id_t *node_id;
- const char *node_id_str;
-
/* for PRIVATE resources: the private resource type */
enum dav_svn_private_restype restype;
@@ -196,16 +189,6 @@
/*
- For a given resource, return the path that should be used when talking
- to the FS. If a NODE_ID is present, then we must have opened an ID root,
- and that NODE_ID should be used. Otherwise, we opened a revision or txn
- root and should use a normal REPOS_PATH.
-*/
-#define DAV_SVN_REPOS_PATH(res) ((res)->info->node_id_str != NULL \
- ? (res)->info->node_id_str \
- : (res)->info->repos_path)
-
-/*
LIVE PROPERTY HOOKS
These are standard hooks defined by mod_dav. We implement them to expose
@@ -327,12 +310,13 @@
BASELINE: REVISION should be specified
BC: REVISION should be specified
PUBLIC: PATH should be specified with a leading slash
- VERSION: PATH should be specified as a STABLE_ID ("/ID/PATH")
+ VERSION: REV_ROOT and PATH should be specified
VCC: no additional params required
*/
const char *dav_svn_build_uri(const dav_svn_repos *repos,
enum dav_svn_build_what what,
svn_revnum_t revision,
+ svn_fs_root_t *rev_root,
const char *path,
int add_href,
apr_pool_t *pool);
@@ -352,7 +336,6 @@
svn_revnum_t rev;
const char *repos_path;
const char *activity_id;
- svn_fs_id_t *node_id;
} dav_svn_uri_info;
svn_error_t *dav_svn_simple_parse_uri(dav_svn_uri_info *info,
diff --git a/subversion/mod_dav_svn/deadprops.c b/subversion/mod_dav_svn/deadprops.c
index bfbc018..1fc8fdf 100644
--- a/subversion/mod_dav_svn/deadprops.c
+++ b/subversion/mod_dav_svn/deadprops.c
@@ -48,7 +48,7 @@
/* retrieve the "right" string to use as a repos path */
static const char *get_repos_path (struct dav_resource_private *info)
{
- return info->node_id_str ? info->node_id_str : info->repos_path;
+ return info->repos_path;
}
diff --git a/subversion/mod_dav_svn/liveprops.c b/subversion/mod_dav_svn/liveprops.c
index fec46e1..ac9a522 100644
--- a/subversion/mod_dav_svn/liveprops.c
+++ b/subversion/mod_dav_svn/liveprops.c
@@ -133,7 +133,7 @@
root object might be an ID root -or- a revision root. */
serr = svn_fs_node_created_rev(&committed_rev,
resource->info->root.root,
- DAV_SVN_REPOS_PATH(resource), p);
+ resource->info->repos_path, p);
if (serr != NULL)
{
/* ### what to do? */
@@ -169,7 +169,7 @@
root object might be an ID root -or- a revision root. */
serr = svn_fs_node_created_rev(&committed_rev,
resource->info->root.root,
- DAV_SVN_REPOS_PATH(resource), p);
+ resource->info->repos_path, p);
if (serr != NULL)
{
/* ### what to do? */
@@ -231,7 +231,7 @@
if (resource->type != DAV_RESOURCE_TYPE_VERSION || !resource->baselined)
return DAV_PROP_INSERT_NOTSUPP;
value = dav_svn_build_uri(resource->info->repos, DAV_SVN_BUILD_URI_BC,
- resource->info->root.rev, NULL,
+ resource->info->root.rev, NULL, NULL,
1 /* add_href */, p);
break;
@@ -252,7 +252,7 @@
}
s = dav_svn_build_uri(resource->info->repos,
DAV_SVN_BUILD_URI_BASELINE,
- revnum, NULL,
+ revnum, NULL, NULL,
0 /* add_href */, p);
value = apr_psprintf(p, "<D:href>%s</D:href>",
apr_xml_quote_string(p, s, 1));
@@ -264,24 +264,11 @@
}
else
{
- svn_fs_id_t *id;
- svn_stringbuf_t *stable_id;
-
- serr = svn_fs_node_id(&id, resource->info->root.root,
- resource->info->repos_path, p);
- if (serr != NULL)
- {
- /* ### what to do? */
- value = "###error###";
- break;
- }
-
- stable_id = svn_fs_unparse_id(id, p);
- svn_stringbuf_appendcstr(stable_id, resource->info->repos_path);
-
s = dav_svn_build_uri(resource->info->repos,
DAV_SVN_BUILD_URI_VERSION,
- SVN_INVALID_REVNUM, stable_id->data,
+ SVN_INVALID_REVNUM,
+ resource->info->root.root,
+ resource->info->repos_path,
0 /* add_href */, p);
value = apr_psprintf(p, "<D:href>%s</D:href>",
apr_xml_quote_string(p, s, 1));
@@ -295,7 +282,7 @@
if (resource->type != DAV_RESOURCE_TYPE_REGULAR)
return DAV_PROP_INSERT_NOTSUPP;
value = dav_svn_build_uri(resource->info->repos, DAV_SVN_BUILD_URI_VCC,
- SVN_IGNORED_REVNUM, NULL,
+ SVN_IGNORED_REVNUM, NULL, NULL,
1 /* add_href */, p);
break;
@@ -320,7 +307,7 @@
root object might be an ID root -or- a revision root. */
serr = svn_fs_node_created_rev(&committed_rev,
resource->info->root.root,
- DAV_SVN_REPOS_PATH(resource), p);
+ resource->info->repos_path, p);
if (serr != NULL)
{
/* ### what to do? */
diff --git a/subversion/mod_dav_svn/merge.c b/subversion/mod_dav_svn/merge.c
index 024dc63..e358b81 100644
--- a/subversion/mod_dav_svn/merge.c
+++ b/subversion/mod_dav_svn/merge.c
@@ -110,26 +110,20 @@
merge_response_ctx *mrc = baton->mrc;
const char *href;
const char *rt;
- svn_fs_id_t *id;
- svn_stringbuf_t *stable_id;
const char *vsn_url;
apr_status_t status;
href = dav_svn_build_uri(mrc->repos, DAV_SVN_BUILD_URI_PUBLIC,
- SVN_IGNORED_REVNUM, baton->path,
+ SVN_IGNORED_REVNUM, NULL, baton->path,
0 /* add_href */, baton->pool);
rt = is_dir
? "<D:resourcetype><D:collection/></D:resourcetype>" DEBUG_CR
: "<D:resourcetype/>" DEBUG_CR;
- SVN_ERR( svn_fs_node_id(&id, mrc->root, baton->path, baton->pool) );
-
- stable_id = svn_fs_unparse_id(id, baton->pool);
- svn_stringbuf_appendcstr(stable_id, baton->path);
-
vsn_url = dav_svn_build_uri(mrc->repos, DAV_SVN_BUILD_URI_VERSION,
- SVN_INVALID_REVNUM, stable_id->data,
+ SVN_INVALID_REVNUM,
+ mrc->root, baton->path,
0 /* add_href */, baton->pool);
status = ap_fputstrs(mrc->output, mrc->bb,
@@ -345,7 +339,7 @@
/* the HREF for the baseline is actually the VCC */
vcc = dav_svn_build_uri(repos, DAV_SVN_BUILD_URI_VCC, SVN_IGNORED_REVNUM,
- NULL, 0 /* add_href */, pool);
+ NULL, NULL, 0 /* add_href */, pool);
/* the version-name of the baseline is the revision number */
sprintf(revbuf, "%" SVN_REVNUM_T_FMT, new_rev);
diff --git a/subversion/mod_dav_svn/mod_dav_svn.c b/subversion/mod_dav_svn/mod_dav_svn.c
index fc43473..654e84c 100644
--- a/subversion/mod_dav_svn/mod_dav_svn.c
+++ b/subversion/mod_dav_svn/mod_dav_svn.c
@@ -34,7 +34,7 @@
/* This is the default "special uri" used for SVN's special resources
(e.g. working resources, activities) */
-#define SVN_DEFAULT_SPECIAL_URI "$svn"
+#define SVN_DEFAULT_SPECIAL_URI "!svn"
/* per-server configuration */
typedef struct {
diff --git a/subversion/mod_dav_svn/repos.c b/subversion/mod_dav_svn/repos.c
index 3347d64..226387f 100644
--- a/subversion/mod_dav_svn/repos.c
+++ b/subversion/mod_dav_svn/repos.c
@@ -84,8 +84,9 @@
int use_checked_in)
{
const char *slash;
+ const char *created_rev_str;
- /* format: NODE_ID/REPOS_PATH */
+ /* format: CREATED_REV/REPOS_PATH */
/* ### what to do with LABEL and USE_CHECKED_IN ?? */
@@ -95,17 +96,17 @@
slash = ap_strchr_c(path, '/');
if (slash == NULL)
{
- /* http://host.name/repos/$svn/ver/1.2.3.4
+ /* http://host.name/repos/$svn/ver/0
This URL form refers to the root path of the repository.
*/
- comb->priv.node_id = svn_fs_parse_id(path, strlen(path), comb->res.pool);
- comb->priv.node_id_str = path;
+ created_rev_str = apr_pstrndup(comb->res.pool, path, strlen(path));
+ comb->priv.root.rev = SVN_STR_TO_REV(created_rev_str);
comb->priv.repos_path = "/";
}
else if (slash == path)
{
- /* the NODE_ID was missing(?)
+ /* the CREATED_REV was missing(?)
### not sure this can happen, though, because it would imply two
### slashes, yet those are cleaned out within get_resource
@@ -116,13 +117,13 @@
{
apr_size_t len = slash - path;
- comb->priv.node_id = svn_fs_parse_id(path, len, comb->res.pool);
- comb->priv.node_id_str = apr_pstrndup(comb->res.pool, path, len);
+ created_rev_str = apr_pstrndup(comb->res.pool, path, len);
+ comb->priv.root.rev = SVN_STR_TO_REV(created_rev_str);
comb->priv.repos_path = slash;
}
- /* if the NODE_ID parsing blew, then propagate it. */
- if (comb->priv.node_id == NULL)
+ /* if the CREATED_REV parsing blew, then propagate it. */
+ if (comb->priv.root.rev == SVN_INVALID_REVNUM)
return TRUE;
return FALSE;
@@ -258,7 +259,7 @@
comb->priv.root.rev = revnum;
/* NOTE: comb->priv.repos_path == NULL */
- /* NOTE: comb->priv.node_id == NULL */
+ /* NOTE: comb->priv.created_rev == SVN_INVALID_REVNUM */
}
return FALSE;
@@ -328,7 +329,7 @@
comb->priv.root.rev = revnum;
/* NOTE: comb->priv.repos_path == NULL */
- /* NOTE: comb->priv.node_id == NULL */
+ /* NOTE: comb->priv.created_rev == SVN_INVALID_REVNUM */
return FALSE;
}
@@ -559,79 +560,55 @@
{
svn_error_t *serr;
- if (comb->priv.node_id != NULL)
+ /* we are accessing the Version Resource by REV/PATH */
+
+ /* ### assert: .baselined = TRUE */
+
+ /* if we don't have a revision, then assume the youngest */
+ if (!SVN_IS_VALID_REVNUM(comb->priv.root.rev))
{
- /* we are accessing the Version Resource by ID */
+ serr = svn_fs_youngest_rev(&comb->priv.root.rev,
+ comb->priv.repos->fs,
+ comb->res.pool);
+ if (serr != NULL)
+ {
+ /* ### might not be a baseline */
+
+ return dav_svn_convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+ "Could not fetch 'youngest' revision "
+ "to enable accessing the latest "
+ "baseline resource.");
+ }
+ }
+
+ /* ### baselines have no repos_path, and we don't need to open
+ ### a root (yet). we just needed to ensure that we have the proper
+ ### revision number. */
- serr = svn_fs_id_root(&comb->priv.root.root, comb->priv.repos->fs,
- comb->res.pool);
+ if (!comb->priv.root.root)
+ {
+ serr = svn_fs_revision_root(&comb->priv.root.root,
+ comb->priv.repos->fs,
+ comb->priv.root.rev,
+ comb->res.pool);
if (serr != NULL)
{
return dav_svn_convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
- "Could not open the Subversion FS.");
+ "Could not open a revision root.");
}
-
- serr = svn_fs_is_dir(&comb->res.collection,
- comb->priv.root.root,
- comb->priv.node_id_str,
- comb->res.pool);
- if (serr != NULL)
- {
- if (serr->apr_err != SVN_ERR_FS_NOT_FOUND)
- {
- return dav_svn_convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
- "Could not determine whether the "
- "resource is a file or dir.");
- }
-
- /* exists == FALSE */
- }
- else
- {
- comb->res.exists = TRUE;
- }
-
- /* ### revise the URI to the "canonical" URI? necessary? */
}
- else
- {
- /* we are accessing the Version Resource by REV/PATH */
- /* ### assert: .baselined = TRUE */
-
- /* if we don't have a revision, then assume the youngest */
- if (!SVN_IS_VALID_REVNUM(comb->priv.root.rev))
- {
- serr = svn_fs_youngest_rev(&comb->priv.root.rev,
- comb->priv.repos->fs,
- comb->res.pool);
- if (serr != NULL)
- {
- /* ### might not be a baseline */
-
- return dav_svn_convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
- "Could not fetch 'youngest' revision "
- "to enable accessing the latest "
- "baseline resource.");
- }
- }
-
- /* ### baselines have no repos_path, and we don't need to open
- ### a root (yet). we just needed to ensure that we have the proper
- ### revision number. */
-
- /* ### we should probably check that the revision is valid */
- comb->res.exists = TRUE;
-
- /* Set up the proper URI. Most likely, we arrived here via a VCC,
- so the URI will be incorrect. Set the canonical form. */
- /* ### assuming a baseline */
- comb->res.uri = dav_svn_build_uri(comb->priv.repos,
- DAV_SVN_BUILD_URI_BASELINE,
- comb->priv.root.rev, NULL,
- 0 /* add_href */,
- comb->res.pool);
- }
+ /* ### we should probably check that the revision is valid */
+ comb->res.exists = TRUE;
+
+ /* Set up the proper URI. Most likely, we arrived here via a VCC,
+ so the URI will be incorrect. Set the canonical form. */
+ /* ### assuming a baseline */
+ comb->res.uri = dav_svn_build_uri(comb->priv.repos,
+ DAV_SVN_BUILD_URI_BASELINE,
+ comb->priv.root.rev, NULL, NULL,
+ 0 /* add_href */,
+ comb->res.pool);
return NULL;
}
@@ -1113,16 +1090,9 @@
res2->info->root.txn,
res2->info->repos->pool);
}
- else if (res2->info->node_id)
- {
- /* regenerate the id "root" object */
- (void) svn_fs_id_root(&(res2->info->root.root),
- res2->info->repos->fs,
- res2->info->repos->pool);
- }
else if (res2->info->root.rev)
{
- /* default: regenerate a revision "root" object */
+ /* default: regenerate the revision "root" object */
(void) svn_fs_revision_root(&(res2->info->root.root),
res2->info->repos->fs,
res2->info->root.rev,
@@ -1317,8 +1287,7 @@
const char * dav_svn_getetag(const dav_resource *resource)
{
svn_error_t *serr;
- svn_fs_id_t *id; /* ### want const here */
- svn_stringbuf_t *idstr;
+ svn_revnum_t created_rev;
/* if the resource doesn't exist, isn't a simple REGULAR or VERSION
resource, or it is a Baseline, then it has no etag. */
@@ -1331,15 +1300,16 @@
/* ### what kind of etag to return for collections, activities, etc? */
- serr = svn_fs_node_id(&id, resource->info->root.root,
- DAV_SVN_REPOS_PATH(resource), resource->pool);
- if (serr != NULL) {
- /* ### what to do? */
- return "";
- }
-
- idstr = svn_fs_unparse_id(id, resource->pool);
- return apr_psprintf(resource->pool, "\"%s\"", idstr->data);
+ if ((serr = svn_fs_node_created_rev(&created_rev, resource->info->root.root,
+ resource->info->repos_path,
+ resource->pool)))
+ {
+ /* ### what to do? */
+ return "";
+ }
+
+ return apr_psprintf(resource->pool, "\"%" SVN_REVNUM_T_FMT "/%s\"",
+ created_rev, resource->info->repos_path);
}
static dav_error * dav_svn_set_headers(request_rec *r,
@@ -1388,7 +1358,7 @@
serr = svn_fs_node_prop(&value,
resource->info->root.root,
- DAV_SVN_REPOS_PATH(resource),
+ resource->info->repos_path,
SVN_PROP_MIME_TYPE,
resource->pool);
if (serr != NULL)
@@ -1401,7 +1371,7 @@
so set up the Content-Length header */
serr = svn_fs_file_length(&length,
resource->info->root.root,
- DAV_SVN_REPOS_PATH(resource),
+ resource->info->repos_path,
resource->pool);
if (serr != NULL)
{
@@ -1482,7 +1452,7 @@
int i;
serr = svn_fs_dir_entries(&entries, resource->info->root.root,
- DAV_SVN_REPOS_PATH(resource), resource->pool);
+ resource->info->repos_path, resource->pool);
if (serr != NULL)
return dav_svn_convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
"could not fetch directory entries");
@@ -1575,7 +1545,7 @@
serr = svn_fs_file_contents(&stream,
resource->info->root.root,
- DAV_SVN_REPOS_PATH(resource),
+ resource->info->repos_path,
resource->pool);
if (serr != NULL)
{
@@ -1628,7 +1598,6 @@
{
dav_svn_uri_info info;
svn_fs_root_t *root;
- svn_stringbuf_t *id_str;
int is_file;
svn_txdelta_stream_t *txd_stream;
svn_stream_t *o_stream;
@@ -1643,23 +1612,21 @@
if (serr != NULL)
return dav_svn_convert_err(serr, HTTP_BAD_REQUEST,
"could not parse the delta base");
- if (info.node_id == NULL)
+ if (info.rev == SVN_INVALID_REVNUM)
return dav_new_error(resource->pool, HTTP_BAD_REQUEST, 0,
"the delta base was not a version "
"resource URL");
/* We are always accessing the base resource by ID, so open
an ID root. */
- serr = svn_fs_id_root(&root, resource->info->repos->fs,
- resource->pool);
+ serr = svn_fs_revision_root(&root, resource->info->repos->fs,
+ info.rev, resource->pool);
if (serr != NULL)
return dav_svn_convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
"could not open a root for the base");
- id_str = svn_fs_unparse_id(info.node_id, resource->pool);
-
/* verify that it is a file */
- serr = svn_fs_is_file(&is_file, root, id_str->data, resource->pool);
+ serr = svn_fs_is_file(&is_file, root, info.repos_path, resource->pool);
if (serr != NULL)
return dav_svn_convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
"could not determine if the base "
@@ -1670,9 +1637,9 @@
/* Okay. Let's open up a delta stream for the client to read. */
serr = svn_fs_get_file_delta_stream(&txd_stream,
- root, id_str->data,
+ root, info.repos_path,
resource->info->root.root,
- DAV_SVN_REPOS_PATH(resource),
+ resource->info->repos_path,
resource->pool);
if (serr != NULL)
return dav_svn_convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
diff --git a/subversion/mod_dav_svn/update.c b/subversion/mod_dav_svn/update.c
index 1566f86..bf50337 100644
--- a/subversion/mod_dav_svn/update.c
+++ b/subversion/mod_dav_svn/update.c
@@ -181,9 +181,6 @@
static void send_vsn_url(item_baton_t *baton)
{
- svn_error_t *serr;
- svn_fs_id_t *id;
- svn_stringbuf_t *stable_id;
const char *href;
const char *path;
@@ -194,18 +191,10 @@
path = get_from_path_map(baton->uc->pathmap, baton->path, baton->pool);
path = strcmp(path, baton->path) ? path : baton->path2;
- if ((serr = svn_fs_node_id(&id, baton->uc->rev_root, path, baton->pool)))
- {
- /* ### what to do? */
- return;
- }
-
- stable_id = svn_fs_unparse_id(id, baton->pool);
- svn_stringbuf_appendcstr(stable_id, path);
-
href = dav_svn_build_uri(baton->uc->resource->info->repos,
DAV_SVN_BUILD_URI_VERSION,
- SVN_INVALID_REVNUM, stable_id->data,
+ SVN_INVALID_REVNUM,
+ baton->uc->rev_root, path,
0 /* add_href */, baton->pool);
send_xml(baton->uc,
@@ -621,11 +610,8 @@
uc.resource = resource;
uc.output = output;
uc.anchor = resource->info->repos_path;
- uc.dst_path = dst_path ? dst_path
- : svn_path_join_many(resource->pool,
- resource->info->repos_path,
- target ? target : NULL,
- NULL);
+ uc.dst_path = dst_path ? dst_path : uc.anchor;
+
uc.bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
uc.pathmap = NULL;
diff --git a/subversion/mod_dav_svn/util.c b/subversion/mod_dav_svn/util.c
index 376492f..865369d 100644
--- a/subversion/mod_dav_svn/util.c
+++ b/subversion/mod_dav_svn/util.c
@@ -65,6 +65,7 @@
const char *dav_svn_build_uri(const dav_svn_repos *repos,
enum dav_svn_build_what what,
svn_revnum_t revision,
+ svn_fs_root_t *rev_root,
const char *path,
int add_href,
apr_pool_t *pool)
@@ -93,9 +94,21 @@
href1, root_path, path, href2);
case DAV_SVN_BUILD_URI_VERSION:
- /* path is the STABLE_ID */
- return apr_psprintf(pool, "%s%s/%s/ver/%s%s",
- href1, root_path, special_uri, path, href2);
+ {
+ svn_error_t *serr;
+ svn_revnum_t created_rev;
+
+ if ((serr = svn_fs_node_created_rev(&created_rev, rev_root,
+ path, pool)))
+ {
+ abort();
+ return NULL;
+ }
+
+ return apr_psprintf(pool, "%s%s/%s/ver/%" SVN_REVNUM_T_FMT "%s%s",
+ href1, root_path, special_uri,
+ created_rev, path, href2);
+ }
case DAV_SVN_BUILD_URI_VCC:
return apr_psprintf(pool, "%s%s/%s/vcc/" DAV_SVN_DEFAULT_VCC_NAME "%s",
@@ -120,6 +133,7 @@
apr_size_t len1;
apr_size_t len2;
const char *slash;
+ const char *created_rev_str;
/* parse the input URI, in case it is more than just a path */
if (apr_uri_parse(pool, uri, &comp) != APR_SUCCESS)
@@ -201,22 +215,24 @@
info->activity_id = path + 5;
}
else if (len2 == 4 && memcmp(path, "/ver/", 5) == 0)
- {
+ {
/* a version resource */
path += 5;
len1 -= 5;
slash = ap_strchr_c(path, '/');
if (slash == NULL)
{
- info->node_id = svn_fs_parse_id(path, len1, pool);
+ created_rev_str = apr_pstrndup(pool, path, len1);
+ info->rev = SVN_STR_TO_REV(created_rev_str);
info->repos_path = "/";
}
else
{
- info->node_id = svn_fs_parse_id(path, slash - path, pool);
+ created_rev_str = apr_pstrndup(pool, path, slash - path);
+ info->rev = SVN_STR_TO_REV(created_rev_str);
info->repos_path = slash;
}
- if (info->node_id == NULL)
+ if (info->rev == SVN_INVALID_REVNUM)
goto malformed_uri;
}
else
diff --git a/subversion/mod_dav_svn/version.c b/subversion/mod_dav_svn/version.c
index 25b2c60..43c1007 100644
--- a/subversion/mod_dav_svn/version.c
+++ b/subversion/mod_dav_svn/version.c
@@ -92,7 +92,7 @@
ap_text_append(resource->pool, option,
dav_svn_build_uri(resource->info->repos,
DAV_SVN_BUILD_URI_ACT_COLLECTION,
- SVN_INVALID_REVNUM, NULL,
+ SVN_INVALID_REVNUM, NULL, NULL,
1 /* add_href */, resource->pool));
ap_text_append(resource->pool, option,
"</D:activity-collection-set>");
@@ -211,7 +211,7 @@
/* verify the specified version resource is the "latest", thus allowing
changes to be made. */
- if (resource->baselined || resource->info->node_id == NULL)
+ if (resource->baselined || resource->info->root.rev == SVN_INVALID_REVNUM)
{
/* a Baseline, or a standard Version Resource which was accessed
via a Label against a VCR within a Baseline Collection. */
@@ -255,8 +255,8 @@
svn_fs_txn_t *txn;
svn_fs_root_t *txn_root;
+ svn_revnum_t txn_created_rev;
dav_error *err;
- int matches;
/* open the specified transaction so that we can verify this version
resource corresponds to the current/latest in the transaction. */
@@ -274,23 +274,33 @@
/* assert: repos_path != NULL (for this type of resource) */
- serr = svn_fs_txn_path_is_id(&matches, txn_root,
- resource->info->repos_path,
- resource->info->node_id,
- resource->pool);
+
+ /* Out-of-dateness check: compare the created-rev of the item
+ in the txn against the created-rev of the version resource
+ being changed. */
+ serr = svn_fs_node_created_rev(&txn_created_rev,
+ txn_root, resource->info->repos_path,
+ resource->pool);
if (serr != NULL)
{
/* ### correct HTTP error? */
return dav_svn_convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
- "Could not match the node ID.");
+ "Could not get created-rev of txn node.");
}
- if (!matches)
+ /* If txn_created_rev is invalid, that means it's already
+ mutable in the txn... which means it has already passed this
+ out-of-dateness check. (Usually, this happens when looking
+ at a parent directory of an already checked-out
+ resource.) */
+
+ if (SVN_IS_VALID_REVNUM(txn_created_rev)
+ && (resource->info->root.rev != txn_created_rev))
{
- /* The node ID they are trying to change does not match what was
- found in the transaction. That means they are trying to modify
- an old (out of date) revision of the resource, or they are
- trying to modify a *newer* revision.
+ /* The node they are trying to change does not match what
+ was found in the transaction. That means they are trying
+ to modify an old (out of date) revision of the resource,
+ or they are trying to modify a *newer* revision.
If the version resource is *newer* than the transaction
root, then the client started a commit, a new revision was
@@ -321,18 +331,12 @@
#else
/* ### some debugging code */
-
- svn_fs_id_t *res_id;
- svn_stringbuf_t *r_id;
- svn_stringbuf_t *t_id;
const char *msg;
- (void) svn_fs_node_id (&res_id, txn_root,
- resource->info->repos_path, resource->pool);
- r_id = svn_fs_unparse_id(resource->info->node_id, resource->pool);
- t_id = svn_fs_unparse_id(res_id, resource->pool);
- msg = apr_psprintf(resource->pool, "id mismatch: r=%s t=%s",
- r_id->data, t_id->data);
+ msg = apr_psprintf(resource->pool,
+ "created-rev mismatch: r=%" SVN_REVNUM_T_FMT
+ ", t=%" SVN_REVNUM_T_FMT,
+ resource->info->root.rev, txn_created_rev);
return dav_new_error_tag(resource->pool, HTTP_CONFLICT,
SVN_ERR_FS_CONFLICT, msg,