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,