Kiln » Dependencies » Dulwich Read More
Clone URL:  
Pushed to one repository · View In Graph Contained in master

objects: Allow tree entries to be sorted by name.

Change-Id: I31e00df32b2a331337b577a55311c5764c04c37c

Changeset 35f04d4ba0ea

Parent 25601d22ffea

committed by Jelmer Vernooij

authored by Dave Borowitz

Changes to 3 files · Browse files at 35f04d4ba0ea Showing diff from parent 25601d22ffea Diff from another changeset...

 
146
147
148
149
 
 
 
 
 
 
150
151
152
153
 
 
154
 
 
 
 
155
156
157
158
159
 
 
 
 
 
160
161
162
 
199
200
201
202
 
203
204
205
 
223
224
225
226
 
227
228
229
 
146
147
148
 
149
150
151
152
153
154
155
156
 
 
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
 
213
214
215
 
216
217
218
219
 
237
238
239
 
240
241
242
243
@@ -146,17 +146,31 @@
  return strcmp(remain_a, remain_b);  }   -static PyObject *py_sorted_tree_items(PyObject *self, PyObject *entries) +int cmp_tree_item_name_order(const void *_a, const void *_b) { + const struct tree_item *a = _a, *b = _b; + return strcmp(a->name, b->name); +} + +static PyObject *py_sorted_tree_items(PyObject *self, PyObject *args)  {   struct tree_item *qsort_entries = NULL; - int num_entries, n = 0, i; - PyObject *ret, *key, *value, *py_mode, *py_sha; + int name_order, num_entries, n = 0, i; + PyObject *entries, *py_name_order, *ret, *key, *value, *py_mode, *py_sha;   Py_ssize_t pos = 0; + int (*cmp)(const void *, const void *); + + if (!PyArg_ParseTuple(args, "OO", &entries, &py_name_order)) + goto error;     if (!PyDict_Check(entries)) {   PyErr_SetString(PyExc_TypeError, "Argument not a dictionary");   goto error;   } + + name_order = PyObject_IsTrue(py_name_order); + if (name_order == -1) + goto error; + cmp = name_order ? cmp_tree_item_name_order : cmp_tree_item;     num_entries = PyDict_Size(entries);   if (PyErr_Occurred()) @@ -199,7 +213,7 @@
  n++;   }   - qsort(qsort_entries, num_entries, sizeof(struct tree_item), cmp_tree_item); + qsort(qsort_entries, num_entries, sizeof(struct tree_item), cmp);     ret = PyList_New(num_entries);   if (ret == NULL) { @@ -223,7 +237,7 @@
   static PyMethodDef py_objects_methods[] = {   { "parse_tree", (PyCFunction)py_parse_tree, METH_VARARGS, NULL }, - { "sorted_tree_items", (PyCFunction)py_sorted_tree_items, METH_O, NULL }, + { "sorted_tree_items", py_sorted_tree_items, METH_VARARGS, NULL },   { NULL, NULL, 0, NULL }  };  
 
730
731
732
733
734
735
736
 
 
 
 
 
 
737
738
739
740
 
 
741
742
743
 
747
748
749
750
 
751
752
753
754
755
 
 
 
 
 
756
757
758
 
833
834
835
836
837
838
 
 
 
 
839
840
841
842
 
843
844
845
 
730
731
732
 
 
 
 
733
734
735
736
737
738
739
740
741
 
742
743
744
745
746
 
750
751
752
 
753
754
755
756
757
758
759
760
761
762
763
764
765
766
 
841
842
843
 
 
 
844
845
846
847
848
849
850
 
851
852
853
854
@@ -730,14 +730,17 @@
  yield "%04o %s\0%s" % (mode, name, hex_to_sha(hexsha))     -def sorted_tree_items(entries): - """Iterate over a tree entries dictionary in the order in which - the items would be serialized. - +def sorted_tree_items(entries, name_order): + """Iterate over a tree entries dictionary. + + :param name_order: If True, iterate entries in order of their name. If + False, iterate entries in tree order, that is, treat subtree entries as + having '/' appended.   :param entries: Dictionary mapping names to (mode, sha) tuples   :return: Iterator over (name, mode, hexsha)   """ - for name, entry in sorted(entries.iteritems(), cmp=cmp_entry): + cmp_func = name_order and cmp_entry_name_order or cmp_entry + for name, entry in sorted(entries.iteritems(), cmp=cmp_func):   mode, hexsha = entry   # Stricter type checks than normal to mirror checks in the C version.   mode = int(mode) @@ -747,12 +750,17 @@
     def cmp_entry((name1, value1), (name2, value2)): - """Compare two tree entries.""" + """Compare two tree entries in tree order."""   if stat.S_ISDIR(value1[0]):   name1 += "/"   if stat.S_ISDIR(value2[0]):   name2 += "/"   return cmp(name1, name2) + + +def cmp_entry_name_order(entry1, entry2): + """Compare two tree entries in name order.""" + return cmp(entry1[0], entry2[0])      class Tree(ShaFile): @@ -833,13 +841,14 @@
  return [   (mode, name, hexsha) for (name, mode, hexsha) in self.iteritems()]   - def iteritems(self): - """Iterate over entries in the order in which they would be serialized. - + def iteritems(self, name_order=False): + """Iterate over entries. + + :param name_order: If True, iterate in name order instead of tree order.   :return: Iterator over (name, mode, sha) tuples   """   self._ensure_parsed() - return sorted_tree_items(self._entries) + return sorted_tree_items(self._entries, name_order)     def items(self):   """Return the sorted entries in this tree.
 
476
477
478
479
 
480
481
482
 
501
502
503
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
504
505
506
 
476
477
478
 
479
480
481
482
 
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
@@ -476,7 +476,7 @@
    def _do_test_sorted_tree_items(self, sorted_tree_items):   def do_sort(entries): - return list(sorted_tree_items(entries)) + return list(sorted_tree_items(entries, False))     actual = do_sort(_TREE_ITEMS)   self.assertEqual(_SORTED_TREE_ITEMS, actual) @@ -501,6 +501,23 @@
  if sorted_tree_items is _sorted_tree_items_py:   raise TestSkipped('sorted_tree_items extension not found')   self._do_test_sorted_tree_items(sorted_tree_items) + + def _do_test_sorted_tree_items_name_order(self, sorted_tree_items): + self.assertEqual([ + TreeEntry('a', stat.S_IFDIR, + 'd80c186a03f423a81b39df39dc87fd269736ca86'), + TreeEntry('a.c', 0100755, 'd80c186a03f423a81b39df39dc87fd269736ca86'), + TreeEntry('a/c', stat.S_IFDIR, + 'd80c186a03f423a81b39df39dc87fd269736ca86'), + ], list(sorted_tree_items(_TREE_ITEMS, True))) + + def test_sorted_tree_items_name_order(self): + self._do_test_sorted_tree_items_name_order(_sorted_tree_items_py) + + def test_sorted_tree_items_name_order_extension(self): + if sorted_tree_items is _sorted_tree_items_py: + raise TestSkipped('sorted_tree_items extension not found') + self._do_test_sorted_tree_items_name_order(sorted_tree_items)     def test_check(self):   t = Tree