Raw
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 }