subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gst...@apache.org
Subject svn commit: r1332881 - /subversion/trunk/subversion/libsvn_delta/compat.c
Date Tue, 01 May 2012 23:14:03 GMT
Author: gstein
Date: Tue May  1 23:14:03 2012
New Revision: 1332881

URL: http://svn.apache.org/viewvc?rev=1332881&view=rev
Log:
Ev2 shims:

Be more careful with sorting paths in preparation for an Ev1 drive.
Deletes must come first (to properly handle case-insensitive
replacements), and it takes some tricky analysis to sort the paths
with this in mind.

* subversion/libsvn_delta/compat.c:
  (count_components): helper function to count the number of path
    components in a relpath.
  (sort_deletes_first): ensure the root is always sorted first. ensure
    that deleted paths sort before "depthier" paths.

Modified:
    subversion/trunk/subversion/libsvn_delta/compat.c

Modified: subversion/trunk/subversion/libsvn_delta/compat.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_delta/compat.c?rev=1332881&r1=1332880&r2=1332881&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_delta/compat.c (original)
+++ subversion/trunk/subversion/libsvn_delta/compat.c Tue May  1 23:14:03 2012
@@ -1342,16 +1342,41 @@ rotate_cb(void *baton,
 
 
 static int
+count_components(const char *relpath)
+{
+  int count = 1;
+  const char *slash = strchr(relpath, '/');
+
+  while (slash != NULL)
+    {
+      ++count;
+      slash = strchr(slash + 1, '/');
+    }
+  return count;
+}
+
+
+static int
 sort_deletes_first(const svn_sort__item_t *item1,
                    const svn_sort__item_t *item2)
 {
   const char *relpath1 = item1->key;
   const char *relpath2 = item2->key;
+  const struct change_node *change1 = item1->value;
+  const struct change_node *change2 = item2->value;
   const char *slash1;
   const char *slash2;
   ptrdiff_t len1;
   ptrdiff_t len2;
 
+  /* Force the root to always sort first. Otherwise, it may look like a
+     sibling of its children (no slashes), and could get sorted *after*
+     any children that get deleted.  */
+  if (*relpath1 == '\0')
+    return -1;
+  if (*relpath2 == '\0')
+    return 1;
+
   /* Are these two items siblings? The 'if' statement tests if they are
      siblings in the root directory, or that slashes were found in both
      paths, that the length of the paths to those slashes match, and that
@@ -1364,9 +1389,6 @@ sort_deletes_first(const svn_sort__item_
           && (len1 = slash1 - relpath1) == (len2 = slash2 - relpath2)
           && memcmp(relpath1, relpath2, len1) == 0))
     {
-      const struct change_node *change1 = item1->value;
-      const struct change_node *change2 = item2->value;
-
       if (change1->action == RESTRUCTURE_DELETE)
         {
           if (change2->action == RESTRUCTURE_DELETE)
@@ -1396,6 +1418,28 @@ sort_deletes_first(const svn_sort__item_
       /* FALLTHROUGH */
     }
 
+  /* Paths-to-be-deleted with fewer components always sort earlier.
+
+     For example, gamma will sort before E/alpha.
+
+     Without this test, E/alpha lexicographically sorts before gamma,
+     but gamma sorts before E when gamma is to be deleted. This kind of
+     ordering would place E/alpha before E. Not good.
+
+     With this test, gamma sorts before E/alpha. E and E/alpha are then
+     sorted by svn_path_compare_paths() (which places E before E/alpha).  */
+  if (change1->action == RESTRUCTURE_DELETE
+      || change2->action == RESTRUCTURE_DELETE)
+    {
+      int count1 = count_components(relpath1);
+      int count2 = count_components(relpath2);
+
+      if (count1 < count2 && change1->action == RESTRUCTURE_DELETE)
+        return -1;
+      if (count1 > count2 && change2->action == RESTRUCTURE_DELETE)
+        return 1;
+    }
+
   /* Use svn_path_compare_paths() to get correct depth-based ordering.  */
   return svn_path_compare_paths(relpath1, relpath2);
 }
@@ -1678,11 +1722,6 @@ drive_changes(const struct editor_baton 
   /* Get a sorted list of Ev1-relative paths.  */
   paths = get_sorted_paths(eb->changes, eb->base_relpath, scratch_pool);
 
-#if 1
-  /* ### something is still broken. sort the paths normally for now.  */
-  qsort(paths->elts, paths->nelts, paths->elt_size, svn_sort_compare_paths);
-#endif
-
   /* We need to pass SVN_INVALID_REVNUM to the path_driver. It uses this
      revision whenever it opens directory batons. If we specified a "real"
      value, such as eb->root.base_revision, then it might use that for a



Mime
View raw message