You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2012/07/03 17:30:32 UTC

svn commit: r1356789 - in /subversion/trunk/subversion: libsvn_client/merge.c libsvn_wc/conflicts.c libsvn_wc/wc_db.c libsvn_wc/wc_db.h

Author: rhuijben
Date: Tue Jul  3 15:30:29 2012
New Revision: 1356789

URL: http://svn.apache.org/viewvc?rev=1356789&view=rev
Log:
Switch the remaining pieces of the wc_db api to using conflict skels for
transfering conflicts. Reconstruct conflict descriptors in
svn_wc__read_conflicts().

* subversion/libsvn_client/merge.c
  (tree_conflict,
   merge_file_added): Remove assumption that you can retrieve conflicts
     on non-existing paths without an error.

* subversion/libsvn_wc/conflicts.c
  (svn_wc__read_conflicts): Create conflict descriptors from the skel from
    wc_db.

* subversion/libsvn_wc/wc_db.c
  (includes): Document that we only need tree_conflicts.h for non skel mode.
  (svn_wc__db_read_conflicts): Rename to ...
  (svn_wc__db_read_conflict): ... this and return the conflict as a non-const
    skel.

* subversion/libsvn_wc/wc_db.h
  (svn_wc__db_read_conflicts): Rename to ...
  (svn_wc__db_read_conflict): ... this and update documentation.

Modified:
    subversion/trunk/subversion/libsvn_client/merge.c
    subversion/trunk/subversion/libsvn_wc/conflicts.c
    subversion/trunk/subversion/libsvn_wc/wc_db.c
    subversion/trunk/subversion/libsvn_wc/wc_db.h

