rugged 0.25.0b9 → 0.25.0b10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 446553349654cfec5239ed7c7bbb2d3cc57034fb
4
- data.tar.gz: 0e580f2767fe9eefac9073fc31f9d53eb997669b
3
+ metadata.gz: 97986b6a7f5c847a110b691dbeb47de7e7d874b4
4
+ data.tar.gz: 9c327457493ea0b9b92893fa2f755214bdde6118
5
5
  SHA512:
6
- metadata.gz: c6ce0b1c7541b0250884c74acb03932c2d15b978b85e816328e3d12daab134e1500289674aa2652aaad68c81144fc573a6de3f8b04837c81165e7b31179535ae
7
- data.tar.gz: 5cc83ce5093f126becab5c0647efe98664f3fe03bdd9c4c6ea0845ef75e541bbdfc63e9edd5caa92ecb76681f11ac73333d247e7506f0ef71a63f508b4f55ac7
6
+ metadata.gz: 5b18c64924beb9a8ce939b513d87ea3878c8cff5bf6f1908f4baf86b3aed57cb5416e5609e2f6c7c837ccffc20666433799e01363ef46c20b6edd8ec0de7283d
7
+ data.tar.gz: 036fdab8629da7429516183c8c2aa2c99d724dc58b747230012cb9d02e8f7be345904fd319dfc053f40d4ac87e8ed045cd6c6139a3f4dd62ca5dc282b1b14ff5
@@ -1,3 +1,3 @@
1
1
  module Rugged
2
- Version = VERSION = '0.25.0b9'
2
+ Version = VERSION = '0.25.0b10'
3
3
  end
@@ -508,7 +508,7 @@ ELSE ()
508
508
  ENDIF ()
509
509
  ENDIF()
510
510
 
511
- CHECK_SYMBOL_EXISTS(regcomp_l "xlocale.h" HAVE_REGCOMP_L)
511
+ CHECK_SYMBOL_EXISTS(regcomp_l "regex.h;xlocale.h" HAVE_REGCOMP_L)
512
512
  IF (HAVE_REGCOMP_L)
513
513
  ADD_DEFINITIONS(-DHAVE_REGCOMP_L)
514
514
  ENDIF ()
@@ -25,17 +25,15 @@ GIT_BEGIN_DECL
25
25
  */
