shallow.con commit git-commit.txt: better description what it does (5cfd4a9)
   1#include "cache.h"
   2#include "repository.h"
   3#include "tempfile.h"
   4#include "lockfile.h"
   5#include "object-store.h"
   6#include "commit.h"
   7#include "tag.h"
   8#include "pkt-line.h"
   9#include "remote.h"
  10#include "refs.h"
  11#include "sha1-array.h"
  12#include "diff.h"
  13#include "revision.h"
  14#include "commit-slab.h"
  15#include "revision.h"
  16#include "list-objects.h"
  17#include "commit-slab.h"
  18#include "repository.h"
  19#include "commit-reach.h"
  20
  21void set_alternate_shallow_file(struct repository *r, const char *path, int override)
  22{
  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);
  29}
  30
  31int register_shallow(struct repository *r, const struct object_id *oid)
  32{
  33        struct commit_graft *graft =
  34                xmalloc(sizeof(struct commit_graft));
  35        struct commit *commit = lookup_commit(the_repository, oid);
  36
  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);
  42}
  43
  44int is_repository_shallow(struct repository *r)
  45{
  46        FILE *fp;
  47        char buf[1024];
  48        const char *path = r->parsed_objects->alternate_shallow_file;
  49
  50        if (r->parsed_objects->is_shallow >= 0)
  51                return r->parsed_objects->is_shallow;
  52
  53        if (!path)
  54                path = git_path_shallow(r);
  55        /*
  56         * fetch-pack sets '--shallow-file ""' as an indicator that no
  57         * shallow file should be used. We could just open it and it
  58         * will likely fail. But let's do an explicit check instead.
  59         */
  60        if (!*path || (fp = fopen(path, "r")) == NULL) {
  61                stat_validity_clear(r->parsed_objects->shallow_stat);
  62                r->parsed_objects->is_shallow = 0;
  63                return r->parsed_objects->is_shallow;
  64        }
  65        stat_validity_update(r->parsed_objects->shallow_stat, fileno(fp));
  66        r->parsed_objects->is_shallow = 1;
  67
  68        while (fgets(buf, sizeof(buf), fp)) {
  69                struct object_id oid;
  70                if (get_oid_hex(buf, &oid))
  71                        die("bad shallow line: %s", buf);
  72                register_shallow(r, &oid);
  73        }
  74        fclose(fp);
  75        return r->parsed_objects->is_shallow;
  76}
  77
  78/*
  79 * TODO: use "int" elemtype instead of "int *" when/if commit-slab
  80 * supports a "valid" flag.
  81 */
  82define_commit_slab(commit_depth, int *);
  83struct commit_list *get_shallow_commits(struct object_array *heads, int depth,
  84                int shallow_flag, int not_shallow_flag)
  85{
  86        int i = 0, cur_depth = 0;
  87        struct commit_list *result = NULL;
  88        struct object_array stack = OBJECT_ARRAY_INIT;
  89        struct commit *commit = NULL;
  90        struct commit_graft *graft;
  91        struct commit_depth depths;
  92
  93        init_commit_depth(&depths);
  94        while (commit || i < heads->nr || stack.nr) {
  95                struct commit_list *p;
  96                if (!commit) {
  97                        if (i < heads->nr) {
  98                                int **depth_slot;
  99                                commit = (struct commit *)
 100                                        deref_tag(the_repository,
 101                                                  heads->objects[i++].item,
 102                                                  NULL, 0);
 103                                if (!commit || commit->object.type != OBJ_COMMIT) {
 104                                        commit = NULL;
 105                                        continue;
 106                                }
 107                                depth_slot = commit_depth_at(&depths, commit);
 108                                if (!*depth_slot)
 109                                        *depth_slot = xmalloc(sizeof(int));
 110                                **depth_slot = 0;
 111                                cur_depth = 0;
 112                        } else {
 113                                commit = (struct commit *)
 114                                        object_array_pop(&stack);
 115                                cur_depth = **commit_depth_at(&depths, commit);
 116                        }
 117                }
 118                parse_commit_or_die(commit);
 119                cur_depth++;
 120                if ((depth != INFINITE_DEPTH && cur_depth >= depth) ||
 121                    (is_repository_shallow(the_repository) && !commit->parents &&
 122                     (graft = lookup_commit_graft(the_repository, &commit->object.oid)) != NULL &&
 123                     graft->nr_parent < 0)) {
 124                        commit_list_insert(commit, &result);
 125                        commit->object.flags |= shallow_flag;
 126                        commit = NULL;
 127                        continue;
 128                }
 129                commit->object.flags |= not_shallow_flag;
 130                for (p = commit->parents, commit = NULL; p; p = p->next) {
 131                        int **depth_slot = commit_depth_at(&depths, p->item);
 132                        if (!*depth_slot) {
 133                                *depth_slot = xmalloc(sizeof(int));
 134                                **depth_slot = cur_depth;
 135                        } else {
 136                                if (cur_depth >= **depth_slot)
 137                                        continue;
 138                                **depth_slot = cur_depth;
 139                        }
 140                        if (p->next)
 141                                add_object_array(&p->item->object,
 142                                                NULL, &stack);
 143                        else {
 144                                commit = p->item;
 145                                cur_depth = **commit_depth_at(&depths, commit);
 146                        }
 147                }
 148        }
 149        for (i = 0; i < depths.slab_count; i++) {
 150                int j;
 151
 152                for (j = 0; j < depths.slab_size; j++)
 153                        free(depths.slab[i][j]);
 154        }
 155        clear_commit_depth(&depths);
 156
 157        return result;
 158}
 159
 160static void show_commit(struct commit *commit, void *data)
 161{
 162        commit_list_insert(commit, data);
 163}
 164
 165/*
 166 * Given rev-list arguments, run rev-list. All reachable commits
 167 * except border ones are marked with not_shallow_flag. Border commits
 168 * are marked with shallow_flag. The list of border/shallow commits
 169 * are also returned.
 170 */
 171struct commit_list *get_shallow_commits_by_rev_list(int ac, const char **av,
 172                                                    int shallow_flag,
 173                                                    int not_shallow_flag)
 174{
 175        struct commit_list *result = NULL, *p;
 176        struct commit_list *not_shallow_list = NULL;
 177        struct rev_info revs;
 178        int both_flags = shallow_flag | not_shallow_flag;
 179
 180        /*
 181         * SHALLOW (excluded) and NOT_SHALLOW (included) should not be
 182         * set at this point. But better be safe than sorry.
 183         */
 184        clear_object_flags(both_flags);
 185
 186        is_repository_shallow(the_repository); /* make sure shallows are read */
 187
 188        repo_init_revisions(the_repository, &revs, NULL);
 189        save_commit_buffer = 0;
 190        setup_revisions(ac, av, &revs, NULL);
 191
 192        if (prepare_revision_walk(&revs))
 193                die("revision walk setup failed");
 194        traverse_commit_list(&revs, show_commit, NULL, &not_shallow_list);
 195
 196        if (!not_shallow_list)
 197                die("no commits selected for shallow requests");
 198
 199        /* Mark all reachable commits as NOT_SHALLOW */
 200        for (p = not_shallow_list; p; p = p->next)
 201                p->item->object.flags |= not_shallow_flag;
 202
 203        /*
 204         * mark border commits SHALLOW + NOT_SHALLOW.
 205         * We cannot clear NOT_SHALLOW right now. Imagine border
 206         * commit A is processed first, then commit B, whose parent is
 207         * A, later. If NOT_SHALLOW on A is cleared at step 1, B
 208         * itself is considered border at step 2, which is incorrect.
 209         */
 210        for (p = not_shallow_list; p; p = p->next) {
 211                struct commit *c = p->item;
 212                struct commit_list *parent;
 213
 214                if (parse_commit(c))
 215                        die("unable to parse commit %s",
 216                            oid_to_hex(&c->object.oid));
 217
 218                for (parent = c->parents; parent; parent = parent->next)
 219                        if (!(parent->item->object.flags & not_shallow_flag)) {
 220                                c->object.flags |= shallow_flag;
 221                                commit_list_insert(c, &result);
 222                                break;
 223                        }
 224        }
 225        free_commit_list(not_shallow_list);
 226
 227        /*
 228         * Now we can clean up NOT_SHALLOW on border commits. Having
 229         * both flags set can confuse the caller.
 230         */
 231        for (p = result; p; p = p->next) {
 232                struct object *o = &p->item->object;
 233                if ((o->flags & both_flags) == both_flags)
 234                        o->flags &= ~not_shallow_flag;
 235        }
 236        return result;
 237}
 238
 239static void check_shallow_file_for_update(struct repository *r)
 240{
 241        if (r->parsed_objects->is_shallow == -1)
 242                BUG("shallow must be initialized by now");
 243
 244        if (!stat_validity_check(r->parsed_objects->shallow_stat, git_path_shallow(the_repository)))
 245                die("shallow file has changed since we read it");
 246}
 247
 248#define SEEN_ONLY 1
 249#define VERBOSE   2
 250#define QUICK 4
 251
 252struct write_shallow_data {
 253        struct strbuf *out;
 254        int use_pack_protocol;
 255        int count;
 256        unsigned flags;
 257};
 258
 259static int write_one_shallow(const struct commit_graft *graft, void *cb_data)
 260{
 261        struct write_shallow_data *data = cb_data;
 262        const char *hex = oid_to_hex(&graft->oid);
 263        if (graft->nr_parent != -1)
 264                return 0;
 265        if (data->flags & QUICK) {
 266                if (!has_object_file(&graft->oid))
 267                        return 0;
 268        } else if (data->flags & SEEN_ONLY) {
 269                struct commit *c = lookup_commit(the_repository, &graft->oid);
 270                if (!c || !(c->object.flags & SEEN)) {
 271                        if (data->flags & VERBOSE)
 272                                printf("Removing %s from .git/shallow\n",
 273                                       oid_to_hex(&c->object.oid));
 274                        return 0;
 275                }
 276        }
 277        data->count++;
 278        if (data->use_pack_protocol)
 279                packet_buf_write(data->out, "shallow %s", hex);
 280        else {
 281                strbuf_addstr(data->out, hex);
 282                strbuf_addch(data->out, '\n');
 283        }
 284        return 0;
 285}
 286
 287static int write_shallow_commits_1(struct strbuf *out, int use_pack_protocol,
 288                                   const struct oid_array *extra,
 289                                   unsigned flags)
 290{
 291        struct write_shallow_data data;
 292        int i;
 293        data.out = out;
 294        data.use_pack_protocol = use_pack_protocol;
 295        data.count = 0;
 296        data.flags = flags;
 297        for_each_commit_graft(write_one_shallow, &data);
 298        if (!extra)
 299                return data.count;
 300        for (i = 0; i < extra->nr; i++) {
 301                strbuf_addstr(out, oid_to_hex(extra->oid + i));
 302                strbuf_addch(out, '\n');
 303                data.count++;
 304        }
 305        return data.count;
 306}
 307
 308int write_shallow_commits(struct strbuf *out, int use_pack_protocol,
 309                          const struct oid_array *extra)
 310{
 311        return write_shallow_commits_1(out, use_pack_protocol, extra, 0);
 312}
 313
 314const char *setup_temporary_shallow(const struct oid_array *extra)
 315{
 316        struct tempfile *temp;
 317        struct strbuf sb = STRBUF_INIT;
 318
 319        if (write_shallow_commits(&sb, 0, extra)) {
 320                temp = xmks_tempfile(git_path("shallow_XXXXXX"));
 321
 322                if (write_in_full(temp->fd, sb.buf, sb.len) < 0 ||
 323                    close_tempfile_gently(temp) < 0)
 324                        die_errno("failed to write to %s",
 325                                  get_tempfile_path(temp));
 326                strbuf_release(&sb);
 327                return get_tempfile_path(temp);
 328        }
 329        /*
 330         * is_repository_shallow() sees empty string as "no shallow
 331         * file".
 332         */
 333        return "";
 334}
 335
 336void setup_alternate_shallow(struct lock_file *shallow_lock,
 337                             const char **alternate_shallow_file,
 338                             const struct oid_array *extra)
 339{
 340        struct strbuf sb = STRBUF_INIT;
 341        int fd;
 342
 343        fd = hold_lock_file_for_update(shallow_lock,
 344                                       git_path_shallow(the_repository),
 345                                       LOCK_DIE_ON_ERROR);
 346        check_shallow_file_for_update(the_repository);
 347        if (write_shallow_commits(&sb, 0, extra)) {
 348                if (write_in_full(fd, sb.buf, sb.len) < 0)
 349                        die_errno("failed to write to %s",
 350                                  get_lock_file_path(shallow_lock));
 351                *alternate_shallow_file = get_lock_file_path(shallow_lock);
 352        } else
 353                /*
 354                 * is_repository_shallow() sees empty string as "no
 355                 * shallow file".
 356                 */
 357                *alternate_shallow_file = "";
 358        strbuf_release(&sb);
 359}
 360
 361static int advertise_shallow_grafts_cb(const struct commit_graft *graft, void *cb)
 362{
 363        int fd = *(int *)cb;
 364        if (graft->nr_parent == -1)
 365                packet_write_fmt(fd, "shallow %s\n", oid_to_hex(&graft->oid));
 366        return 0;
 367}
 368
 369void advertise_shallow_grafts(int fd)
 370{
 371        if (!is_repository_shallow(the_repository))
 372                return;
 373        for_each_commit_graft(advertise_shallow_grafts_cb, &fd);
 374}
 375
 376/*
 377 * mark_reachable_objects() should have been run prior to this and all
 378 * reachable commits marked as "SEEN", except when quick_prune is non-zero,
 379 * in which case lines are excised from the shallow file if they refer to
 380 * commits that do not exist (any longer).
 381 */
 382void prune_shallow(unsigned options)
 383{
 384        struct lock_file shallow_lock = LOCK_INIT;
 385        struct strbuf sb = STRBUF_INIT;
 386        unsigned flags = SEEN_ONLY;
 387        int fd;
 388
 389        if (options & PRUNE_QUICK)
 390                flags |= QUICK;
 391
 392        if (options & PRUNE_SHOW_ONLY) {
 393                flags |= VERBOSE;
 394                write_shallow_commits_1(&sb, 0, NULL, flags);
 395                strbuf_release(&sb);
 396                return;
 397        }
 398        fd = hold_lock_file_for_update(&shallow_lock,
 399                                       git_path_shallow(the_repository),
 400                                       LOCK_DIE_ON_ERROR);
 401        check_shallow_file_for_update(the_repository);
 402        if (write_shallow_commits_1(&sb, 0, NULL, flags)) {
 403                if (write_in_full(fd, sb.buf, sb.len) < 0)
 404                        die_errno("failed to write to %s",
 405                                  get_lock_file_path(&shallow_lock));
 406                commit_lock_file(&shallow_lock);
 407        } else {
 408                unlink(git_path_shallow(the_repository));
 409                rollback_lock_file(&shallow_lock);
 410        }
 411        strbuf_release(&sb);
 412}
 413
 414struct trace_key trace_shallow = TRACE_KEY_INIT(SHALLOW);
 415
 416/*
 417 * Step 1, split sender shallow commits into "ours" and "theirs"
 418 * Step 2, clean "ours" based on .git/shallow
 419 */
 420void prepare_shallow_info(struct shallow_info *info, struct oid_array *sa)
 421{
 422        int i;
 423        trace_printf_key(&trace_shallow, "shallow: prepare_shallow_info\n");
 424        memset(info, 0, sizeof(*info));
 425        info->shallow = sa;
 426        if (!sa)
 427                return;
 428        ALLOC_ARRAY(info->ours, sa->nr);
 429        ALLOC_ARRAY(info->theirs, sa->nr);
 430        for (i = 0; i < sa->nr; i++) {
 431                if (has_object_file(sa->oid + i)) {
 432                        struct commit_graft *graft;
 433                        graft = lookup_commit_graft(the_repository,
 434                                                    &sa->oid[i]);
 435                        if (graft && graft->nr_parent < 0)
 436                                continue;
 437                        info->ours[info->nr_ours++] = i;
 438                } else
 439                        info->theirs[info->nr_theirs++] = i;
 440        }
 441}
 442
 443void clear_shallow_info(struct shallow_info *info)
 444{
 445        free(info->ours);
 446        free(info->theirs);
 447}
 448
 449/* Step 4, remove non-existent ones in "theirs" after getting the pack */
 450
 451void remove_nonexistent_theirs_shallow(struct shallow_info *info)
 452{
 453        struct object_id *oid = info->shallow->oid;
 454        int i, dst;
 455        trace_printf_key(&trace_shallow, "shallow: remove_nonexistent_theirs_shallow\n");
 456        for (i = dst = 0; i < info->nr_theirs; i++) {
 457                if (i != dst)
 458                        info->theirs[dst] = info->theirs[i];
 459                if (has_object_file(oid + info->theirs[i]))
 460                        dst++;
 461        }
 462        info->nr_theirs = dst;
 463}
 464
 465define_commit_slab(ref_bitmap, uint32_t *);
 466
 467#define POOL_SIZE (512 * 1024)
 468
 469struct paint_info {
 470        struct ref_bitmap ref_bitmap;
 471        unsigned nr_bits;
 472        char **pools;
 473        char *free, *end;
 474        unsigned pool_count;
 475};
 476
 477static uint32_t *paint_alloc(struct paint_info *info)
 478{
 479        unsigned nr = DIV_ROUND_UP(info->nr_bits, 32);
 480        unsigned size = nr * sizeof(uint32_t);
 481        void *p;
 482        if (!info->pool_count || size > info->end - info->free) {
 483                if (size > POOL_SIZE)
 484                        BUG("pool size too small for %d in paint_alloc()",
 485                            size);
 486                info->pool_count++;
 487                REALLOC_ARRAY(info->pools, info->pool_count);
 488                info->free = xmalloc(POOL_SIZE);
 489                info->pools[info->pool_count - 1] = info->free;
 490                info->end = info->free + POOL_SIZE;
 491        }
 492        p = info->free;
 493        info->free += size;
 494        return p;
 495}
 496
 497/*
 498 * Given a commit SHA-1, walk down to parents until either SEEN,
 499 * UNINTERESTING or BOTTOM is hit. Set the id-th bit in ref_bitmap for
 500 * all walked commits.
 501 */
 502static void paint_down(struct paint_info *info, const struct object_id *oid,
 503                       unsigned int id)
 504{
 505        unsigned int i, nr;
 506        struct commit_list *head = NULL;
 507        int bitmap_nr = DIV_ROUND_UP(info->nr_bits, 32);
 508        size_t bitmap_size = st_mult(sizeof(uint32_t), bitmap_nr);
 509        struct commit *c = lookup_commit_reference_gently(the_repository, oid,
 510                                                          1);
 511        uint32_t *tmp; /* to be freed before return */
 512        uint32_t *bitmap;
 513
 514        if (!c)
 515                return;
 516
 517        tmp = xmalloc(bitmap_size);
 518        bitmap = paint_alloc(info);
 519        memset(bitmap, 0, bitmap_size);
 520        bitmap[id / 32] |= (1U << (id % 32));
 521        commit_list_insert(c, &head);
 522        while (head) {
 523                struct commit_list *p;
 524                struct commit *c = pop_commit(&head);
 525                uint32_t **refs = ref_bitmap_at(&info->ref_bitmap, c);
 526
 527                /* XXX check "UNINTERESTING" from pack bitmaps if available */
 528                if (c->object.flags & (SEEN | UNINTERESTING))
 529                        continue;
 530                else
 531                        c->object.flags |= SEEN;
 532
 533                if (*refs == NULL)
 534                        *refs = bitmap;
 535                else {
 536                        memcpy(tmp, *refs, bitmap_size);
 537                        for (i = 0; i < bitmap_nr; i++)
 538                                tmp[i] |= bitmap[i];
 539                        if (memcmp(tmp, *refs, bitmap_size)) {
 540                                *refs = paint_alloc(info);
 541                                memcpy(*refs, tmp, bitmap_size);
 542                        }
 543                }
 544
 545                if (c->object.flags & BOTTOM)
 546                        continue;
 547
 548                if (parse_commit(c))
 549                        die("unable to parse commit %s",
 550                            oid_to_hex(&c->object.oid));
 551
 552                for (p = c->parents; p; p = p->next) {
 553                        if (p->item->object.flags & SEEN)
 554                                continue;
 555                        commit_list_insert(p->item, &head);
 556                }
 557        }
 558
 559        nr = get_max_object_index();
 560        for (i = 0; i < nr; i++) {
 561                struct object *o = get_indexed_object(i);
 562                if (o && o->type == OBJ_COMMIT)
 563                        o->flags &= ~SEEN;
 564        }
 565
 566        free(tmp);
 567}
 568
 569static int mark_uninteresting(const char *refname, const struct object_id *oid,
 570                              int flags, void *cb_data)
 571{
 572        struct commit *commit = lookup_commit_reference_gently(the_repository,
 573                                                               oid, 1);
 574        if (!commit)
 575                return 0;
 576        commit->object.flags |= UNINTERESTING;
 577        mark_parents_uninteresting(commit);
 578        return 0;
 579}
 580
 581static void post_assign_shallow(struct shallow_info *info,
 582                                struct ref_bitmap *ref_bitmap,
 583                                int *ref_status);
 584/*
 585 * Step 6(+7), associate shallow commits with new refs
 586 *
 587 * info->ref must be initialized before calling this function.
 588 *
 589 * If used is not NULL, it's an array of info->shallow->nr
 590 * bitmaps. The n-th bit set in the m-th bitmap if ref[n] needs the
 591 * m-th shallow commit from info->shallow.
 592 *
 593 * If used is NULL, "ours" and "theirs" are updated. And if ref_status
 594 * is not NULL it's an array of ref->nr ints. ref_status[i] is true if
 595 * the ref needs some shallow commits from either info->ours or
 596 * info->theirs.
 597 */
 598void assign_shallow_commits_to_refs(struct shallow_info *info,
 599                                    uint32_t **used, int *ref_status)
 600{
 601        struct object_id *oid = info->shallow->oid;
 602        struct oid_array *ref = info->ref;
 603        unsigned int i, nr;
 604        int *shallow, nr_shallow = 0;
 605        struct paint_info pi;
 606
 607        trace_printf_key(&trace_shallow, "shallow: assign_shallow_commits_to_refs\n");
 608        ALLOC_ARRAY(shallow, info->nr_ours + info->nr_theirs);
 609        for (i = 0; i < info->nr_ours; i++)
 610                shallow[nr_shallow++] = info->ours[i];
 611        for (i = 0; i < info->nr_theirs; i++)
 612                shallow[nr_shallow++] = info->theirs[i];
 613
 614        /*
 615         * Prepare the commit graph to track what refs can reach what
 616         * (new) shallow commits.
 617         */
 618        nr = get_max_object_index();
 619        for (i = 0; i < nr; i++) {
 620                struct object *o = get_indexed_object(i);
 621                if (!o || o->type != OBJ_COMMIT)
 622                        continue;
 623
 624                o->flags &= ~(UNINTERESTING | BOTTOM | SEEN);
 625        }
 626
 627        memset(&pi, 0, sizeof(pi));
 628        init_ref_bitmap(&pi.ref_bitmap);
 629        pi.nr_bits = ref->nr;
 630
 631        /*
 632         * "--not --all" to cut short the traversal if new refs
 633         * connect to old refs. If not (e.g. force ref updates) it'll
 634         * have to go down to the current shallow commits.
 635         */
 636        head_ref(mark_uninteresting, NULL);
 637        for_each_ref(mark_uninteresting, NULL);
 638
 639        /* Mark potential bottoms so we won't go out of bound */
 640        for (i = 0; i < nr_shallow; i++) {
 641                struct commit *c = lookup_commit(the_repository,
 642                                                 &oid[shallow[i]]);
 643                c->object.flags |= BOTTOM;
 644        }
 645
 646        for (i = 0; i < ref->nr; i++)
 647                paint_down(&pi, ref->oid + i, i);
 648
 649        if (used) {
 650                int bitmap_size = DIV_ROUND_UP(pi.nr_bits, 32) * sizeof(uint32_t);
 651                memset(used, 0, sizeof(*used) * info->shallow->nr);
 652                for (i = 0; i < nr_shallow; i++) {
 653                        const struct commit *c = lookup_commit(the_repository,
 654                                                               &oid[shallow[i]]);
 655                        uint32_t **map = ref_bitmap_at(&pi.ref_bitmap, c);
 656                        if (*map)
 657                                used[shallow[i]] = xmemdupz(*map, bitmap_size);
 658                }
 659                /*
 660                 * unreachable shallow commits are not removed from
 661                 * "ours" and "theirs". The user is supposed to run
 662                 * step 7 on every ref separately and not trust "ours"
 663                 * and "theirs" any more.
 664                 */
 665        } else
 666                post_assign_shallow(info, &pi.ref_bitmap, ref_status);
 667
 668        clear_ref_bitmap(&pi.ref_bitmap);
 669        for (i = 0; i < pi.pool_count; i++)
 670                free(pi.pools[i]);
 671        free(pi.pools);
 672        free(shallow);
 673}
 674
 675struct commit_array {
 676        struct commit **commits;
 677        int nr, alloc;
 678};
 679
 680static int add_ref(const char *refname, const struct object_id *oid,
 681                   int flags, void *cb_data)
 682{
 683        struct commit_array *ca = cb_data;
 684        ALLOC_GROW(ca->commits, ca->nr + 1, ca->alloc);
 685        ca->commits[ca->nr] = lookup_commit_reference_gently(the_repository,
 686                                                             oid, 1);
 687        if (ca->commits[ca->nr])
 688                ca->nr++;
 689        return 0;
 690}
 691
 692static void update_refstatus(int *ref_status, int nr, uint32_t *bitmap)
 693{
 694        unsigned int i;
 695        if (!ref_status)
 696                return;
 697        for (i = 0; i < nr; i++)
 698                if (bitmap[i / 32] & (1U << (i % 32)))
 699                        ref_status[i]++;
 700}
 701
 702/*
 703 * Step 7, reachability test on "ours" at commit level
 704 */
 705static void post_assign_shallow(struct shallow_info *info,
 706                                struct ref_bitmap *ref_bitmap,
 707                                int *ref_status)
 708{
 709        struct object_id *oid = info->shallow->oid;
 710        struct commit *c;
 711        uint32_t **bitmap;
 712        int dst, i, j;
 713        int bitmap_nr = DIV_ROUND_UP(info->ref->nr, 32);
 714        struct commit_array ca;
 715
 716        trace_printf_key(&trace_shallow, "shallow: post_assign_shallow\n");
 717        if (ref_status)
 718                memset(ref_status, 0, sizeof(*ref_status) * info->ref->nr);
 719
 720        /* Remove unreachable shallow commits from "theirs" */
 721        for (i = dst = 0; i < info->nr_theirs; i++) {
 722                if (i != dst)
 723                        info->theirs[dst] = info->theirs[i];
 724                c = lookup_commit(the_repository, &oid[info->theirs[i]]);
 725                bitmap = ref_bitmap_at(ref_bitmap, c);
 726                if (!*bitmap)
 727                        continue;
 728                for (j = 0; j < bitmap_nr; j++)
 729                        if (bitmap[0][j]) {
 730                                update_refstatus(ref_status, info->ref->nr, *bitmap);
 731                                dst++;
 732                                break;
 733                        }
 734        }
 735        info->nr_theirs = dst;
 736
 737        memset(&ca, 0, sizeof(ca));
 738        head_ref(add_ref, &ca);
 739        for_each_ref(add_ref, &ca);
 740
 741        /* Remove unreachable shallow commits from "ours" */
 742        for (i = dst = 0; i < info->nr_ours; i++) {
 743                if (i != dst)
 744                        info->ours[dst] = info->ours[i];
 745                c = lookup_commit(the_repository, &oid[info->ours[i]]);
 746                bitmap = ref_bitmap_at(ref_bitmap, c);
 747                if (!*bitmap)
 748                        continue;
 749                for (j = 0; j < bitmap_nr; j++)
 750                        if (bitmap[0][j] &&
 751                            /* Step 7, reachability test at commit level */
 752                            !in_merge_bases_many(c, ca.nr, ca.commits)) {
 753                                update_refstatus(ref_status, info->ref->nr, *bitmap);
 754                                dst++;
 755                                break;
 756                        }
 757        }
 758        info->nr_ours = dst;
 759
 760        free(ca.commits);
 761}
 762
 763/* (Delayed) step 7, reachability test at commit level */
 764int delayed_reachability_test(struct shallow_info *si, int c)
 765{
 766        if (si->need_reachability_test[c]) {
 767                struct commit *commit = lookup_commit(the_repository,
 768                                                      &si->shallow->oid[c]);
 769
 770                if (!si->commits) {
 771                        struct commit_array ca;
 772
 773                        memset(&ca, 0, sizeof(ca));
 774                        head_ref(add_ref, &ca);
 775                        for_each_ref(add_ref, &ca);
 776                        si->commits = ca.commits;
 777                        si->nr_commits = ca.nr;
 778                }
 779
 780                si->reachable[c] = in_merge_bases_many(commit,
 781                                                       si->nr_commits,
 782                                                       si->commits);
 783                si->need_reachability_test[c] = 0;
 784        }
 785        return si->reachable[c];
 786}