rugged 0.25.0b9 → 0.25.0b10

Sign up to get free protection for your applications and to get access to all the features.
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