26
26
  typedef enum {
27
27
  /**
28
- * Sort the repository contents in no particular ordering;
29
- * this sorting is arbitrary, implementation-specific
30
- * and subject to change at any time.
28
+ * Sort the output with the same default time-order method from git.
31
29
  * This is the default sorting for new walkers.
32
30
  */
33
31
  GIT_SORT_NONE = 0,
34
32
 
35
33
  /**
36
- * Sort the repository contents in topological order
37
- * (parents before children); this sorting mode
38
- * can be combined with time sorting.
34
+ * Sort the repository contents in topological order (parents before
35
+ * children); this sorting mode can be combined with time sorting to
36
+ * produce git's "time-order".
39
37
  */
40
38
  GIT_SORT_TOPOLOGICAL = 1 << 0,
41
39
 
@@ -13,10 +13,15 @@
13
13
 
14
14
  int git_commit_list_time_cmp(const void *a, const void *b)
15
15
  {
16
- const git_commit_list_node *commit_a = a;
17
- const git_commit_list_node *commit_b = b;
16
+ int64_t time_a = ((git_commit_list_node *) a)->time;
17
+ int64_t time_b = ((git_commit_list_node *) b)->time;
18
18
 
19
- return (commit_a->time < commit_b->time);
19
+ if (time_a < time_b)
20
+ return 1;
21
+ if (time_a > time_b)
22
+ return -1;
23
+
24
+ return 0;
20
25
  }
21
26
 
22
27
  git_commit_list *git_commit_list_insert(git_commit_list_node *item, git_commit_list **list_p)
@@ -28,6 +28,7 @@ typedef struct git_commit_list_node {
28
28
  uninteresting:1,
29
29
  topo_delay:1,
30
30
  parsed:1,
31
+ added:1,
31
32
  flags : FLAG_BITS;
32
33
 
33
34
  unsigned short in_degree;
@@ -93,7 +93,7 @@ int git_pqueue_insert(git_pqueue *pq, void *item)
93
93
  (void)git_pqueue_pop(pq);
94
94
  }
95
95
 
96
- if (!(error = git_vector_insert(pq, item)))
96
+ if (!(error = git_vector_insert(pq, item)) && pq->_cmp)
97
97
  pqueue_up(pq, pq->length - 1);
98
98
 
99
99
  return error;
@@ -101,9 +101,15 @@ int git_pqueue_insert(git_pqueue *pq, void *item)
101
101
 
102
102
  void *git_pqueue_pop(git_pqueue *pq)
103
103
  {
104
- void *rval = git_pqueue_get(pq, 0);
104
+ void *rval;
105
105
 
106
- if (git_pqueue_size(pq) > 1) {
106
+ if (!pq->_cmp) {
107
+ rval = git_vector_last(pq);
108
+ } else {
109
+ rval = git_pqueue_get(pq, 0);
110
+ }
111
+
112
+ if (git_pqueue_size(pq) > 1 && pq->_cmp) {
107
113
  /* move last item to top of heap, shrink, and push item down */
108
114
  pq->contents[0] = git_vector_last(pq);
109
115
  git_vector_pop(pq);
@@ -35,6 +35,7 @@ extern int git_pqueue_init(
35
35
  #define git_pqueue_clear git_vector_clear
36
36
  #define git_pqueue_size git_vector_length
37
37
  #define git_pqueue_get git_vector_get
38
+ #define git_pqueue_reverse git_vector_reverse
38
39
 
39
40
  /**
40
41
  * Insert a new item into the queue
@@ -586,7 +586,7 @@ static int rebase_init_operations(
586
586
  (error = git_revwalk_hide(revwalk, git_annotated_commit_id(upstream))) < 0)
587
587
  goto done;
588
588
 
589
- git_revwalk_sorting(revwalk, GIT_SORT_REVERSE | GIT_SORT_TIME);
589
+ git_revwalk_sorting(revwalk, GIT_SORT_REVERSE);
590
590
 
591
591
  while ((error = git_revwalk_next(&id, revwalk)) == 0) {
592
592
  if ((error = git_commit_lookup(&commit, repo, &id)) < 0)
@@ -13,6 +13,7 @@
13
13
  #include "revwalk.h"
14
14
  #include "git2/revparse.h"
15
15
  #include "merge.h"
16
+ #include "vector.h"
16
17
 
17
18
  GIT__USE_OIDMAP
18
19
 
@@ -41,97 +42,6 @@ git_commit_list_node *git_revwalk__commit_lookup(
41
42
  return commit;
42
43
  }
43
44
 
44
- typedef git_array_t(git_commit_list_node*) commit_list_node_array;
45
-
46
- static bool interesting_arr(commit_list_node_array arr)
47
- {
48
- git_commit_list_node **n;
49
- size_t i = 0, size;
50
-
51
- size = git_array_size(arr);
52
- for (i = 0; i < size; i++) {
53
- n = git_array_get(arr, i);
54
- if (!*n)
55
- break;
56
-
57
- if (!(*n)->uninteresting)
58
- return true;
59
- }
60
-
61
- return false;
62
- }
63
-
64
- static int mark_uninteresting(git_revwalk *walk, git_commit_list_node *commit)
65
- {
66
- int error;
67
- unsigned short i;
68
- commit_list_node_array pending = GIT_ARRAY_INIT;
69
- git_commit_list_node **tmp;
70
-
71
- assert(commit);
72
-
73
- do {
74
- commit->uninteresting = 1;
75
-
76
- if ((error = git_commit_list_parse(walk, commit)) < 0)
77
- return error;
78
-
79
- for (i = 0; i < commit->out_degree; ++i)
80
- if (!commit->parents[i]->uninteresting) {
81
- git_commit_list_node **node = git_array_alloc(pending);
82
- GITERR_CHECK_ALLOC(node);
83
- *node = commit->parents[i];
84
- }
85
-
86
- tmp = git_array_pop(pending);
87
- commit = tmp ? *tmp : NULL;
88
-
89
- } while (commit != NULL && !interesting_arr(pending));
90
-
91
- git_array_clear(pending);
92
-
93
- return 0;
94
- }
95
-
96
- static int process_commit(git_revwalk *walk, git_commit_list_node *commit, int hide)
97
- {
98
- int error;
99
-
100
- if (!hide && walk->hide_cb)
101
- hide = walk->hide_cb(&commit->oid, walk->hide_cb_payload);
102
-
103
- if (hide && mark_uninteresting(walk, commit) < 0)
104
- return -1;
105
-
106
- if (commit->seen)
107
- return 0;
108
-
109
- commit->seen = 1;
110
-
111
- if ((error = git_commit_list_parse(walk, commit)) < 0)
112
- return error;
113
-
114
- if (!hide)
115
- return walk->enqueue(walk, commit);
116
-
117
- return 0;
118
- }
119
-
120
- static int process_commit_parents(git_revwalk *walk, git_commit_list_node *commit)
121
- {
122
- unsigned short i, max;
123
- int error = 0;
124
-
125
- max = commit->out_degree;
126
- if (walk->first_parent && commit->out_degree)
127
- max = 1;
128
-
129
- for (i = 0; i < max && !error; ++i)
130
- error = process_commit(walk, commit->parents[i], commit->uninteresting);
131
-
132
- return error;
133
- }
134
-
135
45
  static int push_commit(git_revwalk *walk, const git_oid *oid, int uninteresting, int from_glob)
136
46
  {
137
47
  git_oid commit_id;
@@ -321,17 +231,12 @@ static int revwalk_enqueue_unsorted(git_revwalk *walk, git_commit_list_node *com
321
231
 
322
232
  static int revwalk_next_timesort(git_commit_list_node **object_out, git_revwalk *walk)
323
233
  {
324
- int error;
325
234
  git_commit_list_node *next;
326
235
 
327
- while ((next = git_pqueue_pop(&walk->iterator_time)) != NULL)
328
- if (!next->uninteresting) {
329
- if ((error = process_commit_parents(walk, next)) < 0)
330
- return error;
331
-
332
- *object_out = next;
333
- return 0;
334
- }
236
+ if ((next = git_pqueue_pop(&walk->iterator_time)) != NULL) {
237
+ *object_out = next;
238
+ return 0;
239
+ }
335
240
 
336
241
  giterr_clear();
337
242
  return GIT_ITEROVER;
@@ -339,17 +244,15 @@ static int revwalk_next_timesort(git_commit_list_node **object_out, git_revwalk
339
244
 
340
245
  static int revwalk_next_unsorted(git_commit_list_node **object_out, git_revwalk *walk)
341
246
  {
342
- int error;
343
247
  git_commit_list_node *next;
344
248
 
345
- while ((next = git_commit_list_pop(&walk->iterator_rand)) != NULL)
249
+ while ((next = git_commit_list_pop(&walk->iterator_rand)) != NULL) {
250
+ /* Some commits might become uninteresting after being added to the list */
346
251
  if (!next->uninteresting) {
347
- if ((error = process_commit_parents(walk, next)) < 0)
348
- return error;
349
-
350
252
  *object_out = next;
351
253
  return 0;
352
254
  }
255
+ }
353
256
 
354
257
  giterr_clear();
355
258
  return GIT_ITEROVER;
@@ -358,121 +261,283 @@ static int revwalk_next_unsorted(git_commit_list_node **object_out, git_revwalk
358
261
  static int revwalk_next_toposort(git_commit_list_node **object_out, git_revwalk *walk)
359
262
  {
360
263
  git_commit_list_node *next;
361
- unsigned short i, max;
362
264
 
363
- for (;;) {
364
- next = git_commit_list_pop(&walk->iterator_topo);
365
- if (next == NULL) {
366
- giterr_clear();
367
- return GIT_ITEROVER;
265
+ while ((next = git_commit_list_pop(&walk->iterator_topo)) != NULL) {
266
+ /* Some commits might become uninteresting after being added to the list */
267
+ if (!next->uninteresting) {
268
+ *object_out = next;
269
+ return 0;
368
270
  }
271
+ }
369
272
 
370
- if (next->in_degree > 0) {
371
- next->topo_delay = 1;
372
- continue;
273
+ giterr_clear();
274
+ return GIT_ITEROVER;
275
+ }
276
+
277
+ static int revwalk_next_reverse(git_commit_list_node **object_out, git_revwalk *walk)
278
+ {
279
+ *object_out = git_commit_list_pop(&walk->iterator_reverse);
280
+ return *object_out ? 0 : GIT_ITEROVER;
281
+ }
282
+
283
+ static void mark_parents_uninteresting(git_commit_list_node *commit)
284
+ {
285
+ unsigned short i;
286
+ git_commit_list *parents = NULL;
287
+
288
+ for (i = 0; i < commit->out_degree; i++)
289
+ git_commit_list_insert(commit->parents[i], &parents);
290
+
291
+
292
+ while (parents) {
293
+ git_commit_list_node *commit = git_commit_list_pop(&parents);
294
+
295
+ while (commit) {
296
+ if (commit->uninteresting)
297
+ break;
298
+
299
+ commit->uninteresting = 1;
300
+ /*
301
+ * If we've reached this commit some other way
302
+ * already, we need to mark its parents uninteresting
303
+ * as well.
304
+ */
305
+ if (!commit->parents)
306
+ break;
307
+
308
+ for (i = 0; i < commit->out_degree; i++)
309
+ git_commit_list_insert(commit->parents[i], &parents);
310
+ commit = commit->parents[0];
373
311
  }
312
+ }
313
+ }
374
314
 
315
+ static int add_parents_to_list(git_revwalk *walk, git_commit_list_node *commit, git_commit_list **list)
316
+ {
317
+ unsigned short i;
318
+ int error;
375
319
 
376
- max = next->out_degree;
377
- if (walk->first_parent && next->out_degree)
378
- max = 1;
320
+ if (commit->added)
321
+ return 0;
379
322
 
380
- for (i = 0; i < max; ++i) {
381
- git_commit_list_node *parent = next->parents[i];
323
+ commit->added = 1;
324
+
325
+ /*
326
+ * Go full on in the uninteresting case as we want to include
327
+ * as many of these as we can.
328
+ *
329
+ * Usually we haven't parsed the parent of a parent, but if we
330
+ * have it we reached it via other means so we want to mark
331
+ * its parents recursively too.
332
+ */
333
+ if (commit->uninteresting) {
334
+ for (i = 0; i < commit->out_degree; i++) {
335
+ git_commit_list_node *p = commit->parents[i];
336
+ p->uninteresting = 1;
382
337
 
383
- if (--parent->in_degree == 0 && parent->topo_delay) {
384
- parent->topo_delay = 0;
385
- if (git_commit_list_insert(parent, &walk->iterator_topo) == NULL)
386
- return -1;
387
- }
338
+ /* git does it gently here, but we don't like missing objects */
339
+ if ((error = git_commit_list_parse(walk, p)) < 0)
340
+ return error;
341
+
342
+ if (p->parents)
343
+ mark_parents_uninteresting(p);
344
+
345
+ p->seen = 1;
346
+ git_commit_list_insert_by_date(p, list);
388
347
  }
389
348
 
390
- *object_out = next;
391
349
  return 0;
392
350
  }
351
+
352
+ /*
353
+ * Now on to what we do if the commit is indeed
354
+ * interesting. Here we do want things like first-parent take
355
+ * effect as this is what we'll be showing.
356
+ */
357
+ for (i = 0; i < commit->out_degree; i++) {
358
+ git_commit_list_node *p = commit->parents[i];
359
+
360
+ if ((error = git_commit_list_parse(walk, p)) < 0)
361
+ return error;
362
+
363
+ if (walk->hide_cb && walk->hide_cb(&p->oid, walk->hide_cb_payload))
364
+ continue;
365
+
366
+ if (!p->seen) {
367
+ p->seen = 1;
368
+ git_commit_list_insert_by_date(p, list);
369
+ }
370
+
371
+ if (walk->first_parent)
372
+ break;
373
+ }
374
+ return 0;
393
375
  }
394
376
 
395
- static int revwalk_next_reverse(git_commit_list_node **object_out, git_revwalk *walk)
377
+ static int everybody_uninteresting(git_commit_list *orig)
396
378
  {
397
- *object_out = git_commit_list_pop(&walk->iterator_reverse);
398
- return *object_out ? 0 : GIT_ITEROVER;
379
+ git_commit_list *list = orig;
380
+
381
+ while (list) {
382
+ git_commit_list_node *commit = list->item;
383
+ list = list->next;
384
+ if (!commit->uninteresting)
385
+ return 0;
386
+ }
387
+
388
+ return 1;
399
389
  }
400
390
 
391
+ /* How many unintersting commits we want to look at after we run out of interesting ones */
392
+ #define SLOP 5
401
393
 
402
- static int interesting(git_pqueue *list)
394
+ static int still_interesting(git_commit_list *list, int64_t time, int slop)
403
395
  {
404
- size_t i;
396
+ /* The empty list is pretty boring */
397
+ if (!list)
398
+ return 0;
405
399
 
406
- for (i = 0; i < git_pqueue_size(list); i++) {
407
- git_commit_list_node *commit = git_pqueue_get(list, i);
408
- if (!commit->uninteresting)
409
- return 1;
410
- }
400
+ /*
401
+ * If the destination list has commits with an earlier date
402
+ * than our source we want to continue looking.
403
+ */
404
+ if (time <= list->item->time)
405
+ return SLOP;
411
406
 
412
- return 0;
407
+ /* If we find interesting commits, we reset the slop count */
408
+ if (!everybody_uninteresting(list))
409
+ return SLOP;
410
+
411
+ /* Everything's uninteresting, reduce the count */
412
+ return slop - 1;
413
413
  }
414
414
 
415
- static int contains(git_pqueue *list, git_commit_list_node *node)
415
+ static int limit_list(git_commit_list **out, git_revwalk *walk, git_commit_list *commits)
416
416
  {
417
- size_t i;
417
+ int error, slop = SLOP;
418
+ int64_t time = ~0ll;
419
+ git_commit_list *list = commits;
420
+ git_commit_list *newlist = NULL;
421
+ git_commit_list **p = &newlist;
422
+
423
+ while (list) {
424
+ git_commit_list_node *commit = git_commit_list_pop(&list);
425
+
426
+ if ((error = add_parents_to_list(walk, commit, &list)) < 0)
427
+ return error;
428
+
429
+ if (commit->uninteresting) {
430
+ mark_parents_uninteresting(commit);
431
+
432
+ slop = still_interesting(list, time, slop);
433
+ if (slop)
434
+ continue;
435
+
436
+ break;
437
+ }
438
+
439
+ if (!commit->uninteresting && walk->hide_cb && walk->hide_cb(&commit->oid, walk->hide_cb_payload))
440
+ continue;
418
441
 
419
- for (i = 0; i < git_pqueue_size(list); i++) {
420
- git_commit_list_node *commit = git_pqueue_get(list, i);
421
- if (commit == node)
422
- return 1;
442
+ time = commit->time;
443
+ p = &git_commit_list_insert(commit, p)->next;
423
444
  }
424
445
 
446
+ git_commit_list_free(&list);
447
+ *out = newlist;
425
448
  return 0;
426
449
  }
427
450
 
428
- static int premark_uninteresting(git_revwalk *walk)
451
+ static int sort_in_topological_order(git_commit_list **out, git_revwalk *walk, git_commit_list *list)
429
452
  {
430
- int error = 0;
453
+ git_commit_list *ll = NULL, *newlist, **pptr;
454
+ git_commit_list_node *next;
455
+ git_pqueue queue;
456
+ git_vector_cmp queue_cmp = NULL;
431
457
  unsigned short i;
432
- git_pqueue q;
433
- git_commit_list *list;
434
- git_commit_list_node *commit, *parent;
458
+ int error;
435
459
 
436
- if ((error = git_pqueue_init(&q, 0, 8, git_commit_list_time_cmp)) < 0)
437
- return error;
460
+ if (walk->sorting & GIT_SORT_TIME)
461
+ queue_cmp = git_commit_list_time_cmp;
438
462
 
439
- for (list = walk->user_input; list; list = list->next) {
440
- if ((error = git_commit_list_parse(walk, list->item)) < 0)
441
- goto cleanup;
463
+ if ((error = git_pqueue_init(&queue, 0, 8, queue_cmp)))
464
+ return error;
442
465
 
443
- if ((error = git_pqueue_insert(&q, list->item)) < 0)
444
- goto cleanup;
466
+ /*
467
+ * Start by resetting the in-degree to 1 for the commits in
468
+ * our list. We want to go through this list again, so we
469
+ * store it in the commit list as we extract it from the lower
470
+ * machinery.
471
+ */
472
+ for (ll = list; ll; ll = ll->next) {
473
+ ll->item->in_degree = 1;
445
474
  }
446
475
 
447
- while (interesting(&q)) {
448
- commit = git_pqueue_pop(&q);
449
-
450
- for (i = 0; i < commit->out_degree; i++) {
451
- parent = commit->parents[i];
476
+ /*
477
+ * Count up how many children each commit has. We limit
478
+ * ourselves to those commits in the original list (in-degree
479
+ * of 1) avoiding setting it for any parent that was hidden.
480
+ */
481
+ for(ll = list; ll; ll = ll->next) {
482
+ for (i = 0; i < ll->item->out_degree; ++i) {
483
+ git_commit_list_node *parent = ll->item->parents[i];
484
+ if (parent->in_degree)
485
+ parent->in_degree++;
486
+ }
487
+ }
452
488
 
453
- if ((error = git_commit_list_parse(walk, parent)) < 0)
489
+ /*
490
+ * Now we find the tips i.e. those not reachable from any other node
491
+ * i.e. those which still have an in-degree of 1.
492
+ */
493
+ for(ll = list; ll; ll = ll->next) {
494
+ if (ll->item->in_degree == 1) {
495
+ if ((error = git_pqueue_insert(&queue, ll->item)))
454
496
  goto cleanup;
497
+ }
498
+ }
499
+
500
+ /*
501
+ * We need to output the tips in the order that they came out of the
502
+ * traversal, so if we're not doing time-sorting, we need to reverse the
503
+ * pqueue in order to get them to come out as we inserted them.
504
+ */
505
+ if ((walk->sorting & GIT_SORT_TIME) == 0)
506
+ git_pqueue_reverse(&queue);
455
507
 
456
- if (commit->uninteresting)
457
- parent->uninteresting = 1;
458
508
 
459
- if (contains(&q, parent))
509
+ pptr = &newlist;
510
+ newlist = NULL;
511
+ while ((next = git_pqueue_pop(&queue)) != NULL) {
512
+ for (i = 0; i < next->out_degree; ++i) {
513
+ git_commit_list_node *parent = next->parents[i];
514
+ if (parent->in_degree == 0)
460
515
  continue;
461
516
 
462
- if ((error = git_pqueue_insert(&q, parent)) < 0)
463
- goto cleanup;
517
+ if (--parent->in_degree == 1) {
518
+ if ((error = git_pqueue_insert(&queue, parent)))
519
+ goto cleanup;
520
+ }
464
521
  }
522
+
523
+ /* All the children of 'item' have been emitted (since we got to it via the priority queue) */
524
+ next->in_degree = 0;
525
+
526
+ pptr = &git_commit_list_insert(next, pptr)->next;
465
527
  }
466
528
 
529
+ *out = newlist;
530
+ error = 0;
531
+
467
532
  cleanup:
468
- git_pqueue_free(&q);
533
+ git_pqueue_free(&queue);
469
534
  return error;
470
535
  }
471
536
 
472
537
  static int prepare_walk(git_revwalk *walk)
473
538
  {
474
539
  int error;
475
- git_commit_list *list;
540
+ git_commit_list *list, *commits = NULL;
476
541
  git_commit_list_node *next;
477
542
 
478
543
  /* If there were no pushes, we know that the walk is already over */
@@ -481,32 +546,42 @@ static int prepare_walk(git_revwalk *walk)
481
546
  return GIT_ITEROVER;
482
547
  }
483
548
 
484
- if (walk->did_hide && (error = premark_uninteresting(walk)) < 0)
485
- return error;
486
-
487
549
  for (list = walk->user_input; list; list = list->next) {
488
- if (process_commit(walk, list->item, list->item->uninteresting) < 0)
489
- return -1;
490
- }
550
+ git_commit_list_node *commit = list->item;
551
+ if ((error = git_commit_list_parse(walk, commit)) < 0)
552
+ return error;
491
553
 
554
+ if (commit->uninteresting)
555
+ mark_parents_uninteresting(commit);
492
556
 
493
- if (walk->sorting & GIT_SORT_TOPOLOGICAL) {
494
- unsigned short i;
557
+ if (!commit->seen) {
558
+ commit->seen = 1;
559
+ git_commit_list_insert(commit, &commits);
560
+ }
561
+ }
495
562
 
496
- while ((error = walk->get_next(&next, walk)) == 0) {
497
- for (i = 0; i < next->out_degree; ++i) {
498
- git_commit_list_node *parent = next->parents[i];
499
- parent->in_degree++;
500
- }
563
+ if ((error = limit_list(&commits, walk, commits)) < 0)
564
+ return error;
501
565
 
502
- if (git_commit_list_insert(next, &walk->iterator_topo) == NULL)
503
- return -1;
504
- }
566
+ if (walk->sorting & GIT_SORT_TOPOLOGICAL) {
567
+ error = sort_in_topological_order(&walk->iterator_topo, walk, commits);
568
+ git_commit_list_free(&commits);
505
569
 
506
- if (error != GIT_ITEROVER)
570
+ if (error < 0)
507
571
  return error;
508
572
 
509
573
  walk->get_next = &revwalk_next_toposort;
574
+ } else if (walk->sorting & GIT_SORT_TIME) {
575
+ for (list = commits; list && !error; list = list->next)
576
+ error = walk->enqueue(walk, list->item);
577
+
578
+ git_commit_list_free(&commits);
579
+
580
+ if (error < 0)
581
+ return error;
582
+ } else {
583
+ walk->iterator_rand = commits;
584
+ walk->get_next = revwalk_next_unsorted;
510
585
  }
511
586
 
512
587
  if (walk->sorting & GIT_SORT_REVERSE) {
@@ -632,6 +707,7 @@ void git_revwalk_reset(git_revwalk *walk)
632
707
  commit->in_degree = 0;
633
708
  commit->topo_delay = 0;
634
709
  commit->uninteresting = 0;
710
+ commit->added = 0;
635
711
  commit->flags = 0;
636
712
  });
637
713
 
@@ -401,3 +401,19 @@ int git_vector_verify_sorted(const git_vector *v)
401
401
 
402
402
  return 0;
403
403
  }
404
+
405
+ void git_vector_reverse(git_vector *v)
406
+ {
407
+ size_t a, b;
408
+
409
+ a = 0;
410
+ b = v->length - 1;
411
+
412
+ while (a < b) {
413
+ void *tmp = v->contents[a];
414
+ v->contents[a] = v->contents[b];
415
+ v->contents[b] = tmp;
416
+ a++;
417
+ b--;
418
+ }
419
+ }
@@ -118,4 +118,9 @@ GIT_INLINE(void) git_vector_set_cmp(git_vector *v, git_vector_cmp cmp)
118
118
  /* Just use this in tests, not for realz. returns -1 if not sorted */
119
119
  int git_vector_verify_sorted(const git_vector *v);
120
120
 
121
+ /**
122
+ * Reverse the vector in-place.
123
+ */
124
+ void git_vector_reverse(git_vector *v);
125
+
121
126
  #endif
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rugged
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.25.0b9
4
+ version: 0.25.0b10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Chacon
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-10-06 00:00:00.000000000 Z
12
+ date: 2016-10-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake-compiler