Modified: subversion/trunk/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/merge.c?rev=1356789&r1=1356788&r2=1356789&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/merge.c (original)
+++ subversion/trunk/subversion/libsvn_client/merge.c Tue Jul  3 15:30:29 2012
@@ -661,13 +661,24 @@ tree_conflict(merge_cmd_baton_t *merge_b
               svn_wc_conflict_reason_t reason)
 {
   const svn_wc_conflict_description2_t *existing_conflict;
+  svn_error_t *err;
 
   if (merge_b->record_only || merge_b->dry_run)
     return SVN_NO_ERROR;
 
-  SVN_ERR(svn_wc__get_tree_conflict(&existing_conflict, merge_b->ctx->wc_ctx,
-                                    victim_abspath, merge_b->pool,
-                                    merge_b->pool));
+  err = svn_wc__get_tree_conflict(&existing_conflict, merge_b->ctx->wc_ctx,
+                                  victim_abspath, merge_b->pool,
+                                  merge_b->pool);
+
+  if (err)
+    {
+      if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
+        return svn_error_trace(err);
+
+      svn_error_clear(err);
+      existing_conflict = FALSE;
+    }
+
   if (existing_conflict == NULL)
     {
       svn_wc_conflict_description2_t *conflict;
@@ -1869,6 +1880,7 @@ merge_file_added(svn_wc_notify_state_t *
             svn_stream_t *new_contents, *new_base_contents;
             apr_hash_t *new_base_props, *new_props;
             const svn_wc_conflict_description2_t *existing_conflict;
+            svn_error_t *err;
 
             /* If this is a merge from the same repository as our
                working copy, we handle adds as add-with-history.
@@ -1904,10 +1916,20 @@ merge_file_added(svn_wc_notify_state_t *
                                                  scratch_pool, scratch_pool));
               }
 
-            SVN_ERR(svn_wc__get_tree_conflict(&existing_conflict,
-                                              merge_b->ctx->wc_ctx,
-                                              mine_abspath, merge_b->pool,
-                                              merge_b->pool));
+            err = svn_wc__get_tree_conflict(&existing_conflict,
+                                            merge_b->ctx->wc_ctx,
+                                            mine_abspath, merge_b->pool,
+                                            merge_b->pool);
+
+            if (err)
+              {
+                if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
+                  return svn_error_trace(err);
+
+                svn_error_clear(err);
+                existing_conflict = FALSE;
+              }
+
             if (existing_conflict)
               {
                 svn_boolean_t moved_here;

Modified: subversion/trunk/subversion/libsvn_wc/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/conflicts.c?rev=1356789&r1=1356788&r2=1356789&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/trunk/subversion/libsvn_wc/conflicts.c Tue Jul  3 15:30:29 2012
@@ -1798,10 +1798,165 @@ svn_wc__read_conflicts(const apr_array_h
                        apr_pool_t *result_pool,
                        apr_pool_t *scratch_pool)
 {
-  return svn_error_trace(
-            svn_wc__db_read_conflicts(conflicts,
-                                      db, local_abspath,
-                                      result_pool, scratch_pool));
+  svn_skel_t *conflict_skel;
+  apr_array_header_t *cflcts;
+  svn_boolean_t prop_conflicted;
+  svn_boolean_t text_conflicted;
+  svn_boolean_t tree_conflicted;
+  svn_wc_operation_t operation;
+  const apr_array_header_t *locations;
+  svn_error_t *err;
+
+  SVN_ERR(svn_wc__db_read_conflict(&conflict_skel, db, local_abspath,
+                                   scratch_pool, scratch_pool));
+
+  if (!conflict_skel)
+    {
+      /* Some callers expect not NULL */
+      *conflicts = apr_array_make(result_pool, 0,
+                                  sizeof(svn_wc_conflict_description2_t*));;
+      return SVN_NO_ERROR;
+    }
+
+  SVN_ERR(svn_wc__conflict_read_info(&operation, &locations, &text_conflicted,
+                                     &prop_conflicted, &tree_conflicted,
+                                     db, local_abspath, conflict_skel,
+                                     scratch_pool, scratch_pool));
+
+  cflcts = apr_array_make(result_pool, 4,
+                          sizeof(svn_wc_conflict_description2_t*));
+
+  if (prop_conflicted)
+    {
+      svn_wc_conflict_description2_t *desc;
+      desc  = svn_wc_conflict_description_create_prop2(local_abspath,
+                                                       svn_node_unknown,
+                                                       "",
+                                                       result_pool);
+
+      SVN_ERR(svn_wc__conflict_read_prop_conflict(&desc->their_abspath,
+                                                  NULL, NULL,  NULL, NULL,
+                                                  db, local_abspath,
+                                                  conflict_skel,
+                                                  result_pool, scratch_pool));
+
+      APR_ARRAY_PUSH(cflcts, svn_wc_conflict_description2_t*) = desc;
+    }
+
+  if (text_conflicted)
+    {
+      svn_wc_conflict_description2_t *desc;
+      desc  = svn_wc_conflict_description_create_text2(local_abspath,
+                                                       result_pool);
+
+      SVN_ERR(svn_wc__conflict_read_text_conflict(&desc->my_abspath,
+                                                  &desc->base_abspath,
+                                                  &desc->their_abspath,
+                                                  db, local_abspath,
+                                                  conflict_skel,
+                                                  result_pool, scratch_pool));
+
+      desc->merged_file = apr_pstrdup(result_pool, local_abspath);
+
+      APR_ARRAY_PUSH(cflcts, svn_wc_conflict_description2_t*) = desc;
+    }
+
+  if (tree_conflicted)
+    {
+      svn_wc_conflict_description2_t *desc;
+      svn_wc_conflict_version_t *v1;
+      svn_wc_conflict_version_t *v2;
+      svn_node_kind_t tc_kind;
+      svn_wc_conflict_reason_t local_change;
+      svn_wc_conflict_action_t incoming_change;
+
+      SVN_ERR(svn_wc__conflict_read_tree_conflict(&local_change,
+                                                  &incoming_change,
+                                                  db, local_abspath,
+                                                  conflict_skel,
+                                                  scratch_pool, scratch_pool));
+
+      v1 = (locations && locations->nelts > 0)
+                    ? APR_ARRAY_IDX(locations, 0, svn_wc_conflict_version_t *)
+                    : NULL;
+
+      v2 = (locations && locations->nelts > 1)
+                    ? APR_ARRAY_IDX(locations, 1, svn_wc_conflict_version_t *)
+                    : NULL;
+
+      if (incoming_change != svn_wc_conflict_action_delete
+          && (operation == svn_wc_operation_update
+              || operation == svn_wc_operation_switch))
+        {
+          svn_wc__db_status_t status;
+          svn_revnum_t revision;
+          const char *repos_relpath;
+          const char *repos_root_url;
+          const char *repos_uuid;
+          svn_kind_t kind;
+          svn_error_t *err;
+
+          /* ### Theoretically we should just fetch the BASE information
+                 here. This code might need tweaks until all tree conflicts
+                 are installed in the proper state */
+
+          SVN_ERR_ASSERT(v2 == NULL); /* Not set for update and switch */
+
+          /* With an update or switch we have to fetch the second location
+             for a tree conflict from WORKING. (For text or prop from BASE)
+           */
+          err = svn_wc__db_base_get_info(&status, &kind, &revision,
+                                         &repos_relpath, &repos_root_url,
+                                         &repos_uuid, NULL, NULL, NULL,
+                                         NULL, NULL, NULL, NULL, NULL, NULL,
+                                         db, local_abspath,
+                                         scratch_pool, scratch_pool);
+
+          if (err)
+            {
+              if (err && err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
+                return svn_error_trace(err);
+
+              svn_error_clear(err);
+              /* Ignore BASE */
+
+              tc_kind = svn_node_file; /* Avoid assertion */
+            }
+          else if (repos_relpath)
+            {
+              v2 = svn_wc_conflict_version_create2(repos_root_url,
+                                                   repos_uuid,
+                                                   repos_relpath,
+                                                   revision,
+                                            svn__node_kind_from_kind(kind),
+                                                   scratch_pool);
+              tc_kind = svn__node_kind_from_kind(kind);
+            }
+          else
+            tc_kind = svn_node_file; /* Avoid assertion */
+        }
+      else
+        {
+          if (v1)
+            tc_kind = v1->node_kind;
+          else if (v2)
+            tc_kind = v2->node_kind;
+          else
+            tc_kind = svn_node_file; /* Avoid assertion */
+        }
+
+      desc  = svn_wc_conflict_description_create_tree2(local_abspath, tc_kind,
+                                                       operation, v1, v2,
+                                                       result_pool);
+
+      desc->reason = local_change;
+      desc->action = incoming_change;
+
+      APR_ARRAY_PUSH(cflcts, const svn_wc_conflict_description2_t *) = desc;
+    }
+
+  *conflicts = cflcts;
+  return SVN_NO_ERROR;
 }
 
 

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1356789&r1=1356788&r2=1356789&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Tue Jul  3 15:30:29 2012
@@ -43,7 +43,9 @@
 #include "entries.h"
 #include "lock.h"
 #include "conflicts.h"
+#if SVN_WC__VERSION < SVN_WC__USES_CONFLICT_SKELS
 #include "tree_conflicts.h"
+#endif
 #include "wc_db_private.h"
 #include "workqueue.h"
 
@@ -5247,8 +5249,6 @@ mark_conflict(svn_wc__db_wcroot_t *wcroo
       svn_boolean_t text_conflict;
       svn_boolean_t prop_conflict;
       svn_boolean_t tree_conflict;
-      svn_wc_conflict_reason_t local_change;
-      svn_wc_conflict_action_t incoming_change;
       const apr_array_header_t *locations;
       svn_wc_operation_t operation;
 
@@ -5336,6 +5336,8 @@ mark_conflict(svn_wc__db_wcroot_t *wcroo
           svn_wc_conflict_version_t *v2;
           svn_node_kind_t tc_kind;
           svn_skel_t *skel;
+          svn_wc_conflict_reason_t local_change;
+          svn_wc_conflict_action_t incoming_change;
 
           SVN_ERR(svn_wc__conflict_read_tree_conflict(&local_change,
                                                       &incoming_change,
@@ -11610,115 +11612,195 @@ svn_wc__db_get_conflict_marker_files(apr
 
 
 svn_error_t *
-svn_wc__db_read_conflicts(const apr_array_header_t **conflicts,
-                          svn_wc__db_t *db,
-                          const char *local_abspath,
-                          apr_pool_t *result_pool,
-                          apr_pool_t *scratch_pool)
+svn_wc__db_read_conflict(svn_skel_t **conflict,
+                         svn_wc__db_t *db,
+                         const char *local_abspath,
+                         apr_pool_t *result_pool,
+                         apr_pool_t *scratch_pool)
 {
   svn_wc__db_wcroot_t *wcroot;
   const char *local_relpath;
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
-  apr_array_header_t *cflcts;
 
   /* The parent should be a working copy directory. */
   SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
                               local_abspath, scratch_pool, scratch_pool));
   VERIFY_USABLE_WCROOT(wcroot);
 
-  /* ### This will be much easier once we have all conflicts in one
-         field of actual.*/
-
-  /* First look for text and property conflicts in ACTUAL */
+  /* Check if we have a conflict in ACTUAL */
   SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                     STMT_SELECT_ACTUAL_NODE));
   SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
 
-  cflcts = apr_array_make(result_pool, 4,
-                           sizeof(svn_wc_conflict_description2_t*));
-
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
 
-  if (have_row)
+  if (! have_row)
     {
-#if SVN_WC__VERSION < SVN_WC__USES_CONFLICT_SKELS
-      const char *prop_reject;
-      const char *conflict_old;
-      const char *conflict_new;
-      const char *conflict_working;
-      const char *conflict_data;
-
-      /* ### Store in description! */
-      prop_reject = svn_sqlite__column_text(stmt, 6, NULL);
-      if (prop_reject)
-        {
-          svn_wc_conflict_description2_t *desc;
+      /* Do this while stmt is still open to avoid closing the sqlite
+         transaction and then reopening. */
+      svn_sqlite__stmt_t *stmt_node;
+      svn_error_t *err;
 
-          desc  = svn_wc_conflict_description_create_prop2(local_abspath,
-                                                           svn_node_unknown,
-                                                           "",
-                                                           result_pool);
+      err = svn_sqlite__get_statement(&stmt_node, wcroot->sdb,
+                                      STMT_SELECT_NODE_INFO);
 
-          desc->their_abspath = svn_dirent_join(wcroot->abspath, prop_reject,
-                                                result_pool);
+      if (err)
+        stmt_node = NULL;
+      else
+        err = svn_sqlite__bindf(stmt_node, "is", wcroot->wc_id,
+                                local_relpath);
 
-          APR_ARRAY_PUSH(cflcts, svn_wc_conflict_description2_t*) = desc;
-        }
+      if (!err)
+        err = svn_sqlite__step(&have_row, stmt_node);
 
-      conflict_old = svn_sqlite__column_text(stmt, 3, NULL);
-      conflict_new = svn_sqlite__column_text(stmt, 4, NULL);
-      conflict_working = svn_sqlite__column_text(stmt, 5, NULL);
+      if (stmt_node)
+        err = svn_error_compose_create(err,
+                                       svn_sqlite__reset(stmt_node));
+
+      SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
 
-      if (conflict_old || conflict_new || conflict_working)
+      if (have_row)
         {
-          svn_wc_conflict_description2_t *desc
-              = svn_wc_conflict_description_create_text2(local_abspath,
-                                                         result_pool);
+          *conflict = NULL;
+          return SVN_NO_ERROR;
+        }
 
-          if (conflict_old)
-            desc->base_abspath = svn_dirent_join(wcroot->abspath, conflict_old,
-                                                 result_pool);
-          if (conflict_new)
-            desc->their_abspath = svn_dirent_join(wcroot->abspath, conflict_new,
-                                                  result_pool);
-          if (conflict_working)
-            desc->my_abspath = svn_dirent_join(wcroot->abspath,
-                                               conflict_working, result_pool);
-          desc->merged_file = apr_pstrdup(result_pool, local_abspath);
+      return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+                               _("The node '%s' was not found."),
+                                   path_for_error_message(wcroot,
+                                                          local_relpath,
+                                                          scratch_pool));
+    }
 
-          APR_ARRAY_PUSH(cflcts, svn_wc_conflict_description2_t*) = desc;
-        }
+#if SVN_WC__VERSION < SVN_WC__USES_CONFLICT_SKELS
+  {
+    const char *conflict_old = svn_sqlite__column_text(stmt, 3, NULL);
+    const char *conflict_new = svn_sqlite__column_text(stmt, 4, NULL);
+    const char *conflict_wrk = svn_sqlite__column_text(stmt, 5, NULL);
+    const char *conflict_prj = svn_sqlite__column_text(stmt, 6, NULL);
+    const char *tree_conflict = svn_sqlite__column_text(stmt, 7, NULL);
+    svn_skel_t *conflict_skel = NULL;
+    svn_error_t *err = NULL;
 
-      conflict_data = svn_sqlite__column_text(stmt, 7, scratch_pool);
-      if (conflict_data)
-        {
-          const svn_wc_conflict_description2_t *desc;
-          const svn_skel_t *skel;
-          svn_error_t *err;
+    if (conflict_old || conflict_new || conflict_wrk)
+      {
+        conflict_skel = svn_wc__conflict_skel_create(result_pool);
 
-          skel = svn_skel__parse(conflict_data, strlen(conflict_data),
-                                 scratch_pool);
-          err = svn_wc__deserialize_conflict(&desc, skel,
+        if (conflict_old)
+          conflict_old = svn_dirent_join(wcroot->abspath, conflict_old,
+                                         scratch_pool);
+
+        if (conflict_new)
+          conflict_new = svn_dirent_join(wcroot->abspath, conflict_new,
+                                         scratch_pool);
+
+        if (conflict_wrk)
+          conflict_wrk = svn_dirent_join(wcroot->abspath, conflict_wrk,
+                                         scratch_pool);
+
+        err = svn_wc__conflict_skel_add_text_conflict(conflict_skel,
+                                                      db, local_abspath,
+                                                      conflict_wrk,
+                                                      conflict_old,
+                                                      conflict_new,
+                                                      result_pool,
+                                                      scratch_pool);
+      }
+
+    if (!err && conflict_prj)
+      {
+        if (!conflict_skel)
+          conflict_skel = svn_wc__conflict_skel_create(result_pool);
+
+        if (conflict_prj)
+          conflict_prj = svn_dirent_join(wcroot->abspath, conflict_prj,
+                                         scratch_pool);
+
+        err = svn_wc__conflict_skel_add_prop_conflict(conflict_skel,
+                                                      db, local_abspath,
+                                                      conflict_prj,
+                                                      NULL, NULL, NULL,
+                                                  apr_hash_make(scratch_pool),
+                                                      result_pool,
+                                                      scratch_pool);
+      }
+
+    if (!err && tree_conflict)
+      {
+        const svn_wc_conflict_description2_t *tc;
+        const svn_skel_t *tc_skel;
+        if (!conflict_skel)
+          conflict_skel = svn_wc__conflict_skel_create(result_pool);
+
+        tc_skel = svn_skel__parse(tree_conflict, strlen(tree_conflict),
+                                  scratch_pool);
+        err = svn_wc__deserialize_conflict(
+                          &tc, tc_skel,
                           svn_dirent_dirname(local_abspath, scratch_pool),
-                          result_pool, scratch_pool);
+                          scratch_pool, scratch_pool);
 
-          if (err)
-            SVN_ERR(svn_error_compose_create(err,
-                                             svn_sqlite__reset(stmt)));
+        if (!err)
+          err = svn_wc__conflict_skel_add_tree_conflict(conflict_skel,
+                                                        db, local_abspath,
+                                                        tc->reason,
+                                                        tc->action,
+                                                        result_pool,
+                                                        scratch_pool);
+
+        if (!err)
+          switch (tc->operation)
+            {
+              case svn_wc_operation_merge:
+                err = svn_wc__conflict_skel_set_op_merge(conflict_skel,
+                                                         tc->src_left_version,
+                                                         tc->src_right_version,
+                                                         result_pool,
+                                                         scratch_pool);
+                break;
+              case svn_wc_operation_update:
+              default:
+                err = svn_wc__conflict_skel_set_op_update(conflict_skel,
+                                                          tc->src_left_version,
+                                                          result_pool,
+                                                          scratch_pool);
+                break;
+              case svn_wc_operation_switch:
+                err = svn_wc__conflict_skel_set_op_switch(conflict_skel,
+                                                          tc->src_left_version,
+                                                          result_pool,
+                                                          scratch_pool);
+                break;
+            }
+      }
+    else if (!err && conflict_skel)
+      {
+        err = svn_wc__conflict_skel_set_op_update(conflict_skel, NULL,
+                                                  result_pool, scratch_pool);
+      }
 
-          APR_ARRAY_PUSH(cflcts, const svn_wc_conflict_description2_t *) = desc;
-        }
+    if (err)
+      return svn_error_trace(
+                        svn_error_compose_create(err, svn_sqlite__reset(stmt)));
+
+    *conflict = conflict_skel;
+  }
 #else
-      SVN_ERR_MALFUNCTION();
-#endif
-    }
+  {
+    apr_size_t cfl_len;
+    const void *cfl_data;
 
-  SVN_ERR(svn_sqlite__reset(stmt));
+    /* svn_skel__parse doesn't copy data, so store in result_pool */
+    cfl_data = svn_sqlite__column_blob(stmt, 2, &cfl_len, result_pool);
 
-  *conflicts = cflcts;
+    if (cfl_data)
+      *conflict = svn_skel__parse(cfl_data, cfl_len, result_pool);
+    else
+      *conflict = NULL;
+  }
+#endif
 
-  return SVN_NO_ERROR;
+  return svn_error_trace(svn_sqlite__reset(stmt));
 }
 
 

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=1356789&r1=1356788&r2=1356789&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Tue Jul  3 15:30:29 2012
@@ -2119,22 +2119,20 @@ svn_wc__db_get_conflict_marker_files(apr
                                      apr_pool_t *result_pool,
                                      apr_pool_t *scratch_pool);
 
