Merge branch 'ds/ahead-behind'
[git.git] / shallow.c
blob1cbb05ba0e45637f1b0655b9b1dbd51ac4da8117
1 #include "git-compat-util.h"
2 #include "alloc.h"
3 #include "hex.h"
4 #include "repository.h"
5 #include "tempfile.h"
6 #include "lockfile.h"
7 #include "object-store.h"
8 #include "commit.h"
9 #include "tag.h"
10 #include "pkt-line.h"
11 #include "remote.h"
12 #include "refs.h"
13 #include "oid-array.h"
14 #include "diff.h"
15 #include "revision.h"
16 #include "commit-slab.h"
17 #include "list-objects.h"
18 #include "commit-reach.h"
19 #include "shallow.h"
21 void set_alternate_shallow_file(struct repository *r, const char *path, int override)
23 if (r->parsed_objects->is_shallow != -1)
24 BUG("is_repository_shallow must not be called before set_alternate_shallow_file");
25 if (r->parsed_objects->alternate_shallow_file && !override)
26 return;
27 free(r->parsed_objects->alternate_shallow_file);
28 r->parsed_objects->alternate_shallow_file = xstrdup_or_null(path);
31 int register_shallow(struct repository *r, const struct object_id *oid)
33 struct commit_graft *graft =
34 xmalloc(sizeof(struct commit_graft));
35 struct commit *commit = lookup_commit(the_repository, oid);
37 oidcpy(&graft->oid, oid);
38 graft->nr_parent = -1;
39 if (commit && commit->object.parsed)
40 commit->parents = NULL;
41 return register_commit_graft(r, graft, 0);
44 int unregister_shallow(const struct object_id *oid)
46 int pos = commit_graft_pos(the_repository, oid);
47 if (pos < 0)
48 return -1;
49 if (pos + 1 < the_repository->parsed_objects->grafts_nr)
50 MOVE_ARRAY(the_repository->parsed_objects->grafts + pos,
51 the_repository->parsed_objects->grafts + pos + 1,
52 the_repository->parsed_objects->grafts_nr - pos - 1);
53 the_repository->parsed_objects->grafts_nr--;
54 return 0;
57 int is_repository_shallow(struct repository *r)
59 FILE *fp;
60 char buf[1024];
61 const char *path = r->parsed_objects->alternate_shallow_file;
63 if (r->parsed_objects->is_shallow >= 0)
64 return r->parsed_objects->is_shallow;
66 if (!path)
67 path = git_path_shallow(r);
69 * fetch-pack sets '--shallow-file ""' as an indicator that no
70 * shallow file should be used. We could just open it and it
71 * will likely fail. But let's do an explicit check instead.
73 if (!*path || (fp = fopen(path, "r")) == NULL) {
74 stat_validity_clear(r->parsed_objects->shallow_stat);
75 r->parsed_objects->is_shallow = 0;
76 return r->parsed_objects->is_shallow;
78 stat_validity_update(r->parsed_objects->shallow_stat, fileno(fp));
79 r->parsed_objects->is_shallow = 1;
81 while (fgets(buf, sizeof(buf), fp)) {
82 struct object_id oid;
83 if (get_oid_hex(buf, &oid))
84 die("bad shallow line: %s", buf);
85 register_shallow(r, &oid);
87 fclose(fp);
88 return r->parsed_objects->is_shallow;
91 static void reset_repository_shallow(struct repository *r)
93 r->parsed_objects->is_shallow = -1;
94 stat_validity_clear(r->parsed_objects->shallow_stat);
95 reset_commit_grafts(r);
98 int commit_shallow_file(struct repository *r, struct shallow_lock *lk)
100 int res = commit_lock_file(&lk->lock);
101 reset_repository_shallow(r);
104 * Update in-memory data structures with the new shallow information,
105 * including unparsing all commits that now have grafts.
107 is_repository_shallow(r);
109 return res;
112 void rollback_shallow_file(struct repository *r, struct shallow_lock *lk)
114 rollback_lock_file(&lk->lock);
115 reset_repository_shallow(r);
119 * TODO: use "int" elemtype instead of "int *" when/if commit-slab
120 * supports a "valid" flag.
122 define_commit_slab(commit_depth, int *);
123 static void free_depth_in_slab(int **ptr)
125 FREE_AND_NULL(*ptr);
127 struct commit_list *get_shallow_commits(struct object_array *heads, int depth,
128 int shallow_flag, int not_shallow_flag)
130 int i = 0, cur_depth = 0;
131 struct commit_list *result = NULL;
132 struct object_array stack = OBJECT_ARRAY_INIT;
133 struct commit *commit = NULL;
134 struct commit_graft *graft;
135 struct commit_depth depths;
137 init_commit_depth(&depths);
138 while (commit || i < heads->nr || stack.nr) {
139 struct commit_list *p;
140 if (!commit) {
141 if (i < heads->nr) {
142 int **depth_slot;
143 commit = (struct commit *)
144 deref_tag(the_repository,
145 heads->objects[i++].item,
146 NULL, 0);
147 if (!commit || commit->object.type != OBJ_COMMIT) {
148 commit = NULL;
149 continue;
151 depth_slot = commit_depth_at(&depths, commit);
152 if (!*depth_slot)
153 *depth_slot = xmalloc(sizeof(int));
154 **depth_slot = 0;
155 cur_depth = 0;
156 } else {
157 commit = (struct commit *)
158 object_array_pop(&stack);
159 cur_depth = **commit_depth_at(&depths, commit);
162 parse_commit_or_die(commit);
163 cur_depth++;
164 if ((depth != INFINITE_DEPTH && cur_depth >= depth) ||
165 (is_repository_shallow(the_repository) && !commit->parents &&
166 (graft = lookup_commit_graft(the_repository, &commit->object.oid)) != NULL &&
167 graft->nr_parent < 0)) {
168 commit_list_insert(commit, &result);
169 commit->object.flags |= shallow_flag;
170 commit = NULL;
171 continue;
173 commit->object.flags |= not_shallow_flag;
174 for (p = commit->parents, commit = NULL; p; p = p->next) {
175 int **depth_slot = commit_depth_at(&depths, p->item);
176 if (!*depth_slot) {
177 *depth_slot = xmalloc(sizeof(int));
178 **depth_slot = cur_depth;
179 } else {
180 if (cur_depth >= **depth_slot)
181 continue;
182 **depth_slot = cur_depth;
184 if (p->next)
185 add_object_array(&p->item->object,
186 NULL, &stack);
187 else {
188 commit = p->item;
189 cur_depth = **commit_depth_at(&depths, commit);
193 deep_clear_commit_depth(&depths, free_depth_in_slab);
195 return result;
198 static void show_commit(struct commit *commit, void *data)
200 commit_list_insert(commit, data);
204 * Given rev-list arguments, run rev-list. All reachable commits
205 * except border ones are marked with not_shallow_flag. Border commits
206 * are marked with shallow_flag. The list of border/shallow commits
207 * are also returned.
209 struct commit_list *get_shallow_commits_by_rev_list(int ac, const char **av,
210 int shallow_flag,
211 int not_shallow_flag)
213 struct commit_list *result = NULL, *p;
214 struct commit_list *not_shallow_list = NULL;
215 struct rev_info revs;
216 int both_flags = shallow_flag | not_shallow_flag;
219 * SHALLOW (excluded) and NOT_SHALLOW (included) should not be
220 * set at this point. But better be safe than sorry.
222 clear_object_flags(both_flags);
224 is_repository_shallow(the_repository); /* make sure shallows are read */
226 repo_init_revisions(the_repository, &revs, NULL);
227 save_commit_buffer = 0;
228 setup_revisions(ac, av, &revs, NULL);
230 if (prepare_revision_walk(&revs))
231 die("revision walk setup failed");
232 traverse_commit_list(&revs, show_commit, NULL, &not_shallow_list);
234 if (!not_shallow_list)
235 die("no commits selected for shallow requests");
237 /* Mark all reachable commits as NOT_SHALLOW */
238 for (p = not_shallow_list; p; p = p->next)
239 p->item->object.flags |= not_shallow_flag;
242 * mark border commits SHALLOW + NOT_SHALLOW.
243 * We cannot clear NOT_SHALLOW right now. Imagine border
244 * commit A is processed first, then commit B, whose parent is
245 * A, later. If NOT_SHALLOW on A is cleared at step 1, B
246 * itself is considered border at step 2, which is incorrect.
248 for (p = not_shallow_list; p; p = p->next) {
249 struct commit *c = p->item;
250 struct commit_list *parent;
252 if (parse_commit(c))
253 die("unable to parse commit %s",
254 oid_to_hex(&c->object.oid));
256 for (parent = c->parents; parent; parent = parent->next)
257 if (!(parent->item->object.flags & not_shallow_flag)) {
258 c->object.flags |= shallow_flag;
259 commit_list_insert(c, &result);
260 break;
263 free_commit_list(not_shallow_list);
266 * Now we can clean up NOT_SHALLOW on border commits. Having
267 * both flags set can confuse the caller.
269 for (p = result; p; p = p->next) {
270 struct object *o = &p->item->object;
271 if ((o->flags & both_flags) == both_flags)
272 o->flags &= ~not_shallow_flag;
274 release_revisions(&revs);
275 return result;
278 static void check_shallow_file_for_update(struct repository *r)
280 if (r->parsed_objects->is_shallow == -1)
281 BUG("shallow must be initialized by now");
283 if (!stat_validity_check(r->parsed_objects->shallow_stat,
284 git_path_shallow(r)))
285 die("shallow file has changed since we read it");
288 #define SEEN_ONLY 1
289 #define VERBOSE 2
290 #define QUICK 4
292 struct write_shallow_data {
293 struct strbuf *out;
294 int use_pack_protocol;
295 int count;
296 unsigned flags;
299 static int write_one_shallow(const struct commit_graft *graft, void *cb_data)
301 struct write_shallow_data *data = cb_data;
302 const char *hex = oid_to_hex(&graft->oid);
303 if (graft->nr_parent != -1)
304 return 0;
305 if (data->flags & QUICK) {
306 if (!has_object_file(&graft->oid))
307 return 0;
308 } else if (data->flags & SEEN_ONLY) {
309 struct commit *c = lookup_commit(the_repository, &graft->oid);
310 if (!c || !(c->object.flags & SEEN)) {
311 if (data->flags & VERBOSE)
312 printf("Removing %s from .git/shallow\n",
313 oid_to_hex(&c->object.oid));
314 return 0;
317 data->count++;
318 if (data->use_pack_protocol)
319 packet_buf_write(data->out, "shallow %s", hex);
320 else {
321 strbuf_addstr(data->out, hex);
322 strbuf_addch(data->out, '\n');
324 return 0;
327 static int write_shallow_commits_1(struct strbuf *out, int use_pack_protocol,
328 const struct oid_array *extra,
329 unsigned flags)
331 struct write_shallow_data data;
332 int i;
333 data.out = out;
334 data.use_pack_protocol = use_pack_protocol;
335 data.count = 0;
336 data.flags = flags;
337 for_each_commit_graft(write_one_shallow, &data);
338 if (!extra)
339 return data.count;
340 for (i = 0; i < extra->nr; i++) {
341 strbuf_addstr(out, oid_to_hex(extra->oid + i));
342 strbuf_addch(out, '\n');
343 data.count++;
345 return data.count;
348 int write_shallow_commits(struct strbuf *out, int use_pack_protocol,
349 const struct oid_array *extra)
351 return write_shallow_commits_1(out, use_pack_protocol, extra, 0);
354 const char *setup_temporary_shallow(const struct oid_array *extra)
356 struct tempfile *temp;
357 struct strbuf sb = STRBUF_INIT;
359 if (write_shallow_commits(&sb, 0, extra)) {
360 temp = xmks_tempfile(git_path("shallow_XXXXXX"));
362 if (write_in_full(temp->fd, sb.buf, sb.len) < 0 ||
363 close_tempfile_gently(temp) < 0)
364 die_errno("failed to write to %s",
365 get_tempfile_path(temp));
366 strbuf_release(&sb);
367 return get_tempfile_path(temp);
370 * is_repository_shallow() sees empty string as "no shallow
371 * file".
373 return "";
376 void setup_alternate_shallow(struct shallow_lock *shallow_lock,
377 const char **alternate_shallow_file,
378 const struct oid_array *extra)
380 struct strbuf sb = STRBUF_INIT;
381 int fd;
383 fd = hold_lock_file_for_update(&shallow_lock->lock,
384 git_path_shallow(the_repository),
385 LOCK_DIE_ON_ERROR);
386 check_shallow_file_for_update(the_repository);
387 if (write_shallow_commits(&sb, 0, extra)) {
388 if (write_in_full(fd, sb.buf, sb.len) < 0)
389 die_errno("failed to write to %s",
390 get_lock_file_path(&shallow_lock->lock));
391 *alternate_shallow_file = get_lock_file_path(&shallow_lock->lock);
392 } else
394 * is_repository_shallow() sees empty string as "no
395 * shallow file".
397 *alternate_shallow_file = "";
398 strbuf_release(&sb);
401 static int advertise_shallow_grafts_cb(const struct commit_graft *graft, void *cb)
403 int fd = *(int *)cb;
404 if (graft->nr_parent == -1)
405 packet_write_fmt(fd, "shallow %s\n", oid_to_hex(&graft->oid));
406 return 0;
409 void advertise_shallow_grafts(int fd)
411 if (!is_repository_shallow(the_repository))
412 return;
413 for_each_commit_graft(advertise_shallow_grafts_cb, &fd);
417 * mark_reachable_objects() should have been run prior to this and all
418 * reachable commits marked as "SEEN", except when quick_prune is non-zero,
419 * in which case lines are excised from the shallow file if they refer to
420 * commits that do not exist (any longer).
422 void prune_shallow(unsigned options)
424 struct shallow_lock shallow_lock = SHALLOW_LOCK_INIT;
425 struct strbuf sb = STRBUF_INIT;
426 unsigned flags = SEEN_ONLY;
427 int fd;
429 if (options & PRUNE_QUICK)
430 flags |= QUICK;
432 if (options & PRUNE_SHOW_ONLY) {
433 flags |= VERBOSE;
434 write_shallow_commits_1(&sb, 0, NULL, flags);
435 strbuf_release(&sb);
436 return;
438 fd = hold_lock_file_for_update(&shallow_lock.lock,
439 git_path_shallow(the_repository),
440 LOCK_DIE_ON_ERROR);
441 check_shallow_file_for_update(the_repository);
442 if (write_shallow_commits_1(&sb, 0, NULL, flags)) {
443 if (write_in_full(fd, sb.buf, sb.len) < 0)
444 die_errno("failed to write to %s",
445 get_lock_file_path(&shallow_lock.lock));
446 commit_shallow_file(the_repository, &shallow_lock);
447 } else {
448 unlink(git_path_shallow(the_repository));
449 rollback_shallow_file(the_repository, &shallow_lock);
451 strbuf_release(&sb);
454 struct trace_key trace_shallow = TRACE_KEY_INIT(SHALLOW);
457 * Step 1, split sender shallow commits into "ours" and "theirs"
458 * Step 2, clean "ours" based on .git/shallow
460 void prepare_shallow_info(struct shallow_info *info, struct oid_array *sa)
462 int i;
463 trace_printf_key(&trace_shallow, "shallow: prepare_shallow_info\n");
464 memset(info, 0, sizeof(*info));
465 info->shallow = sa;
466 if (!sa)
467 return;
468 ALLOC_ARRAY(info->ours, sa->nr);
469 ALLOC_ARRAY(info->theirs, sa->nr);
470 for (i = 0; i < sa->nr; i++) {
471 if (has_object_file(sa->oid + i)) {
472 struct commit_graft *graft;
473 graft = lookup_commit_graft(the_repository,
474 &sa->oid[i]);
475 if (graft && graft->nr_parent < 0)
476 continue;
477 info->ours[info->nr_ours++] = i;
478 } else
479 info->theirs[info->nr_theirs++] = i;
483 void clear_shallow_info(struct shallow_info *info)
485 free(info->ours);
486 free(info->theirs);
489 /* Step 4, remove non-existent ones in "theirs" after getting the pack */
491 void remove_nonexistent_theirs_shallow(struct shallow_info *info)
493 struct object_id *oid = info->shallow->oid;
494 int i, dst;
495 trace_printf_key(&trace_shallow, "shallow: remove_nonexistent_theirs_shallow\n");
496 for (i = dst = 0; i < info->nr_theirs; i++) {
497 if (i != dst)
498 info->theirs[dst] = info->theirs[i];
499 if (has_object_file(oid + info->theirs[i]))
500 dst++;
502 info->nr_theirs = dst;
505 define_commit_slab(ref_bitmap, uint32_t *);
507 #define POOL_SIZE (512 * 1024)
509 struct paint_info {
510 struct ref_bitmap ref_bitmap;
511 unsigned nr_bits;
512 char **pools;
513 char *free, *end;
514 unsigned pool_count;
517 static uint32_t *paint_alloc(struct paint_info *info)
519 unsigned nr = DIV_ROUND_UP(info->nr_bits, 32);
520 unsigned size = nr * sizeof(uint32_t);
521 void *p;
522 if (!info->pool_count || size > info->end - info->free) {
523 if (size > POOL_SIZE)
524 BUG("pool size too small for %d in paint_alloc()",
525 size);
526 info->pool_count++;
527 REALLOC_ARRAY(info->pools, info->pool_count);
528 info->free = xmalloc(POOL_SIZE);
529 info->pools[info->pool_count - 1] = info->free;
530 info->end = info->free + POOL_SIZE;
532 p = info->free;
533 info->free += size;
534 return p;
538 * Given a commit SHA-1, walk down to parents until either SEEN,
539 * UNINTERESTING or BOTTOM is hit. Set the id-th bit in ref_bitmap for
540 * all walked commits.
542 static void paint_down(struct paint_info *info, const struct object_id *oid,
543 unsigned int id)
545 unsigned int i, nr;
546 struct commit_list *head = NULL;
547 int bitmap_nr = DIV_ROUND_UP(info->nr_bits, 32);
548 size_t bitmap_size = st_mult(sizeof(uint32_t), bitmap_nr);
549 struct commit *c = lookup_commit_reference_gently(the_repository, oid,
551 uint32_t *tmp; /* to be freed before return */
552 uint32_t *bitmap;
554 if (!c)
555 return;
557 tmp = xmalloc(bitmap_size);
558 bitmap = paint_alloc(info);
559 memset(bitmap, 0, bitmap_size);
560 bitmap[id / 32] |= (1U << (id % 32));
561 commit_list_insert(c, &head);
562 while (head) {
563 struct commit_list *p;
564 struct commit *c = pop_commit(&head);
565 uint32_t **refs = ref_bitmap_at(&info->ref_bitmap, c);
567 /* XXX check "UNINTERESTING" from pack bitmaps if available */
568 if (c->object.flags & (SEEN | UNINTERESTING))
569 continue;
570 else
571 c->object.flags |= SEEN;
573 if (!*refs)
574 *refs = bitmap;
575 else {
576 memcpy(tmp, *refs, bitmap_size);
577 for (i = 0; i < bitmap_nr; i++)
578 tmp[i] |= bitmap[i];
579 if (memcmp(tmp, *refs, bitmap_size)) {
580 *refs = paint_alloc(info);
581 memcpy(*refs, tmp, bitmap_size);
585 if (c->object.flags & BOTTOM)
586 continue;
588 if (parse_commit(c))
589 die("unable to parse commit %s",
590 oid_to_hex(&c->object.oid));
592 for (p = c->parents; p; p = p->next) {
593 if (p->item->object.flags & SEEN)
594 continue;
595 commit_list_insert(p->item, &head);
599 nr = get_max_object_index();
600 for (i = 0; i < nr; i++) {
601 struct object *o = get_indexed_object(i);
602 if (o && o->type == OBJ_COMMIT)
603 o->flags &= ~SEEN;
606 free(tmp);
609 static int mark_uninteresting(const char *refname UNUSED,
610 const struct object_id *oid,
611 int flags UNUSED,
612 void *cb_data UNUSED)
614 struct commit *commit = lookup_commit_reference_gently(the_repository,
615 oid, 1);
616 if (!commit)
617 return 0;
618 commit->object.flags |= UNINTERESTING;
619 mark_parents_uninteresting(NULL, commit);
620 return 0;
623 static void post_assign_shallow(struct shallow_info *info,
624 struct ref_bitmap *ref_bitmap,
625 int *ref_status);
627 * Step 6(+7), associate shallow commits with new refs
629 * info->ref must be initialized before calling this function.
631 * If used is not NULL, it's an array of info->shallow->nr
632 * bitmaps. The n-th bit set in the m-th bitmap if ref[n] needs the
633 * m-th shallow commit from info->shallow.
635 * If used is NULL, "ours" and "theirs" are updated. And if ref_status
636 * is not NULL it's an array of ref->nr ints. ref_status[i] is true if
637 * the ref needs some shallow commits from either info->ours or
638 * info->theirs.
640 void assign_shallow_commits_to_refs(struct shallow_info *info,
641 uint32_t **used, int *ref_status)
643 struct object_id *oid = info->shallow->oid;
644 struct oid_array *ref = info->ref;
645 unsigned int i, nr;
646 int *shallow, nr_shallow = 0;
647 struct paint_info pi;
649 trace_printf_key(&trace_shallow, "shallow: assign_shallow_commits_to_refs\n");
650 ALLOC_ARRAY(shallow, info->nr_ours + info->nr_theirs);
651 for (i = 0; i < info->nr_ours; i++)
652 shallow[nr_shallow++] = info->ours[i];
653 for (i = 0; i < info->nr_theirs; i++)
654 shallow[nr_shallow++] = info->theirs[i];
657 * Prepare the commit graph to track what refs can reach what
658 * (new) shallow commits.
660 nr = get_max_object_index();
661 for (i = 0; i < nr; i++) {
662 struct object *o = get_indexed_object(i);
663 if (!o || o->type != OBJ_COMMIT)
664 continue;
666 o->flags &= ~(UNINTERESTING | BOTTOM | SEEN);
669 memset(&pi, 0, sizeof(pi));
670 init_ref_bitmap(&pi.ref_bitmap);
671 pi.nr_bits = ref->nr;
674 * "--not --all" to cut short the traversal if new refs
675 * connect to old refs. If not (e.g. force ref updates) it'll
676 * have to go down to the current shallow commits.
678 head_ref(mark_uninteresting, NULL);
679 for_each_ref(mark_uninteresting, NULL);
681 /* Mark potential bottoms so we won't go out of bound */
682 for (i = 0; i < nr_shallow; i++) {
683 struct commit *c = lookup_commit(the_repository,
684 &oid[shallow[i]]);
685 c->object.flags |= BOTTOM;
688 for (i = 0; i < ref->nr; i++)
689 paint_down(&pi, ref->oid + i, i);
691 if (used) {
692 int bitmap_size = DIV_ROUND_UP(pi.nr_bits, 32) * sizeof(uint32_t);
693 memset(used, 0, sizeof(*used) * info->shallow->nr);
694 for (i = 0; i < nr_shallow; i++) {
695 const struct commit *c = lookup_commit(the_repository,
696 &oid[shallow[i]]);
697 uint32_t **map = ref_bitmap_at(&pi.ref_bitmap, c);
698 if (*map)
699 used[shallow[i]] = xmemdupz(*map, bitmap_size);
702 * unreachable shallow commits are not removed from
703 * "ours" and "theirs". The user is supposed to run
704 * step 7 on every ref separately and not trust "ours"
705 * and "theirs" any more.
707 } else
708 post_assign_shallow(info, &pi.ref_bitmap, ref_status);
710 clear_ref_bitmap(&pi.ref_bitmap);
711 for (i = 0; i < pi.pool_count; i++)
712 free(pi.pools[i]);
713 free(pi.pools);
714 free(shallow);
717 struct commit_array {
718 struct commit **commits;
719 int nr, alloc;
722 static int add_ref(const char *refname UNUSED,
723 const struct object_id *oid,
724 int flags UNUSED,
725 void *cb_data)
727 struct commit_array *ca = cb_data;
728 ALLOC_GROW(ca->commits, ca->nr + 1, ca->alloc);
729 ca->commits[ca->nr] = lookup_commit_reference_gently(the_repository,
730 oid, 1);
731 if (ca->commits[ca->nr])
732 ca->nr++;
733 return 0;
736 static void update_refstatus(int *ref_status, int nr, uint32_t *bitmap)
738 unsigned int i;
739 if (!ref_status)
740 return;
741 for (i = 0; i < nr; i++)
742 if (bitmap[i / 32] & (1U << (i % 32)))
743 ref_status[i]++;
747 * Step 7, reachability test on "ours" at commit level
749 static void post_assign_shallow(struct shallow_info *info,
750 struct ref_bitmap *ref_bitmap,
751 int *ref_status)
753 struct object_id *oid = info->shallow->oid;
754 struct commit *c;
755 uint32_t **bitmap;
756 int dst, i, j;
757 int bitmap_nr = DIV_ROUND_UP(info->ref->nr, 32);
758 struct commit_array ca;
760 trace_printf_key(&trace_shallow, "shallow: post_assign_shallow\n");
761 if (ref_status)
762 memset(ref_status, 0, sizeof(*ref_status) * info->ref->nr);
764 /* Remove unreachable shallow commits from "theirs" */
765 for (i = dst = 0; i < info->nr_theirs; i++) {
766 if (i != dst)
767 info->theirs[dst] = info->theirs[i];
768 c = lookup_commit(the_repository, &oid[info->theirs[i]]);
769 bitmap = ref_bitmap_at(ref_bitmap, c);
770 if (!*bitmap)
771 continue;
772 for (j = 0; j < bitmap_nr; j++)
773 if (bitmap[0][j]) {
774 update_refstatus(ref_status, info->ref->nr, *bitmap);
775 dst++;
776 break;
779 info->nr_theirs = dst;
781 memset(&ca, 0, sizeof(ca));
782 head_ref(add_ref, &ca);
783 for_each_ref(add_ref, &ca);
785 /* Remove unreachable shallow commits from "ours" */
786 for (i = dst = 0; i < info->nr_ours; i++) {
787 if (i != dst)
788 info->ours[dst] = info->ours[i];
789 c = lookup_commit(the_repository, &oid[info->ours[i]]);
790 bitmap = ref_bitmap_at(ref_bitmap, c);
791 if (!*bitmap)
792 continue;
793 for (j = 0; j < bitmap_nr; j++)
794 if (bitmap[0][j] &&
795 /* Step 7, reachability test at commit level */
796 !in_merge_bases_many(c, ca.nr, ca.commits)) {
797 update_refstatus(ref_status, info->ref->nr, *bitmap);
798 dst++;
799 break;
802 info->nr_ours = dst;
804 free(ca.commits);
807 /* (Delayed) step 7, reachability test at commit level */
808 int delayed_reachability_test(struct shallow_info *si, int c)
810 if (si->need_reachability_test[c]) {
811 struct commit *commit = lookup_commit(the_repository,
812 &si->shallow->oid[c]);
814 if (!si->commits) {
815 struct commit_array ca;
817 memset(&ca, 0, sizeof(ca));
818 head_ref(add_ref, &ca);
819 for_each_ref(add_ref, &ca);
820 si->commits = ca.commits;
821 si->nr_commits = ca.nr;
824 si->reachable[c] = in_merge_bases_many(commit,
825 si->nr_commits,
826 si->commits);
827 si->need_reachability_test[c] = 0;
829 return si->reachable[c];