commit-reach: move walk methods from commit.c
There are several commit walks in the codebase. Group them together into a new commit-reach.c file and corresponding header. After we group these walks into one place, we can reduce duplicate logic by calling equivalent methods. The method declarations in commit.h are not touched by this commit and will be moved in a following commit. Many consumers need to point to commit-reach.h and that would bloat this commit. Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Derrick Stolee committed
Jul 20, 2018 at 16:33 UTC
5227c385667cadd3b34668329016755181fa98ea
5 files changed
+404
-359
Makefile
+1
@@ -829,6 +829,7 @@ LIB_OBJS += column.o
829
LIB_OBJS += combine-diff.o
830
LIB_OBJS += commit.o
831
LIB_OBJS += commit-graph.o
832
+LIB_OBJS += commit-reach.o
833
LIB_OBJS += compat/obstack.o
834
LIB_OBJS += compat/terminal.o
835
LIB_OBJS += config.o
commit-reach.c
new
+360
@@ -0,0 +1,360 @@
1
+#include "cache.h"
2
+#include "prio-queue.h"
3
+#include "commit.h"
4
+#include "commit-reach.h"
5
+
6
+/* Remember to update object flag allocation in object.h */
7
+#define PARENT1 (1u<<16)
8
+#define PARENT2 (1u<<17)
9
+#define STALE (1u<<18)
10
+#define RESULT (1u<<19)
11
+
12
+static const unsigned all_flags = (PARENT1 | PARENT2 | STALE | RESULT);
13
+
14
+static int queue_has_nonstale(struct prio_queue *queue)
15
+{
16
+ int i;
17
+ for (i = 0; i < queue->nr; i++) {
18
+ struct commit *commit = queue->array[i].data;
19
+ if (!(commit->object.flags & STALE))
20
+ return 1;
21
+ }
22
+ return 0;
23
+}
24
+
25
+/* all input commits in one and twos[] must have been parsed! */
26
+static struct commit_list *paint_down_to_common(struct commit *one, int n,
27
+ struct commit **twos,
28
+ int min_generation)
29
+{
30
+ struct prio_queue queue = { compare_commits_by_gen_then_commit_date };
31
+ struct commit_list *result = NULL;
32
+ int i;
33
+ uint32_t last_gen = GENERATION_NUMBER_INFINITY;
34
+
35
+ one->object.flags |= PARENT1;
36
+ if (!n) {
37
+ commit_list_append(one, &result);
38
+ return result;
39
+ }
40
+ prio_queue_put(&queue, one);
41
+
42
+ for (i = 0; i < n; i++) {
43
+ twos[i]->object.flags |= PARENT2;
44
+ prio_queue_put(&queue, twos[i]);
45
+ }
46
+
47
+ while (queue_has_nonstale(&queue)) {
48
+ struct commit *commit = prio_queue_get(&queue);
49
+ struct commit_list *parents;
50
+ int flags;
51
+
52
+ if (commit->generation > last_gen)
53
+ BUG("bad generation skip %8x > %8x at %s",
54
+ commit->generation, last_gen,
55
+ oid_to_hex(&commit->object.oid));
56
+ last_gen = commit->generation;
57
+
58
+ if (commit->generation < min_generation)
59
+ break;
60
+
61
+ flags = commit->object.flags & (PARENT1 | PARENT2 | STALE);
62
+ if (flags == (PARENT1 | PARENT2)) {
63
+ if (!(commit->object.flags & RESULT)) {
64
+ commit->object.flags |= RESULT;
65
+ commit_list_insert_by_date(commit, &result);
66
+ }
67
+ /* Mark parents of a found merge stale */
68
+ flags |= STALE;
69
+ }
70
+ parents = commit->parents;
71
+ while (parents) {
72
+ struct commit *p = parents->item;
73
+ parents = parents->next;
74
+ if ((p->object.flags & flags) == flags)
75
+ continue;
76
+ if (parse_commit(p))
77
+ return NULL;
78
+ p->object.flags |= flags;
79
+ prio_queue_put(&queue, p);
80
+ }
81
+ }
82
+
83
+ clear_prio_queue(&queue);
84
+ return result;
85
+}
86
+
87
+static struct commit_list *merge_bases_many(struct commit *one, int n, struct commit **twos)
88
+{
89
+ struct commit_list *list = NULL;
90
+ struct commit_list *result = NULL;
91
+ int i;
92
+
93
+ for (i = 0; i < n; i++) {
94
+ if (one == twos[i])
95
+ /*
96
+ * We do not mark this even with RESULT so we do not
97
+ * have to clean it up.
98
+ */
99
+ return commit_list_insert(one, &result);
100
+ }
101
+
102
+ if (parse_commit(one))
103
+ return NULL;
104
+ for (i = 0; i < n; i++) {
105
+ if (parse_commit(twos[i]))
106
+ return NULL;
107
+ }
108
+
109
+ list = paint_down_to_common(one, n, twos, 0);
110
+
111
+ while (list) {
112
+ struct commit *commit = pop_commit(&list);
113
+ if (!(commit->object.flags & STALE))
114
+ commit_list_insert_by_date(commit, &result);
115
+ }
116
+ return result;
117
+}
118
+
119
+struct commit_list *get_octopus_merge_bases(struct commit_list *in)
120
+{
121
+ struct commit_list *i, *j, *k, *ret = NULL;
122
+
123
+ if (!in)
124
+ return ret;
125
+
126
+ commit_list_insert(in->item, &ret);
127
+
128
+ for (i = in->next; i; i = i->next) {
129
+ struct commit_list *new_commits = NULL, *end = NULL;
130
+
131
+ for (j = ret; j; j = j->next) {
132
+ struct commit_list *bases;
133
+ bases = get_merge_bases(i->item, j->item);
134
+ if (!new_commits)
135
+ new_commits = bases;
136
+ else
137
+ end->next = bases;
138
+ for (k = bases; k; k = k->next)
139
+ end = k;
140
+ }
141
+ ret = new_commits;
142
+ }
143
+ return ret;
144
+}
145
+
146
+static int remove_redundant(struct commit **array, int cnt)
147
+{
148
+ /*
149
+ * Some commit in the array may be an ancestor of
150
+ * another commit. Move such commit to the end of
151
+ * the array, and return the number of commits that
152
+ * are independent from each other.
153
+ */
154
+ struct commit **work;
155
+ unsigned char *redundant;
156
+ int *filled_index;
157
+ int i, j, filled;
158
+
159
+ work = xcalloc(cnt, sizeof(*work));
160
+ redundant = xcalloc(cnt, 1);
161
+ ALLOC_ARRAY(filled_index, cnt - 1);
162
+
163
+ for (i = 0; i < cnt; i++)
164
+ parse_commit(array[i]);
165
+ for (i = 0; i < cnt; i++) {
166
+ struct commit_list *common;
167
+ uint32_t min_generation = array[i]->generation;
168
+
169
+ if (redundant[i])
170
+ continue;
171
+ for (j = filled = 0; j < cnt; j++) {
172
+ if (i == j || redundant[j])
173
+ continue;
174
+ filled_index[filled] = j;
175
+ work[filled++] = array[j];
176
+
177
+ if (array[j]->generation < min_generation)
178
+ min_generation = array[j]->generation;
179
+ }
180
+ common = paint_down_to_common(array[i], filled, work,
181
+ min_generation);
182
+ if (array[i]->object.flags & PARENT2)
183
+ redundant[i] = 1;
184
+ for (j = 0; j < filled; j++)
185
+ if (work[j]->object.flags & PARENT1)
186
+ redundant[filled_index[j]] = 1;
187
+ clear_commit_marks(array[i], all_flags);
188
+ clear_commit_marks_many(filled, work, all_flags);
189
+ free_commit_list(common);
190
+ }
191
+
192
+ /* Now collect the result */
193
+ COPY_ARRAY(work, array, cnt);
194
+ for (i = filled = 0; i < cnt; i++)
195
+ if (!redundant[i])
196
+ array[filled++] = work[i];
197
+ for (j = filled, i = 0; i < cnt; i++)
198
+ if (redundant[i])
199
+ array[j++] = work[i];
200
+ free(work);
201
+ free(redundant);
202
+ free(filled_index);
203
+ return filled;
204
+}
205
+
206
+static struct commit_list *get_merge_bases_many_0(struct commit *one,
207
+ int n,
208
+ struct commit **twos,
209
+ int cleanup)
210
+{
211
+ struct commit_list *list;
212
+ struct commit **rslt;
213
+ struct commit_list *result;
214
+ int cnt, i;
215
+
216
+ result = merge_bases_many(one, n, twos);
217
+ for (i = 0; i < n; i++) {
218
+ if (one == twos[i])
219
+ return result;
220
+ }
221
+ if (!result || !result->next) {
222
+ if (cleanup) {
223
+ clear_commit_marks(one, all_flags);
224
+ clear_commit_marks_many(n, twos, all_flags);
225
+ }
226
+ return result;
227
+ }
228
+
229
+ /* There are more than one */
230
+ cnt = commit_list_count(result);
231
+ rslt = xcalloc(cnt, sizeof(*rslt));
232
+ for (list = result, i = 0; list; list = list->next)
233
+ rslt[i++] = list->item;
234
+ free_commit_list(result);
235
+
236
+ clear_commit_marks(one, all_flags);
237
+ clear_commit_marks_many(n, twos, all_flags);
238
+
239
+ cnt = remove_redundant(rslt, cnt);
240
+ result = NULL;
241
+ for (i = 0; i < cnt; i++)
242
+ commit_list_insert_by_date(rslt[i], &result);
243
+ free(rslt);
244
+ return result;
245
+}
246
+
247
+struct commit_list *get_merge_bases_many(struct commit *one,
248
+ int n,
249
+ struct commit **twos)
250
+{
251
+ return get_merge_bases_many_0(one, n, twos, 1);
252
+}
253
+
254
+struct commit_list *get_merge_bases_many_dirty(struct commit *one,
255
+ int n,
256
+ struct commit **twos)
257
+{
258
+ return get_merge_bases_many_0(one, n, twos, 0);
259
+}
260
+
261
+struct commit_list *get_merge_bases(struct commit *one, struct commit *two)
262
+{
263
+ return get_merge_bases_many_0(one, 1, &two, 1);
264
+}
265
+
266
+/*
267
+ * Is "commit" a descendant of one of the elements on the "with_commit" list?
268
+ */
269
+int is_descendant_of(struct commit *commit, struct commit_list *with_commit)
270
+{
271
+ if (!with_commit)
272
+ return 1;
273
+ while (with_commit) {
274
+ struct commit *other;
275
+
276
+ other = with_commit->item;
277
+ with_commit = with_commit->next;
278
+ if (in_merge_bases(other, commit))
279
+ return 1;
280
+ }
281
+ return 0;
282
+}
283
+
284
+/*
285
+ * Is "commit" an ancestor of one of the "references"?
286
+ */
287
+int in_merge_bases_many(struct commit *commit, int nr_reference, struct commit **reference)
288
+{
289
+ struct commit_list *bases;
290
+ int ret = 0, i;
291
+ uint32_t min_generation = GENERATION_NUMBER_INFINITY;
292
+
293
+ if (parse_commit(commit))
294
+ return ret;
295
+ for (i = 0; i < nr_reference; i++) {
296
+ if (parse_commit(reference[i]))
297
+ return ret;
298
+ if (reference[i]->generation < min_generation)
299
+ min_generation = reference[i]->generation;
300
+ }
301
+
302
+ if (commit->generation > min_generation)
303
+ return ret;
304
+
305
+ bases = paint_down_to_common(commit, nr_reference, reference, commit->generation);
306
+ if (commit->object.flags & PARENT2)
307
+ ret = 1;
308
+ clear_commit_marks(commit, all_flags);
309
+ clear_commit_marks_many(nr_reference, reference, all_flags);
310
+ free_commit_list(bases);
311
+ return ret;
312
+}
313
+
314
+/*
315
+ * Is "commit" an ancestor of (i.e. reachable from) the "reference"?
316
+ */
317
+int in_merge_bases(struct commit *commit, struct commit *reference)
318
+{
319
+ return in_merge_bases_many(commit, 1, &reference);
320
+}
321
+
322
+struct commit_list *reduce_heads(struct commit_list *heads)
323
+{
324
+ struct commit_list *p;
325
+ struct commit_list *result = NULL, **tail = &result;
326
+ struct commit **array;
327
+ int num_head, i;
328
+
329
+ if (!heads)
330
+ return NULL;
331
+
332
+ /* Uniquify */
333
+ for (p = heads; p; p = p->next)
334
+ p->item->object.flags &= ~STALE;
335
+ for (p = heads, num_head = 0; p; p = p->next) {
336
+ if (p->item->object.flags & STALE)
337
+ continue;
338
+ p->item->object.flags |= STALE;
339
+ num_head++;
340
+ }
341
+ array = xcalloc(num_head, sizeof(*array));
342
+ for (p = heads, i = 0; p; p = p->next) {
343
+ if (p->item->object.flags & STALE) {
344
+ array[i++] = p->item;
345
+ p->item->object.flags &= ~STALE;
346
+ }
347
+ }
348
+ num_head = remove_redundant(array, num_head);
349
+ for (i = 0; i < num_head; i++)
350
+ tail = &commit_list_insert(array[i], tail)->next;
351
+ free(array);
352
+ return result;
353
+}
354
+
355
+void reduce_heads_replace(struct commit_list **heads)
356
+{
357
+ struct commit_list *result = reduce_heads(*heads);
358
+ free_commit_list(*heads);
359
+ *heads = result;
360
+}
commit-reach.h
new
+42
@@ -0,0 +1,42 @@
1
+#ifndef __COMMIT_REACH_H__
2
+#define __COMMIT_REACH_H__
3
+
4
+struct commit;
5
+struct commit_list;
6
+
7
+struct commit_list *get_merge_bases_many(struct commit *one,
8
+ int n,
9
+ struct commit **twos);
10
+struct commit_list *get_merge_bases_many_dirty(struct commit *one,
11
+ int n,
12
+ struct commit **twos);
13
+struct commit_list *get_merge_bases(struct commit *one, struct commit *two);
14
+struct commit_list *get_octopus_merge_bases(struct commit_list *in);
15
+
16
+/* To be used only when object flags after this call no longer matter */
17
+struct commit_list *get_merge_bases_many_dirty(struct commit *one, int n, struct commit **twos);
18
+
19
+int is_descendant_of(struct commit *commit, struct commit_list *with_commit);
20
+int in_merge_bases_many(struct commit *commit, int nr_reference, struct commit **reference);
21
+int in_merge_bases(struct commit *commit, struct commit *reference);
22
+
23
+
24
+/*
25
+ * Takes a list of commits and returns a new list where those
26
+ * have been removed that can be reached from other commits in
27
+ * the list. It is useful for, e.g., reducing the commits
28
+ * randomly thrown at the git-merge command and removing
29
+ * redundant commits that the user shouldn't have given to it.
30
+ *
31
+ * This function destroys the STALE bit of the commit objects'
32
+ * flags.
33
+ */
34
+struct commit_list *reduce_heads(struct commit_list *heads);
35
+
36
+/*
37
+ * Like `reduce_heads()`, except it replaces the list. Use this
38
+ * instead of `foo = reduce_heads(foo);` to avoid memory leaks.
39
+ */
40
+void reduce_heads_replace(struct commit_list **heads);
41
+
42
+#endif
commit.c
-358
@@ -843,364 +843,6 @@ void sort_in_topological_order(struct commit_list **list, enum rev_sort_order so
843
clear_author_date_slab(&author_date);
844
}
845
846
-/* merge-base stuff */
847
-
848
-/* Remember to update object flag allocation in object.h */
849
-#define PARENT1 (1u<<16)
850
-#define PARENT2 (1u<<17)
851
-#define STALE (1u<<18)
852
-#define RESULT (1u<<19)
853
-
854
-static const unsigned all_flags = (PARENT1 | PARENT2 | STALE | RESULT);
855
-
856
-static int queue_has_nonstale(struct prio_queue *queue)
857
-{
858
- int i;
859
- for (i = 0; i < queue->nr; i++) {
860
- struct commit *commit = queue->array[i].data;
861
- if (!(commit->object.flags & STALE))
862
- return 1;
863
- }
864
- return 0;
865
-}
866
-
867
-/* all input commits in one and twos[] must have been parsed! */
868
-static struct commit_list *paint_down_to_common(struct commit *one, int n,
869
- struct commit **twos,
870
- int min_generation)
871
-{
872
- struct prio_queue queue = { compare_commits_by_gen_then_commit_date };
873
- struct commit_list *result = NULL;
874
- int i;
875
- uint32_t last_gen = GENERATION_NUMBER_INFINITY;
876
-
877
- one->object.flags |= PARENT1;
878
- if (!n) {
879
- commit_list_append(one, &result);
880
- return result;
881
- }
882
- prio_queue_put(&queue, one);
883
-
884
- for (i = 0; i < n; i++) {
885
- twos[i]->object.flags |= PARENT2;
886
- prio_queue_put(&queue, twos[i]);
887
- }
888
-
889
- while (queue_has_nonstale(&queue)) {
890
- struct commit *commit = prio_queue_get(&queue);
891
- struct commit_list *parents;
892
- int flags;
893
-
894
- if (commit->generation > last_gen)
895
- BUG("bad generation skip %8x > %8x at %s",
896
- commit->generation, last_gen,
897
- oid_to_hex(&commit->object.oid));
898
- last_gen = commit->generation;
899
-
900
- if (commit->generation < min_generation)
901
- break;
902
-
903
- flags = commit->object.flags & (PARENT1 | PARENT2 | STALE);
904
- if (flags == (PARENT1 | PARENT2)) {
905
- if (!(commit->object.flags & RESULT)) {
906
- commit->object.flags |= RESULT;
907
- commit_list_insert_by_date(commit, &result);
908
- }
909
- /* Mark parents of a found merge stale */
910
- flags |= STALE;
911
- }
912
- parents = commit->parents;
913
- while (parents) {
914
- struct commit *p = parents->item;
915
- parents = parents->next;
916
- if ((p->object.flags & flags) == flags)
917
- continue;
918
- if (parse_commit(p))
919
- return NULL;
920
- p->object.flags |= flags;
921
- prio_queue_put(&queue, p);
922
- }
923
- }
924
-
925
- clear_prio_queue(&queue);
926
- return result;
927
-}
928
-
929
-static struct commit_list *merge_bases_many(struct commit *one, int n, struct commit **twos)
930
-{
931
- struct commit_list *list = NULL;
932
- struct commit_list *result = NULL;
933
- int i;
934
-
935
- for (i = 0; i < n; i++) {
936
- if (one == twos[i])
937
- /*
938
- * We do not mark this even with RESULT so we do not
939
- * have to clean it up.
940
- */
941
- return commit_list_insert(one, &result);
942
- }
943
-
944
- if (parse_commit(one))
945
- return NULL;
946
- for (i = 0; i < n; i++) {
947
- if (parse_commit(twos[i]))
948
- return NULL;
949
- }
950
-
951
- list = paint_down_to_common(one, n, twos, 0);
952
-
953
- while (list) {
954
- struct commit *commit = pop_commit(&list);
955
- if (!(commit->object.flags & STALE))
956
- commit_list_insert_by_date(commit, &result);
957
- }
958
- return result;
959
-}
960
-
961
-struct commit_list *get_octopus_merge_bases(struct commit_list *in)
962
-{
963
- struct commit_list *i, *j, *k, *ret = NULL;
964
-
965
- if (!in)
966
- return ret;
967
-
968
- commit_list_insert(in->item, &ret);
969
-
970
- for (i = in->next; i; i = i->next) {
971
- struct commit_list *new_commits = NULL, *end = NULL;
972
-
973
- for (j = ret; j; j = j->next) {
974
- struct commit_list *bases;
975
- bases = get_merge_bases(i->item, j->item);
976
- if (!new_commits)
977
- new_commits = bases;
978
- else
979
- end->next = bases;
980
- for (k = bases; k; k = k->next)
981
- end = k;
982
- }
983
- ret = new_commits;
984
- }
985
- return ret;
986
-}
987
-
988
-static int remove_redundant(struct commit **array, int cnt)
989
-{
990
- /*
991
- * Some commit in the array may be an ancestor of
992
- * another commit. Move such commit to the end of
993
- * the array, and return the number of commits that
994
- * are independent from each other.
995
- */
996
- struct commit **work;
997
- unsigned char *redundant;
998
- int *filled_index;
999
- int i, j, filled;
1000
-
1001
- work = xcalloc(cnt, sizeof(*work));
1002
- redundant = xcalloc(cnt, 1);
1003
- ALLOC_ARRAY(filled_index, cnt - 1);
1004
-
1005
- for (i = 0; i < cnt; i++)
1006
- parse_commit(array[i]);
1007
- for (i = 0; i < cnt; i++) {
1008
- struct commit_list *common;
1009
- uint32_t min_generation = array[i]->generation;
1010
-
1011
- if (redundant[i])
1012
- continue;
1013
- for (j = filled = 0; j < cnt; j++) {
1014
- if (i == j || redundant[j])
1015
- continue;
1016
- filled_index[filled] = j;
1017
- work[filled++] = array[j];
1018
-
1019
- if (array[j]->generation < min_generation)
1020
- min_generation = array[j]->generation;
1021
- }
1022
- common = paint_down_to_common(array[i], filled, work,
1023
- min_generation);
1024
- if (array[i]->object.flags & PARENT2)
1025
- redundant[i] = 1;
1026
- for (j = 0; j < filled; j++)
1027
- if (work[j]->object.flags & PARENT1)
1028
- redundant[filled_index[j]] = 1;
1029
- clear_commit_marks(array[i], all_flags);
1030
- clear_commit_marks_many(filled, work, all_flags);
1031
- free_commit_list(common);
1032
- }
1033
-
1034
- /* Now collect the result */
1035
- COPY_ARRAY(work, array, cnt);
1036
- for (i = filled = 0; i < cnt; i++)
1037
- if (!redundant[i])
1038
- array[filled++] = work[i];
1039
- for (j = filled, i = 0; i < cnt; i++)
1040
- if (redundant[i])
1041
- array[j++] = work[i];
1042
- free(work);
1043
- free(redundant);
1044
- free(filled_index);
1045
- return filled;
1046
-}
1047
-
1048
-static struct commit_list *get_merge_bases_many_0(struct commit *one,
1049
- int n,
1050
- struct commit **twos,
1051
- int cleanup)
1052
-{
1053
- struct commit_list *list;
1054
- struct commit **rslt;
1055
- struct commit_list *result;
1056
- int cnt, i;
1057
-
1058
- result = merge_bases_many(one, n, twos);
1059
- for (i = 0; i < n; i++) {
1060
- if (one == twos[i])
1061
- return result;
1062
- }
1063
- if (!result || !result->next) {
1064
- if (cleanup) {
1065
- clear_commit_marks(one, all_flags);
1066
- clear_commit_marks_many(n, twos, all_flags);
1067
- }
1068
- return result;
1069
- }
1070
-
1071
- /* There are more than one */
1072
- cnt = commit_list_count(result);
1073
- rslt = xcalloc(cnt, sizeof(*rslt));
1074
- for (list = result, i = 0; list; list = list->next)
1075
- rslt[i++] = list->item;
1076
- free_commit_list(result);
1077
-
1078
- clear_commit_marks(one, all_flags);
1079
- clear_commit_marks_many(n, twos, all_flags);
1080
-
1081
- cnt = remove_redundant(rslt, cnt);
1082
- result = NULL;
1083
- for (i = 0; i < cnt; i++)
1084
- commit_list_insert_by_date(rslt[i], &result);
1085
- free(rslt);
1086
- return result;
1087
-}
1088
-
1089
-struct commit_list *get_merge_bases_many(struct commit *one,
1090
- int n,
1091
- struct commit **twos)
1092
-{
1093
- return get_merge_bases_many_0(one, n, twos, 1);
1094
-}
1095
-
1096
-struct commit_list *get_merge_bases_many_dirty(struct commit *one,
1097
- int n,
1098
- struct commit **twos)
1099
-{
1100
- return get_merge_bases_many_0(one, n, twos, 0);
1101
-}
1102
-
1103
-struct commit_list *get_merge_bases(struct commit *one, struct commit *two)
1104
-{
1105
- return get_merge_bases_many_0(one, 1, &two, 1);
1106
-}
1107
-
1108
-/*
1109
- * Is "commit" a descendant of one of the elements on the "with_commit" list?
1110
- */
1111
-int is_descendant_of(struct commit *commit, struct commit_list *with_commit)
1112
-{
1113
- if (!with_commit)
1114
- return 1;
1115
- while (with_commit) {
1116
- struct commit *other;
1117
-
1118
- other = with_commit->item;
1119
- with_commit = with_commit->next;
1120
- if (in_merge_bases(other, commit))
1121
- return 1;
1122
- }
1123
- return 0;
1124
-}
1125
-
1126
-/*
1127
- * Is "commit" an ancestor of one of the "references"?
1128
- */
1129
-int in_merge_bases_many(struct commit *commit, int nr_reference, struct commit **reference)
1130
-{
1131
- struct commit_list *bases;
1132
- int ret = 0, i;
1133
- uint32_t min_generation = GENERATION_NUMBER_INFINITY;
1134
-
1135
- if (parse_commit(commit))
1136
- return ret;
1137
- for (i = 0; i < nr_reference; i++) {
1138
- if (parse_commit(reference[i]))
1139
- return ret;
1140
- if (reference[i]->generation < min_generation)
1141
- min_generation = reference[i]->generation;
1142
- }
1143
-
1144
- if (commit->generation > min_generation)
1145
- return ret;
1146
-
1147
- bases = paint_down_to_common(commit, nr_reference, reference, commit->generation);
1148
- if (commit->object.flags & PARENT2)
1149
- ret = 1;
1150
- clear_commit_marks(commit, all_flags);
1151
- clear_commit_marks_many(nr_reference, reference, all_flags);
1152
- free_commit_list(bases);
1153
- return ret;
1154
-}
1155
-
1156
-/*
1157
- * Is "commit" an ancestor of (i.e. reachable from) the "reference"?
1158
- */
1159
-int in_merge_bases(struct commit *commit, struct commit *reference)
1160
-{
1161
- return in_merge_bases_many(commit, 1, &reference);
1162
-}
1163
-
1164
-struct commit_list *reduce_heads(struct commit_list *heads)
1165
-{
1166
- struct commit_list *p;
1167
- struct commit_list *result = NULL, **tail = &result;
1168
- struct commit **array;
1169
- int num_head, i;
1170
-
1171
- if (!heads)
1172
- return NULL;
1173
-
1174
- /* Uniquify */
1175
- for (p = heads; p; p = p->next)
1176
- p->item->object.flags &= ~STALE;
1177
- for (p = heads, num_head = 0; p; p = p->next) {
1178
- if (p->item->object.flags & STALE)
1179
- continue;
1180
- p->item->object.flags |= STALE;
1181
- num_head++;
1182
- }
1183
- array = xcalloc(num_head, sizeof(*array));
1184
- for (p = heads, i = 0; p; p = p->next) {
1185
- if (p->item->object.flags & STALE) {
1186
- array[i++] = p->item;
1187
- p->item->object.flags &= ~STALE;
1188
- }
1189
- }
1190
- num_head = remove_redundant(array, num_head);
1191
- for (i = 0; i < num_head; i++)
1192
- tail = &commit_list_insert(array[i], tail)->next;
1193
- free(array);
1194
- return result;
1195
-}
1196
-
1197
-void reduce_heads_replace(struct commit_list **heads)
1198
-{
1199
- struct commit_list *result = reduce_heads(*heads);
1200
- free_commit_list(*heads);
1201
- *heads = result;
1202
-}
1203
-
846
static const char gpg_sig_header[] = "gpgsig";
847
static const int gpg_sig_header_len = sizeof(gpg_sig_header) - 1;
848
object.h
+1
-1
@@ -65,7 +65,7 @@ struct object_array {
65
* bisect.c: 16
66
* bundle.c: 16
67
* http-push.c: 16-----19
68
- * commit.c: 16-----19
68
+ * commit-reach.c: 16-----19
69
* sha1-name.c: 20
70
* list-objects-filter.c: 21
71
* builtin/fsck.c: 0--3