-/* Read into CONFLICTS svn_wc_conflict_description2_t* structs
-   for all conflicts that have LOCAL_ABSPATH as victim.
+/* Read the conflict information recorded on LOCAL_ABSPATH in *CONFLICT,
+   an editable conflict skel.
 
-   Victim must be versioned or be part of a tree conflict.
+   If the node exists, but does not have a conflict set *CONFLICT to NULL,
+   otherwise return a SVN_ERR_WC_PATH_NOT_FOUND error.
 
    Allocate *CONFLICTS in RESULT_POOL and do temporary allocations in
    SCRATCH_POOL */
-/* ### Currently there can be just one property conflict recorded
-       per victim */
-/*  ### This function will probably be removed. */
 svn_error_t *
-svn_wc__db_read_conflicts(const apr_array_header_t **conflicts,
-                          svn_wc__db_t *db,
-                          const char *local_abspath,
-                          apr_pool_t *result_pool,
-                          apr_pool_t *scratch_pool);
+svn_wc__db_read_conflict(svn_skel_t **conflict,
+                         svn_wc__db_t *db,
+                         const char *local_abspath,
+                         apr_pool_t *result_pool,
+                         apr_pool_t *scratch_pool);
 
 
 /* Return the kind of the node in DB at LOCAL_ABSPATH. The WORKING tree will