| 1 | #define USE_THE_REPOSITORY_VARIABLE |
| 2 | |
| 3 | #include "test-tool.h" |
| 4 | #include "git-compat-util.h" |
| 5 | #include "hex.h" |
| 6 | #include "odb.h" |
| 7 | #include "pack-bitmap.h" |
| 8 | #include "pseudo-merge.h" |
| 9 | #include "setup.h" |
| 10 | |
| 11 | static int bitmap_list_commits(void) |
| 12 | { |
| 13 | return test_bitmap_commits(the_repository); |
| 14 | } |
| 15 | |
| 16 | static int bitmap_list_commits_with_offset(void) |
| 17 | { |
| 18 | return test_bitmap_commits_with_offset(the_repository); |
| 19 | } |
| 20 | |
| 21 | static int bitmap_dump_hashes(void) |
| 22 | { |
| 23 | return test_bitmap_hashes(the_repository); |
| 24 | } |
| 25 | |
| 26 | static int bitmap_dump_pseudo_merges(void) |
| 27 | { |
| 28 | return test_bitmap_pseudo_merges(the_repository); |
| 29 | } |
| 30 | |
| 31 | static int bitmap_dump_pseudo_merge_commits(uint32_t n) |
| 32 | { |
| 33 | return test_bitmap_pseudo_merge_commits(the_repository, n); |
| 34 | } |
| 35 | |
| 36 | static int bitmap_dump_pseudo_merge_objects(uint32_t n) |
| 37 | { |
| 38 | return test_bitmap_pseudo_merge_objects(the_repository, n); |
| 39 | } |
| 40 | |
| 41 | static int add_packed_object(const struct object_id *oid, |
| 42 | struct packed_git *pack, |
| 43 | uint32_t pos, |
| 44 | void *_data) |
| 45 | { |
| 46 | struct packing_data *packed = _data; |
| 47 | struct object_entry *entry; |
| 48 | struct object_info oi = OBJECT_INFO_INIT; |
| 49 | enum object_type type; |
| 50 | |
| 51 | oi.typep = &type; |
| 52 | |
| 53 | if (packlist_find(packed, oid)) |
| 54 | die("pack contains duplicate object %s", oid_to_hex(oid)); |
| 55 | |
| 56 | entry = packlist_alloc(packed, oid); |
| 57 | entry->idx.offset = nth_packed_object_offset(pack, pos); |
| 58 | if (packed_object_info(NULL, pack, entry->idx.offset, &oi) < 0) |
| 59 | die("could not get type of object %s", |
| 60 | oid_to_hex(oid)); |
| 61 | oe_set_type(entry, type); |
| 62 | oe_set_in_pack(packed, entry, pack); |
| 63 | |
| 64 | return 0; |
| 65 | } |
| 66 | |
| 67 | static int idx_oid_cmp(const void *va, const void *vb) |
| 68 | { |
| 69 | const struct pack_idx_entry *a = *(const struct pack_idx_entry **)va; |
| 70 | const struct pack_idx_entry *b = *(const struct pack_idx_entry **)vb; |
| 71 | |
| 72 | return oidcmp(&a->oid, &b->oid); |
| 73 | } |
| 74 | |
| 75 | static int bitmap_write(const char *basename) |
| 76 | { |
| 77 | struct packed_git *p = NULL; |
| 78 | struct packing_data packed = { 0 }; |
| 79 | struct bitmap_writer writer; |
| 80 | struct pack_idx_entry **index; |
| 81 | struct strbuf buf = STRBUF_INIT; |
| 82 | uint32_t i; |
| 83 | |
| 84 | prepare_repo_settings(the_repository); |
| 85 | repo_for_each_pack(the_repository, p) { |
| 86 | if (!strcmp(pack_basename(p), basename)) |
| 87 | break; |
| 88 | } |
| 89 | |
| 90 | if (!p) |
| 91 | die("could not find pack '%s'", basename); |
| 92 | |
| 93 | if (open_pack_index(p)) |
| 94 | die("cannot open pack index for '%s'", p->pack_name); |
| 95 | |
| 96 | prepare_packing_data(the_repository, &packed); |
| 97 | |
| 98 | for_each_object_in_pack(p, add_packed_object, &packed, |
| 99 | ODB_FOR_EACH_OBJECT_PACK_ORDER); |
| 100 | |
| 101 | /* |
| 102 | * Build the index array now that data.packed.objects[] is |
| 103 | * fully allocated (packlist_alloc() may have reallocated it |
| 104 | * during the loop above). |
| 105 | */ |
| 106 | ALLOC_ARRAY(index, p->num_objects); |
| 107 | for (i = 0; i < p->num_objects; i++) |
| 108 | index[i] = &packed.objects[i].idx; |
| 109 | |
| 110 | bitmap_writer_init(&writer, the_repository, &packed, NULL); |
| 111 | bitmap_writer_build_type_index(&writer, index); |
| 112 | |
| 113 | while (strbuf_getline_lf(&buf, stdin) != EOF) { |
| 114 | struct object_id oid; |
| 115 | struct commit *c; |
| 116 | |
| 117 | if (get_oid_hex(buf.buf, &oid)) |
| 118 | die("invalid OID: %s", buf.buf); |
| 119 | |
| 120 | c = lookup_commit(the_repository, &oid); |
| 121 | if (!c || repo_parse_commit(the_repository, c)) |
| 122 | die("could not parse commit %s", buf.buf); |
| 123 | |
| 124 | bitmap_writer_push_commit(&writer, c, 0); |
| 125 | } |
| 126 | |
| 127 | select_pseudo_merges(&writer); |
| 128 | if (bitmap_writer_build(&writer) < 0) |
| 129 | die("failed to build bitmaps"); |
| 130 | |
| 131 | bitmap_writer_set_checksum(&writer, p->hash); |
| 132 | |
| 133 | QSORT(index, p->num_objects, idx_oid_cmp); |
| 134 | |
| 135 | strbuf_reset(&buf); |
| 136 | strbuf_addstr(&buf, p->pack_name); |
| 137 | strbuf_strip_suffix(&buf, ".pack"); |
| 138 | strbuf_addstr(&buf, ".bitmap"); |
| 139 | bitmap_writer_finish(&writer, index, buf.buf, 0); |
| 140 | |
| 141 | bitmap_writer_free(&writer); |
| 142 | strbuf_release(&buf); |
| 143 | free(index); |
| 144 | clear_packing_data(&packed); |
| 145 | |
| 146 | return 0; |
| 147 | } |
| 148 | |
| 149 | int cmd__bitmap(int argc, const char **argv) |
| 150 | { |
| 151 | setup_git_directory(the_repository); |
| 152 | |
| 153 | if (argc == 2 && !strcmp(argv[1], "list-commits")) |
| 154 | return bitmap_list_commits(); |
| 155 | if (argc == 2 && !strcmp(argv[1], "list-commits-with-offset")) |
| 156 | return bitmap_list_commits_with_offset(); |
| 157 | if (argc == 2 && !strcmp(argv[1], "dump-hashes")) |
| 158 | return bitmap_dump_hashes(); |
| 159 | if (argc == 2 && !strcmp(argv[1], "dump-pseudo-merges")) |
| 160 | return bitmap_dump_pseudo_merges(); |
| 161 | if (argc == 3 && !strcmp(argv[1], "dump-pseudo-merge-commits")) |
| 162 | return bitmap_dump_pseudo_merge_commits(atoi(argv[2])); |
| 163 | if (argc == 3 && !strcmp(argv[1], "dump-pseudo-merge-objects")) |
| 164 | return bitmap_dump_pseudo_merge_objects(atoi(argv[2])); |
| 165 | if (argc == 3 && !strcmp(argv[1], "write")) |
| 166 | return bitmap_write(argv[2]); |
| 167 | |
| 168 | usage("\ttest-tool bitmap list-commits\n" |
| 169 | "\ttest-tool bitmap list-commits-with-offset\n" |
| 170 | "\ttest-tool bitmap dump-hashes\n" |
| 171 | "\ttest-tool bitmap dump-pseudo-merges\n" |
| 172 | "\ttest-tool bitmap dump-pseudo-merge-commits <n>\n" |
| 173 | "\ttest-tool bitmap dump-pseudo-merge-objects <n>\n" |
| 174 | "\ttest-tool bitmap write <pack-basename> < <commit-list>"); |
| 175 | |
| 176 | return -1; |
| 177 | } |