1 /* Helper program for git-cinnabar
2  *
3  * It receives commands on stdin and outputs results on stdout.
4  * The following commands are supported:
5  * - git2hg <committish>
6  *     Returns the contents of the git note containing git->hg metadata
7  *     for the given commit in a `cat-file --batch`-like format.
8  * - hg2git <hg_sha1>
9  *     Returns the sha1 of the git object corresponding to the given
10  *     mercurial sha1.
11  * - manifest <hg_sha1>
12  *     Returns the contents of the mercurial manifest with the given
13  *     mercurial sha1, preceded by its length in text form, and followed
14  *     by a carriage return.
15  * - check-manifest <hg_sha1>
16  *     Returns 'ok' when the sha1 of the contents of the mercurial manifest
17  *     matches the manifest sha1, otherwise returns 'error'.
18  * - cat-file <object>
19  *     Returns the contents of the given git object, in a `cat-file
20  *     --batch`-like format.
21  *  - connect <url>
22  *     Connects to the mercurial repository at the given url. The helper then
23  *     expects one of the following commands:
24  *     - state
25  *       This prints out three blocks of data, being the result of the
26  *       following commands on the repository: branchmap, heads, bookmarks.
27  *     - known <node>+
28  *       Calls the "known" command on the repository and returns the
29  *       corresponding result.
30  *     - listkeys <namespace>
31  *     	 Calls the "listkeys" command on the repository and returns the
32  *     	 corresponding result.
33  *     - getbundle <heads> <common> <bundle2caps>
34  *       Calls the "getbundle" command on the repository and streams a
35  *       changegroup in result. `heads` and `common` are comma separated
36  *       lists of changesets.
37  *     - unbundle <head>+
38  *       Calls the "unbundle command on the repository.
39  *     - pushkey <namespace> <key> <old> <new>
40  *     	 Calls the "pushkey" command on the repository and returns the
41  *     	 corresponding result.
42  *     - lookup <key>
43  *       Calls the "lookup" command on the repository and returns the
44  *     	 corresponding result.
45  */
46 
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <string.h>
50 
51 #include "cache.h"
52 #include "attr.h"
53 #include "blob.h"
54 #include "commit.h"
55 #include "config.h"
56 #include "diff.h"
57 #include "diffcore.h"
58 #include "exec-cmd.h"
59 #include "hashmap.h"
60 #include "log-tree.h"
61 #include "shallow.h"
62 #include "strslice.h"
63 #include "strbuf.h"
64 #include "string-list.h"
65 #include "streaming.h"
66 #include "object.h"
67 #include "oidset.h"
68 #include "progress.h"
69 #include "quote.h"
70 #include "replace-object.h"
71 #include "revision.h"
72 #include "tree.h"
73 #include "tree-walk.h"
74 #include "hg-connect.h"
75 #include "hg-data.h"
76 #include "cinnabar-helper.h"
77 #include "cinnabar-fast-import.h"
78 #include "cinnabar-notes.h"
79 #include "which.h"
80 
81 #define _STRINGIFY(s) # s
82 #define STRINGIFY(s) _STRINGIFY(s)
83 
84 #ifndef HELPER_HASH
85 #define HELPER_HASH unknown
86 #endif
87 
88 #define CMD_VERSION 3003
89 
90 #define MIN_CMD_VERSION 3003
91 
92 static const char NULL_NODE[] = "0000000000000000000000000000000000000000";
93 
94 #define MODE_IMPORT 0x01
95 #define MODE_WIRE 0x02
96 
97 static int mode = 0xff; // Enable everything by default
98 
99 struct notes_tree git2hg, hg2git, files_meta;
100 
101 // XXX: Should use a hg-specific oidset type.
102 struct oidset hg2git_seen = OIDSET_INIT;
103 
104 int metadata_flags = 0;
105 int cinnabar_check = 0;
106 int cinnabar_experiments = 0;
107 
config(const char * name,struct strbuf * result)108 static int config(const char *name, struct strbuf *result)
109 {
110 	struct strbuf key = STRBUF_INIT;
111 	char *p, *end;
112 	const char *val;
113 
114 	strbuf_addstr(&key, "GIT_CINNABAR_");
115 	strbuf_addstr(&key, name);
116 	for (p = key.buf + sizeof("git_cinnabar"), end = key.buf + key.len;
117 	     p < end; p++)
118 		*p = toupper(*p);
119 	val = getenv(key.buf);
120 	if (!val) {
121 		strbuf_release(&key);
122 		strbuf_addstr(&key, "cinnabar.");
123 		strbuf_addstr(&key, name);
124 		if (git_config_get_value(key.buf, &val)) {
125 			strbuf_release(&key);
126 			return 1;
127 		}
128 	}
129 	strbuf_addstr(result, val);
130 	strbuf_release(&key);
131 	return 0;
132 }
133 
cleanup_object_array_entry(struct object_array_entry * entry,void * data)134 static int cleanup_object_array_entry(struct object_array_entry *entry, void *data)
135 {
136 	if (entry->item->type == OBJ_TREE)
137 		free_tree_buffer((struct tree *)entry->item);
138 	return 1;
139 }
140 
rev_info_release(struct rev_info * revs)141 static void rev_info_release(struct rev_info *revs)
142 {
143 	int i;
144 
145 	object_array_filter(&revs->pending, cleanup_object_array_entry, NULL);
146 	object_array_clear(&revs->pending);
147 	object_array_clear(&revs->boundary_commits);
148 	for (i = 0; i < revs->cmdline.nr; i++)
149 		free((void *)revs->cmdline.rev[i].name);
150 	free(revs->cmdline.rev);
151 	clear_pathspec(&revs->prune_data);
152 	clear_pathspec(&revs->pruning.pathspec);
153 	clear_pathspec(&revs->diffopt.pathspec);
154 	revs->cmdline.rev = NULL;
155 	for (i = 0; i < revs->treesame.size; i++)
156 		if (revs->treesame.entries[i].base)
157 			free(revs->treesame.entries[i].decoration);
158 	free(revs->treesame.entries);
159 }
160 
split_command(char * line,const char ** command,struct string_list * args)161 static void split_command(char *line, const char **command,
162 			  struct string_list *args)
163 {
164 	struct string_list split_line = STRING_LIST_INIT_NODUP;
165 	string_list_split_in_place(&split_line, line, ' ', 1);
166 	*command = split_line.items[0].string;
167 	if (split_line.nr > 1)
168 		string_list_split_in_place(
169 			args, split_line.items[1].string, ' ', -1);
170 	string_list_clear(&split_line, 0);
171 }
172 
send_buffer(struct strbuf * buf)173 static void send_buffer(struct strbuf *buf)
174 {
175 	if (buf) {
176 		struct strbuf header = STRBUF_INIT;
177 
178 		strbuf_addf(&header, "%lu\n", buf->len);
179 		write_or_die(1, header.buf, header.len);
180 		strbuf_release(&header);
181 
182 		write_or_die(1, buf->buf, buf->len);
183 		write_or_die(1, "\n", 1);
184 	} else {
185 		write_or_die(1, "-1\n\n", 4);
186 	}
187 }
188 
189 /* Send git object info and content to stdout, like cat-file --batch does. */
send_object(const struct object_id * oid)190 static void send_object(const struct object_id *oid)
191 {
192 	struct strbuf header = STRBUF_INIT;
193 	enum object_type type;
194 	unsigned long sz;
195 	struct git_istream *st;
196 
197 	st = open_istream(the_repository, oid, &type, &sz, NULL);
198 
199 	if (!st)
200 		die("open_istream failed for %s", oid_to_hex(oid));
201 
202 	strbuf_addf(&header, "%s %s %lu\n", oid_to_hex(oid), type_name(type),
203 	            sz);
204 
205 	write_or_die(1, header.buf, header.len);
206 
207 	strbuf_release(&header);
208 
209 	for (;;) {
210 		char buf[1024 * 16];
211 		ssize_t wrote;
212 		ssize_t readlen = read_istream(st, buf, sizeof(buf));
213 
214 		if (readlen <= 0)
215 			break;
216 
217 		wrote = write_in_full(1, buf, readlen);
218 		if (wrote < readlen)
219 			break;
220 
221 		sz -= wrote;
222 	}
223 
224 	if (sz != 0)
225 		die("Failed to write object");
226 
227 	write_or_die(1, "\n", 1);
228 
229 	close_istream(st);
230 }
231 
do_cat_file(struct string_list * args)232 static void do_cat_file(struct string_list *args)
233 {
234 	struct object_id oid;
235 
236 	if (args->nr != 1)
237 		goto not_found;
238 
239 	if (get_oid(args->items[0].string, &oid))
240 		goto not_found;
241 
242 	send_object(&oid);
243 	return;
244 
245 not_found:
246 	write_or_die(1, NULL_NODE, 40);
247 	write_or_die(1, "\n", 1);
248 }
249 
250 struct ls_tree_context {
251 	struct strbuf buf;
252 	struct object_list *list;
253 	int recursive;
254 };
255 
fill_ls_tree(const struct object_id * oid,struct strbuf * base,const char * pathname,unsigned mode,void * context)256 static int fill_ls_tree(const struct object_id *oid, struct strbuf *base,
257 			const char *pathname, unsigned mode, void *context)
258 {
259 	struct ls_tree_context *ctx = context;
260 	struct strbuf *buf = &ctx->buf;
261 	const char *type = blob_type;
262 
263 	if (S_ISGITLINK(mode)) {
264 		type = commit_type;
265 	} else if (S_ISDIR(mode)) {
266 		object_list_insert((struct object *)lookup_tree(the_repository, oid),
267 		                   &ctx->list);
268 		if (ctx->recursive)
269 			return READ_TREE_RECURSIVE;
270 		type = tree_type;
271 	}
272 
273 	strbuf_addf(buf, "%06o %s %s\t", mode, type, oid_to_hex(oid));
274 	strbuf_addbuf(buf, base);
275 	strbuf_addstr(buf, pathname);
276 	strbuf_addch(buf, '\0');
277 	return 0;
278 }
279 
do_ls_tree(struct string_list * args)280 static void do_ls_tree(struct string_list *args)
281 {
282 	struct object_id oid;
283 	struct tree *tree = NULL;
284 	struct ls_tree_context ctx = { STRBUF_INIT, NULL, 0 };
285 	struct pathspec match_all;
286 
287 	if (args->nr == 2) {
288 		if (strcmp(args->items[1].string, "-r"))
289 			goto not_found;
290 		ctx.recursive = 1;
291 	} else if (args->nr != 1)
292 		goto not_found;
293 
294 	if (get_oid(args->items[0].string, &oid))
295 		goto not_found;
296 
297 	tree = parse_tree_indirect(&oid);
298 	if (!tree)
299 		goto not_found;
300 
301 	memset(&match_all, 0, sizeof(match_all));
302 	read_tree(the_repository, tree, &match_all, fill_ls_tree, &ctx);
303 	send_buffer(&ctx.buf);
304 	strbuf_release(&ctx.buf);
305 
306 	while (ctx.list) {
307 		struct object *obj = ctx.list->item;
308 		struct object_list *elem = ctx.list;
309 		ctx.list = elem->next;
310 		free(elem);
311 		free_tree_buffer((struct tree *)obj);
312 	}
313 	return;
314 not_found:
315 	write_or_die(1, "0\n\n", 3);
316 }
317 
string_list_to_argv(struct string_list * args)318 static const char **string_list_to_argv(struct string_list *args)
319 {
320 	const char **argv = malloc(sizeof(char *) * (args->nr + 2));
321 	int i;
322 
323 	argv[0] = "";
324 	for (i = 0; i < args->nr; i++) {
325 		argv[i + 1] = args->items[i].string;
326 	}
327 	argv[args->nr + 1] = NULL;
328 
329 	return argv;
330 }
331 
do_rev_list(struct string_list * args)332 static void do_rev_list(struct string_list *args)
333 {
334 	struct rev_info revs;
335 	struct commit *commit;
336 	struct strbuf buf = STRBUF_INIT;
337 	const char **argv = string_list_to_argv(args);
338 
339 	init_revisions(&revs, NULL);
340 	// Note: we do a pass through, but don't make much effort to actually
341 	// support all the options properly.
342 	setup_revisions(args->nr + 1, argv, &revs, NULL);
343 	free(argv);
344 
345 	// Hack to force simplify_commit to save parents. full_diff is only
346 	// checked for there or in setup_revisions so there is no other side
347 	// effect.
348 	revs.full_diff = 1;
349 
350 	if (prepare_revision_walk(&revs))
351 		die("revision walk setup failed");
352 
353 	while ((commit = get_revision(&revs)) != NULL) {
354 		struct commit_list *parent;
355 		struct commit_graft *graft;
356 		if (commit->object.flags & BOUNDARY)
357 			strbuf_addch(&buf, '-');
358 		strbuf_addstr(&buf, oid_to_hex(&commit->object.oid));
359 		strbuf_addch(&buf, ' ');
360 		strbuf_addstr(&buf, oid_to_hex(get_commit_tree_oid(commit)));
361 		parent = commit->parents;
362 		if (!parent && is_repository_shallow(the_repository) &&
363 		    (graft = lookup_commit_graft(
364 			the_repository, &commit->object.oid)) != NULL &&
365 		    graft->nr_parent < 0) {
366 			strbuf_addstr(&buf, " shallow");
367 			if (revs.boundary)
368 				strbuf_addstr(&buf, "\n-shallow shallow");
369 		} else while (parent) {
370 			strbuf_addch(&buf, ' ');
371 			strbuf_addstr(&buf, oid_to_hex(
372 				&parent->item->object.oid));
373 			parent = parent->next;
374 		}
375 		strbuf_addch(&buf, '\n');
376 
377 		// If parents were altered by simplify_commit, we want to
378 		// restore them for any subsequent operation on the commit.
379 		//
380 		// get_saved_parents returning NULL means there is no saved
381 		// parents for the commit. If there was a saved value of null,
382 		// it would mean the commit was a root in the first place, but
383 		// then why would it have been saved?
384 		parent = get_saved_parents(&revs, commit);
385 		if (parent && parent != commit->parents) {
386 			free_commit_list(commit->parents);
387 			commit->parents = copy_commit_list(parent);
388 		}
389 	}
390 
391 	// More extensive than reset_revision_walk(). Otherwise --boundary
392 	// and pathspecs don't work properly.
393 	clear_object_flags(ALL_REV_FLAGS | TOPO_WALK_EXPLORED | TOPO_WALK_INDEGREE);
394 	send_buffer(&buf);
395 	strbuf_release(&buf);
396 	rev_info_release(&revs);
397 }
398 
strbuf_diff_tree(struct diff_queue_struct * q,struct diff_options * opt,void * data)399 static void strbuf_diff_tree(struct diff_queue_struct *q,
400                              struct diff_options *opt, void *data)
401 {
402 	struct strbuf *buf = data;
403 	int i;
404 
405 	for (i = 0; i < q->nr; i++) {
406 		struct diff_filepair *p = q->queue[i];
407 		if (p->status == 0)
408 			die("internal diff status error");
409 		if (p->status == DIFF_STATUS_UNKNOWN)
410 			continue;
411 		strbuf_addf(buf, "%06o %06o %s %s %c",
412 		            p->one->mode,
413 		            p->two->mode,
414 		            oid_to_hex(&p->one->oid),
415 		            oid_to_hex(&p->two->oid),
416 		            p->status);
417 		if (p->score)
418 			strbuf_addf(buf, "%03d",
419 			            (int)(p->score * 100 / MAX_SCORE));
420 		strbuf_addch(buf, '\t');
421 		if (p->status == DIFF_STATUS_COPIED ||
422 		    p->status == DIFF_STATUS_RENAMED) {
423 			strbuf_addstr(buf, p->one->path);
424 			strbuf_addch(buf, '\0');
425 			strbuf_addstr(buf, p->two->path);
426 		} else {
427 			strbuf_addstr(buf, p->one->mode ? p->one->path
428 			                                : p->two->path);
429 		}
430 		strbuf_addch(buf, '\0');
431 	}
432 }
433 
do_diff_tree(struct string_list * args)434 static void do_diff_tree(struct string_list *args)
435 {
436 	struct rev_info revs;
437 	struct strbuf buf = STRBUF_INIT;
438 	const char **argv = string_list_to_argv(args);
439 
440 	init_revisions(&revs, NULL);
441 	revs.diff = 1;
442 	// Note: we do a pass through, but don't make much effort to actually
443 	// support all the options properly.
444 	setup_revisions(args->nr + 1, argv, &revs, NULL);
445 	revs.diffopt.output_format = DIFF_FORMAT_CALLBACK;
446 	revs.diffopt.format_callback = strbuf_diff_tree;
447 	revs.diffopt.format_callback_data = &buf;
448 	revs.diffopt.flags.recursive = 1;
449 	free(argv);
450 
451 	if (revs.pending.nr != 2)
452 		die("diff-tree needs two revs");
453 
454 	diff_tree_oid(&revs.pending.objects[0].item->oid,
455 	              &revs.pending.objects[1].item->oid,
456 	              "", &revs.diffopt);
457 	log_tree_diff_flush(&revs);
458 	send_buffer(&buf);
459 	strbuf_release(&buf);
460 	rev_info_release(&revs);
461 }
462 
do_get_note(struct notes_tree * t,struct string_list * args)463 static void do_get_note(struct notes_tree *t, struct string_list *args)
464 {
465 	struct object_id oid;
466 	const struct object_id *note;
467 
468 	if (args->nr != 1)
469 		goto not_found;
470 
471 	ensure_notes(t);
472 
473 	if (get_oid_committish(args->items[0].string, &oid))
474 		goto not_found;
475 
476 	note = get_note(t, lookup_replace_object(the_repository, &oid));
477 	if (!note)
478 		goto not_found;
479 
480 	send_object(note);
481 	return;
482 
483 not_found:
484 	write_or_die(1, NULL_NODE, 40);
485 	write_or_die(1, "\n", 1);
486 }
487 
get_abbrev_sha1_hex(const char * hex,unsigned char * sha1)488 static size_t get_abbrev_sha1_hex(const char *hex, unsigned char *sha1)
489 {
490 	const char *hex_start = hex;
491 	unsigned char *end = sha1 + 20;
492 	while (sha1 < end) {
493 		unsigned int val;
494 		if (!hex[0])
495 			val = 0xff;
496 		else if (!hex[1])
497 			val = (hexval(hex[0]) << 4) | 0xf;
498 		else
499 			val = (hexval(hex[0]) << 4) | hexval(hex[1]);
500 		if (val & ~0xff)
501 			return 0;
502 		*sha1++ = val;
503 		if (!hex[0] || !hex[1])
504 			break;
505 		hex += 2;
506 	}
507 	while (sha1 < end) {
508 		*sha1++ = 0xff;
509 	}
510 	return hex - hex_start + !!hex[0];
511 }
512 
resolve_hg2git(const struct hg_object_id * oid,size_t len)513 static const struct object_id *resolve_hg2git(const struct hg_object_id *oid,
514                                               size_t len)
515 {
516 	struct object_id git_oid;
517 	const struct object_id *note;
518 
519 	ensure_notes(&hg2git);
520 
521 	note = get_note_hg(&hg2git, oid);
522 	if (len == 40)
523 		return note;
524 
525 	hg_oidcpy2git(&git_oid, oid);
526 	return get_abbrev_note(&hg2git, &git_oid, len);
527 }
528 
do_hg2git(struct string_list * args)529 static void do_hg2git(struct string_list *args)
530 {
531         struct hg_object_id oid;
532 	const struct object_id *note;
533 	size_t sha1_len;
534 
535 	if (args->nr != 1)
536 		goto not_found;
537 
538 	sha1_len =  get_abbrev_sha1_hex(args->items[0].string, oid.hash);
539 	if (!sha1_len)
540 		goto not_found;
541 
542 	note = resolve_hg2git(&oid, sha1_len);
543 	if (note) {
544 		write_or_die(1, oid_to_hex(note), 40);
545 		write_or_die(1, "\n", 1);
546 		return;
547 	}
548 
549 not_found:
550 	write_or_die(1, NULL_NODE, 40);
551 	write_or_die(1, "\n", 1);
552 }
553 
554 /* The git storage for a mercurial manifest uses not-entirely valid file modes
555  * to keep the mercurial manifest data as git trees.
556  * While mercurial manifests are flat, the corresponding git tree uses
557  * sub-directories. The file sha1s are stored as git links (since they're not
558  * valid git sha1s), and the file modes are stored as extra bits in the git
559  * link file mode, that git normally ignores.
560  * - Symlinks are set to have a file mode of 0160000 (standard git link).
561  * - Executables are set to have a file mode of 0160755.
562  * - Regular files are set to have a file mode of 0160644.
563  */
564 
565 /* Return the mercurial manifest character corresponding to the given
566  * git file mode. */
hgattr(unsigned int mode)567 static const char *hgattr(unsigned int mode)
568 {
569 	if (S_ISGITLINK(mode)) {
570 		if ((mode & 0755) == 0755)
571 			return "x";
572 		else if ((mode & 0644) == 0644)
573 			return "";
574 		else if ((mode & 0777) == 0)
575 			return "l";
576 	}
577 	die("Unsupported mode %06o", mode);
578 }
579 
580 /* The git storage for a mercurial manifest used to be a commit with two
581  * directories at its root:
582  * - a git directory, matching the git tree in the git commit corresponding to
583  *   the mercurial changeset using the manifest.
584  * - a hg directory, containing the same file paths, but where all pointed
585  *   objects are commits (mode 160000 in the git tree) whose sha1 is actually
586  *   the mercurial sha1 for the corresponding mercurial file.
587  * Reconstructing the mercurial manifest required file paths, mercurial sha1
588  * for each file, and the corresponding attribute ("l" for symlinks, "x" for
589  * executables"). The hg directory alone was not enough for that, because it
590  * lacked the attribute information.
591  */
592 struct old_manifest_tree {
593 	struct object_id git;
594 	struct object_id hg;
595 };
596 
track_tree(struct tree * tree,struct object_list ** tree_list)597 static void track_tree(struct tree *tree, struct object_list **tree_list)
598 {
599 	if (tree_list) {
600 		object_list_insert(&tree->object, tree_list);
601 		tree->object.flags |= SEEN;
602 	}
603 }
604 
605 /* Fills a manifest_tree with the tree sha1s for the git/ and hg/
606  * subdirectories of the given (git) manifest tree. */
get_old_manifest_tree(struct tree * tree,struct old_manifest_tree * result,struct object_list ** tree_list)607 static int get_old_manifest_tree(struct tree *tree,
608                                  struct old_manifest_tree *result,
609                                  struct object_list **tree_list)
610 {
611 	struct tree_desc desc;
612 	struct name_entry entry;
613 
614 	track_tree(tree, tree_list);
615 
616 	/* If the tree is empty, return an empty tree for both git
617 	 * and hg. */
618 	if (!tree->size) {
619 		oidcpy(&result->git, &tree->object.oid);
620 		oidcpy(&result->hg, &tree->object.oid);
621 		return 0;
622 	}
623 
624 	init_tree_desc(&desc, tree->buffer, tree->size);
625 	/* The first entry in the manifest tree is the git subtree. */
626 	if (!tree_entry(&desc, &entry))
627 		goto not_found;
628 	if (strcmp(entry.path, "git"))
629 		goto not_found;
630 	oidcpy(&result->git, &entry.oid);
631 
632 	/* The second entry in the manifest tree is the hg subtree. */
633 	if (!tree_entry(&desc, &entry))
634 		goto not_found;
635 	if (strcmp(entry.path, "hg"))
636 		goto not_found;
637 	oidcpy(&result->hg, &entry.oid);
638 
639 	/* There shouldn't be any other entry. */
640 	if (tree_entry(&desc, &entry))
641 		goto not_found;
642 
643 	return 0;
644 
645 not_found:
646 	return -1;
647 }
648 
649 struct old_manifest_tree_state {
650 	struct tree *tree_git, *tree_hg;
651 	struct tree_desc desc_git, desc_hg;
652 };
653 
654 struct manifest_tree_state {
655 	struct tree *tree;
656 	struct tree_desc desc;
657 };
658 
manifest_tree_state_init(const struct object_id * tree_id,struct manifest_tree_state * result,struct object_list ** tree_list)659 static int manifest_tree_state_init(const struct object_id *tree_id,
660                                     struct manifest_tree_state *result,
661                                     struct object_list **tree_list)
662 {
663 	result->tree = parse_tree_indirect(tree_id);
664 	if (!result->tree)
665 		return -1;
666 	track_tree(result->tree, tree_list);
667 
668 	init_tree_desc(&result->desc, result->tree->buffer,
669 	               result->tree->size);
670 	return 0;
671 }
672 
673 struct merge_manifest_tree_state {
674 	struct manifest_tree_state state_a, state_b;
675 	struct name_entry entry_a, entry_b;
676 	struct strslice entry_a_path, entry_b_path;
677 	int cmp;
678 };
679 
680 struct merge_name_entry {
681 	struct name_entry *entry_a, *entry_b;
682 	struct strslice path;
683 };
684 
merge_manifest_tree_state_init(const struct object_id * tree_id_a,const struct object_id * tree_id_b,struct merge_manifest_tree_state * result,struct object_list ** tree_list)685 static int merge_manifest_tree_state_init(const struct object_id *tree_id_a,
686                                           const struct object_id *tree_id_b,
687                                           struct merge_manifest_tree_state *result,
688                                           struct object_list **tree_list)
689 {
690 	int ret;
691 	memset(result, 0, sizeof(*result));
692 	result->cmp = 0;
693 
694 	if (tree_id_a) {
695 		ret = manifest_tree_state_init(tree_id_a, &result->state_a, tree_list);
696 		if (ret)
697 			return ret;
698 	} else {
699 		result->entry_a_path = empty_strslice();
700 		result->cmp = 1;
701 	}
702 	if (tree_id_b) {
703 		return manifest_tree_state_init(tree_id_b, &result->state_b, tree_list);
704 	} else if (result->cmp == 0) {
705 		result->entry_b_path = empty_strslice();
706 		result->cmp = -1;
707 		return 0;
708 	}
709 	return 1;
710 }
711 
merge_tree_entry(struct merge_manifest_tree_state * state,struct merge_name_entry * entries)712 static int merge_tree_entry(struct merge_manifest_tree_state *state,
713                             struct merge_name_entry *entries)
714 {
715 	if (state->cmp <= 0) {
716 		if (tree_entry(&state->state_a.desc, &state->entry_a)) {
717 			state->entry_a_path = strslice_from_str(state->entry_a.path);
718 		} else {
719 			state->entry_a_path = empty_strslice();
720 		}
721 	}
722 	if (state->cmp >= 0) {
723 		if (tree_entry(&state->state_b.desc, &state->entry_b)) {
724 			state->entry_b_path = strslice_from_str(state->entry_b.path);
725 		} else {
726 			state->entry_b_path = empty_strslice();
727 		}
728 	}
729 	if (!state->entry_a_path.len) {
730 		if (!state->entry_b_path.len)
731 			return 0;
732 		state->cmp = 1;
733 	} else if (!state->entry_b_path.len) {
734 		state->cmp = -1;
735 	} else {
736 		state->cmp = base_name_compare(
737 			state->entry_a_path.buf, state->entry_a_path.len, state->entry_a.mode,
738 			state->entry_b_path.buf, state->entry_b_path.len, state->entry_b.mode);
739 	}
740 	if (state->cmp <= 0) {
741 		entries->entry_a = &state->entry_a;
742 		entries->path = state->entry_a_path;
743 	} else {
744 		entries->entry_a = NULL;
745 	}
746 	if (state->cmp >= 0) {
747 		entries->entry_b = &state->entry_b;
748 		entries->path = state->entry_b_path;
749 	} else {
750 		entries->entry_b = NULL;
751 	}
752 	return 1;
753 }
754 
old_manifest_tree_state_init(const struct old_manifest_tree * tree,struct old_manifest_tree_state * result,struct object_list ** tree_list)755 static int old_manifest_tree_state_init(const struct old_manifest_tree *tree,
756                                         struct old_manifest_tree_state *result,
757                                         struct object_list **tree_list)
758 {
759 	result->tree_git = parse_tree_indirect(&tree->git);
760 	if (!result->tree_git)
761 		return -1;
762 	track_tree(result->tree_git, tree_list);
763 
764 	result->tree_hg = parse_tree_indirect(&tree->hg);
765 	if (!result->tree_hg)
766 		return -1;
767 	track_tree(result->tree_hg, tree_list);
768 
769 	init_tree_desc(&result->desc_git, result->tree_git->buffer,
770 	               result->tree_git->size);
771 	init_tree_desc(&result->desc_hg, result->tree_hg->buffer,
772 	               result->tree_hg->size);
773 	return 0;
774 }
775 
776 struct old_manifest_entry {
777 	struct object_id oid;
778 	struct object_id other_oid;
779 	const char *path;
780 	unsigned int mode;
781 };
782 
783 /* Like tree_entry, returns true for success. */
old_manifest_tree_entry(struct old_manifest_tree_state * state,struct old_manifest_entry * result)784 static int old_manifest_tree_entry(struct old_manifest_tree_state *state,
785                                    struct old_manifest_entry *result)
786 {
787 	struct name_entry entry_git, entry_hg;
788 	int has_git_entry = tree_entry(&state->desc_git, &entry_git);
789 	int has_hg_entry = tree_entry(&state->desc_hg, &entry_hg);
790 	if (has_git_entry != has_hg_entry)
791 		goto corrupted;
792 	if (!has_git_entry) {
793 		result->path = NULL;
794 		return 0;
795 	}
796 
797 	oidcpy(&result->oid, &entry_hg.oid);
798 	result->path = entry_hg.path;
799 	result->mode = entry_git.mode;
800 	if (strcmp(entry_hg.path, entry_git.path))
801 		goto corrupted;
802 	if (S_ISDIR(entry_git.mode)) {
803 		if (entry_git.mode != entry_hg.mode)
804 			goto corrupted;
805 	}
806 	oidcpy(&result->other_oid, &entry_git.oid);
807 	return 1;
808 corrupted:
809 	die("Corrupted metadata");
810 }
811 
812 /* Return whether two entries have matching sha1s and modes */
manifest_entry_equal(const struct name_entry * e1,const struct name_entry * e2)813 static int manifest_entry_equal(const struct name_entry *e1,
814                                 const struct name_entry *e2)
815 {
816 	return (e1->mode == e2->mode) && (oidcmp(&e1->oid, &e2->oid) == 0);
817 }
818 
819 /* Return whether base + name matches path */
path_match(struct strslice base,struct strslice name,struct strslice path)820 static int path_match(struct strslice base, struct strslice name,
821                       struct strslice path)
822 {
823 	struct strslice slice;
824 
825 	if (!strslice_startswith(path, base) ||
826 	    !strslice_startswith(strslice_slice(path, base.len, SIZE_MAX),
827 	                         name))
828 		return 0;
829 
830 	slice = strslice_slice(path, name.len + base.len, 1);
831 	return slice.len == 1 && (slice.buf[0] == '\0' || slice.buf[0] == '/');
832 }
833 
recurse_manifest(const struct object_id * ref_tree_id,struct strslice ref_manifest,const struct object_id * tree_id,struct strbuf * manifest,struct strslice base,struct object_list ** tree_list)834 static void recurse_manifest(const struct object_id *ref_tree_id,
835                              struct strslice ref_manifest,
836                              const struct object_id *tree_id,
837                              struct strbuf *manifest, struct strslice base,
838                              struct object_list **tree_list)
839 {
840 	struct merge_manifest_tree_state state;
841 	struct merge_name_entry entries;
842 	struct strslice cursor;
843 	struct strslice underscore = { 1, "_" };
844 	struct strbuf dir = STRBUF_INIT;
845 
846 	if (merge_manifest_tree_state_init(ref_tree_id, tree_id, &state, tree_list))
847 		goto corrupted;
848 
849 	while (merge_tree_entry(&state, &entries)) {
850 		if (!strslice_startswith(entries.path, underscore))
851 			goto corrupted;
852 		cursor = ref_manifest;
853 		if (entries.entry_a) {
854 			size_t len = base.len + entries.path.len + 40;
855 			do {
856 				strslice_split_once(&ref_manifest, '\n');
857 			} while (S_ISDIR(entries.entry_a->mode) &&
858 			         (ref_manifest.len > len) &&
859 			         path_match(base, strslice_slice(
860 					entries.path, 1, SIZE_MAX), ref_manifest));
861 		}
862 		/* File/directory was removed, nothing to do */
863 		if (!entries.entry_b)
864 			continue;
865 		/* File/directory didn't change, copy from the reference
866 		 * manifest. */
867 		if (entries.entry_a && entries.entry_b &&
868 		    manifest_entry_equal(entries.entry_a, entries.entry_b)) {
869 			strbuf_add(manifest, cursor.buf,
870 			           cursor.len - ref_manifest.len);
871 			continue;
872 		}
873 		if (entries.entry_b && !S_ISDIR(entries.entry_b->mode)) {
874 			strbuf_addslice(manifest, base);
875 			strbuf_addslice(manifest, strslice_slice(
876 				entries.path, 1, SIZE_MAX));
877 			strbuf_addf(manifest, "%c%s%s\n", '\0',
878 			            oid_to_hex(&entries.entry_b->oid),
879 			            hgattr(entries.entry_b->mode));
880 			continue;
881 		}
882 
883 		strbuf_addslice(&dir, base);
884 		strbuf_addslice(&dir, strslice_slice(
885 			entries.path, 1, SIZE_MAX));
886 		strbuf_addch(&dir, '/');
887 		if (entries.entry_a && entries.entry_b &&
888                     S_ISDIR(entries.entry_a->mode)) {
889 			recurse_manifest(&entries.entry_a->oid, cursor,
890 				         &entries.entry_b->oid, manifest,
891 			                 strbuf_as_slice(&dir), tree_list);
892 		} else
893 			recurse_manifest(NULL, empty_strslice(),
894 			                 &entries.entry_b->oid, manifest,
895 			                 strbuf_as_slice(&dir), tree_list);
896 		strbuf_release(&dir);
897 	}
898 
899 	return;
900 corrupted:
901 	die("Corrupted metadata");
902 }
903 
904 struct manifest {
905 	struct object_id tree_id;
906 	struct strbuf content;
907 	struct object_list *tree_list;
908 };
909 
910 #define MANIFEST_INIT { { { 0, } }, STRBUF_INIT, NULL }
911 
912 /* For repositories with a lot of files, generating a manifest is a slow
913  * operation.
914  * In most cases, there are way less changes between changesets than there
915  * are files in the repository, so it is much faster to generate a manifest
916  * from a previously generated manifest, by applying the differences between
917  * the corresponding trees.
918  * Therefore, we always keep the last generated manifest.
919  */
920 static struct manifest generated_manifest = MANIFEST_INIT;
921 
922 /* The returned strbuf must not be released and/or freed. */
generate_manifest(const struct object_id * oid)923 struct strbuf *generate_manifest(const struct object_id *oid)
924 {
925 	struct strbuf content = STRBUF_INIT;
926 	struct object_list *tree_list = NULL;
927 
928 	/* We keep a list of all the trees we've seen while generating the
929 	 * previous manifest. Each tree is marked as SEEN at that time.
930 	 * Then, on the next manifest generation, we unmark them as SEEN,
931 	 * and the generation that follows will re-mark them if they are
932 	 * re-used. Trees that are not marked SEEN are subsequently freed.
933 	 */
934 	struct object_list *previous_list = generated_manifest.tree_list;
935 	while (previous_list) {
936 		previous_list->item->flags &= ~SEEN;
937 		previous_list = previous_list->next;
938 	}
939 
940 	if (oidcmp(&generated_manifest.tree_id, oid) == 0) {
941 		return &generated_manifest.content;
942 	}
943 
944 	if (generated_manifest.content.len) {
945 		struct strslice gm;
946 		gm = strbuf_slice(&generated_manifest.content, 0, SIZE_MAX);
947 		strbuf_grow(&content, generated_manifest.content.alloc - 1);
948 		recurse_manifest(&generated_manifest.tree_id, gm,
949 		                 oid, &content, empty_strslice(), &tree_list);
950 	} else {
951 		recurse_manifest(NULL, empty_strslice(), oid, &content,
952 		                 empty_strslice(), &tree_list);
953 	}
954 
955 	oidcpy(&generated_manifest.tree_id, oid);
956 	strbuf_swap(&content, &generated_manifest.content);
957 	strbuf_release(&content);
958 
959 	previous_list = generated_manifest.tree_list;
960 	generated_manifest.tree_list = tree_list;
961 
962 	while (previous_list) {
963 		struct object *obj = previous_list->item;
964 		struct object_list *elem = previous_list;
965 		previous_list = elem->next;
966 		free(elem);
967 		if (!(obj->flags & SEEN))
968 			free_tree_buffer((struct tree *)obj);
969 	}
970 	return &generated_manifest.content;
971 }
972 
do_manifest(struct string_list * args)973 static void do_manifest(struct string_list *args)
974 {
975 	struct hg_object_id hg_oid;
976 	struct object_id oid;
977 	const struct object_id *manifest_oid;
978 	struct strbuf *manifest = NULL;
979 	size_t sha1_len;
980 
981 	if (args->nr != 1)
982 		goto not_found;
983 
984 	if (!strncmp(args->items[0].string, "git:", 4)) {
985 		if (get_oid_hex(args->items[0].string + 4, &oid))
986 			goto not_found;
987 		manifest_oid = &oid;
988 	} else {
989 		sha1_len = get_abbrev_sha1_hex(args->items[0].string, hg_oid.hash);
990 		if (!sha1_len)
991 			goto not_found;
992 
993 		manifest_oid = resolve_hg2git(&hg_oid, sha1_len);
994 		if (!manifest_oid)
995 			goto not_found;
996 	}
997 
998 	manifest = generate_manifest(manifest_oid);
999 	if (!manifest)
1000 		goto not_found;
1001 
1002 	send_buffer(manifest);
1003 	return;
1004 
1005 not_found:
1006 	write_or_die(1, "0\n\n", 3);
1007 }
1008 
get_manifest_oid(const struct commit * commit,struct hg_object_id * oid)1009 static void get_manifest_oid(const struct commit *commit, struct hg_object_id *oid)
1010 {
1011 	const char *msg;
1012 	const char *hex_sha1;
1013 
1014 	msg = get_commit_buffer(commit, NULL);
1015 
1016 	hex_sha1 = strstr(msg, "\n\n") + 2;
1017 
1018 	if (get_sha1_hex(hex_sha1, oid->hash))
1019 		hg_oidclr(oid);
1020 
1021 	unuse_commit_buffer(commit, msg);
1022 }
1023 
hg_sha1(struct strbuf * data,const struct hg_object_id * parent1,const struct hg_object_id * parent2,struct hg_object_id * result)1024 static void hg_sha1(struct strbuf *data, const struct hg_object_id *parent1,
1025                     const struct hg_object_id *parent2, struct hg_object_id *result)
1026 {
1027 	git_SHA_CTX ctx;
1028 
1029 	if (!parent1)
1030 		parent1 = &hg_null_oid;
1031 	if (!parent2)
1032 		parent2 = &hg_null_oid;
1033 
1034 	git_SHA1_Init(&ctx);
1035 
1036 	if (hg_oidcmp(parent1, parent2) < 0) {
1037 		git_SHA1_Update(&ctx, parent1, 20);
1038 		git_SHA1_Update(&ctx, parent2, 20);
1039 	} else {
1040 		git_SHA1_Update(&ctx, parent2, 20);
1041 		git_SHA1_Update(&ctx, parent1, 20);
1042 	}
1043 
1044 	git_SHA1_Update(&ctx, data->buf, data->len);
1045 
1046 	git_SHA1_Final(result->hash, &ctx);
1047 }
1048 
check_manifest(const struct object_id * oid,struct hg_object_id * hg_oid)1049 int check_manifest(const struct object_id *oid,
1050                    struct hg_object_id *hg_oid)
1051 {
1052 	struct hg_object_id parent1, parent2, stored, computed;
1053 	const struct commit *manifest_commit;
1054 	struct strbuf *manifest;
1055 
1056 	manifest = generate_manifest(oid);
1057 	if (!manifest)
1058 		return 0;
1059 
1060 	manifest_commit = lookup_commit(the_repository, oid);
1061 	if (!manifest_commit)
1062 		return 0;
1063 
1064 	if (manifest_commit->parents) {
1065 		get_manifest_oid(manifest_commit->parents->item, &parent1);
1066 		if (manifest_commit->parents->next) {
1067 			get_manifest_oid(manifest_commit->parents->next->item,
1068 			                 &parent2);
1069 		} else
1070 			hg_oidclr(&parent2);
1071 	} else {
1072 		hg_oidclr(&parent1);
1073 		hg_oidclr(&parent2);
1074 	}
1075 
1076 	if (!hg_oid)
1077 		hg_oid = &computed;
1078 
1079 	hg_sha1(manifest, &parent1, &parent2, hg_oid);
1080 
1081 	get_manifest_oid(manifest_commit, &stored);
1082 
1083 	return hg_oideq(&stored, hg_oid);
1084 }
1085 
do_check_manifest(struct string_list * args)1086 static void do_check_manifest(struct string_list *args)
1087 {
1088 	struct hg_object_id hg_oid, stored;
1089 	struct object_id oid;
1090 	const struct object_id *manifest_oid;
1091 
1092 	if (args->nr != 1)
1093 		goto error;
1094 
1095 	if (!strncmp(args->items[0].string, "git:", 4)) {
1096 		if (get_oid_hex(args->items[0].string + 4, &oid))
1097 			goto error;
1098 		manifest_oid = &oid;
1099 	} else {
1100 		if (get_sha1_hex(args->items[0].string, hg_oid.hash))
1101 			goto error;
1102 
1103 		manifest_oid = resolve_hg2git(&hg_oid, 40);
1104 		if (!manifest_oid)
1105 			goto error;
1106 	}
1107 
1108 	if (!check_manifest(manifest_oid, &stored))
1109 		goto error;
1110 
1111 	if (manifest_oid != &oid && !hg_oideq(&stored, &hg_oid))
1112 		goto error;
1113 
1114 	write_or_die(1, "ok\n", 3);
1115 	return;
1116 error:
1117 	write_or_die(1, "error\n", 6);
1118 }
1119 
do_check_file(struct string_list * args)1120 static void do_check_file(struct string_list *args)
1121 {
1122 	struct hg_file file;
1123 	struct hg_object_id oid, parent1, parent2, result;
1124 
1125 	hg_file_init(&file);
1126 
1127 	if (args->nr < 1 || args->nr > 3)
1128 		goto error;
1129 
1130 	if (get_sha1_hex(args->items[0].string, oid.hash))
1131 		goto error;
1132 
1133 	if (args->nr > 1) {
1134 		if (get_sha1_hex(args->items[1].string, parent1.hash))
1135 			goto error;
1136 	} else
1137 		hg_oidclr(&parent1);
1138 
1139 	if (args->nr > 2) {
1140 		if (get_sha1_hex(args->items[2].string, parent2.hash))
1141 			goto error;
1142 	} else
1143 		hg_oidclr(&parent2);
1144 
1145 	hg_file_load(&file, &oid);
1146 
1147 	/* We do the quick and dirty thing here, for now.
1148 	 * See details in cinnabar.githg.FileFindParents._set_parents_fallback
1149 	 */
1150 	hg_sha1(&file.file, &parent1, &parent2, &result);
1151 	if (hg_oideq(&oid, &result))
1152 		goto ok;
1153 
1154 	hg_sha1(&file.file, &parent1, NULL, &result);
1155 	if (hg_oideq(&oid, &result))
1156 		goto ok;
1157 
1158 	hg_sha1(&file.file, &parent2, NULL, &result);
1159 	if (hg_oideq(&oid, &result))
1160 		goto ok;
1161 
1162 	hg_sha1(&file.file, &parent1, &parent1, &result);
1163 	if (hg_oideq(&oid, &result))
1164 		goto ok;
1165 
1166 	hg_sha1(&file.file, NULL, NULL, &result);
1167 	if (!hg_oideq(&oid, &result))
1168 		goto error;
1169 
1170 ok:
1171 	write_or_die(1, "ok\n", 3);
1172 	hg_file_release(&file);
1173 	return;
1174 
1175 error:
1176 	write_or_die(1, "error\n", 6);
1177 	hg_file_release(&file);
1178 }
1179 
do_version(struct string_list * args)1180 static void do_version(struct string_list *args)
1181 {
1182 	long int version;
1183 	struct strbuf version_s = STRBUF_INIT;
1184 
1185 	if (args->nr != 1)
1186 		exit(1);
1187 
1188 	version = strtol(args->items[0].string, NULL, 10);
1189 	if (version < 100)
1190 		version *= 100;
1191 
1192 	if (!version || version < MIN_CMD_VERSION || version > CMD_VERSION)
1193 		exit(128);
1194 
1195 	strbuf_add(&version_s, STRINGIFY(HELPER_HASH), sizeof(STRINGIFY(HELPER_HASH)) - 1);
1196 	if (version >= 3000)
1197 		strbuf_addf(&version_s, " " STRINGIFY(CMD_VERSION));
1198 	strbuf_addch(&version_s, '\n');
1199 	write_or_die(1, version_s.buf, version_s.len);
1200 	strbuf_release(&version_s);
1201 }
1202 
do_helpercaps(struct string_list * args)1203 static void do_helpercaps(struct string_list *args)
1204 {
1205 	struct strbuf caps = STRBUF_INIT;
1206 
1207 	if (args->nr != 0)
1208 		die("helpercaps takes no arguments");
1209 
1210 	if (mode & MODE_WIRE) {
1211 		char *resolved;
1212 		strbuf_addstr(&caps, "compression=UN,GZ");
1213 		resolved = which("bzip2");
1214 		if (resolved) {
1215 			free(resolved);
1216 			strbuf_addstr(&caps, ",BZ");
1217 		}
1218 		resolved = which("zstd");
1219 		if (resolved) {
1220 			free(resolved);
1221 			strbuf_addstr(&caps, ",ZS");
1222 		}
1223 	}
1224 
1225 	if (cinnabar_experiments & EXPERIMENT_STORE) {
1226 		if (caps.len)
1227 			strbuf_addch(&caps, '\n');
1228 		strbuf_addstr(&caps, "store=new");
1229 	}
1230 
1231 	send_buffer(&caps);
1232 	strbuf_release(&caps);
1233 }
1234 
string_list_as_oid_array(struct string_list * list,struct oid_array * array)1235 static void string_list_as_oid_array(struct string_list *list,
1236 				     struct oid_array *array)
1237 {
1238 	struct string_list_item *item;
1239 	for_each_string_list_item(item, list) {
1240 		struct object_id oid;
1241 		if (!get_oid_hex(item->string, &oid))
1242 			oid_array_append(array, &oid);
1243 	}
1244 }
1245 
do_known(struct hg_connection * conn,struct string_list * args)1246 static void do_known(struct hg_connection *conn, struct string_list *args)
1247 {
1248 	struct strbuf result = STRBUF_INIT;
1249 	struct oid_array nodes = OID_ARRAY_INIT;
1250 	string_list_as_oid_array(args, &nodes);
1251 	hg_known(conn, &result, &nodes);
1252 	send_buffer(&result);
1253 	oid_array_clear(&nodes);
1254 	strbuf_release(&result);
1255 }
1256 
do_listkeys(struct hg_connection * conn,struct string_list * args)1257 static void do_listkeys(struct hg_connection *conn, struct string_list *args)
1258 {
1259 	struct strbuf result = STRBUF_INIT;
1260 	if (args->nr != 1)
1261 		exit(1);
1262 
1263 	hg_listkeys(conn, &result, args->items[0].string);
1264 	send_buffer(&result);
1265 	strbuf_release(&result);
1266 }
1267 
arg_as_oid_array(char * nodes,struct oid_array * array)1268 static void arg_as_oid_array(char *nodes, struct oid_array *array)
1269 {
1270 	struct string_list list = STRING_LIST_INIT_NODUP;
1271 	string_list_split_in_place(&list, nodes, ',', -1);
1272 	string_list_as_oid_array(&list, array);
1273 	string_list_clear(&list, 0);
1274 }
1275 
do_getbundle(struct hg_connection * conn,struct string_list * args)1276 static void do_getbundle(struct hg_connection *conn, struct string_list *args)
1277 {
1278 	struct oid_array heads = OID_ARRAY_INIT;
1279 	struct oid_array common = OID_ARRAY_INIT;
1280 	const char *bundle2caps = NULL;
1281 
1282 	if (args->nr > 3)
1283 		exit(1);
1284 
1285 	if (args->nr > 0)
1286 		arg_as_oid_array(args->items[0].string, &heads);
1287 	if (args->nr > 1)
1288 		arg_as_oid_array(args->items[1].string, &common);
1289 	if (args->nr > 2)
1290 		bundle2caps = args->items[2].string;
1291 
1292 	hg_getbundle(conn, stdout, &heads, &common, bundle2caps);
1293 
1294 	oid_array_clear(&common);
1295 	oid_array_clear(&heads);
1296 }
1297 
do_unbundle(struct hg_connection * conn,struct string_list * args)1298 static void do_unbundle(struct hg_connection *conn, struct string_list *args)
1299 {
1300 	struct strbuf result = STRBUF_INIT;
1301 	struct oid_array heads = OID_ARRAY_INIT;
1302 	if (args->nr < 1)
1303 		exit(1);
1304 	if (args->nr != 1 || strcmp(args->items[0].string, "force"))
1305 		string_list_as_oid_array(args, &heads);
1306 	hg_unbundle(conn, &result, stdin, &heads);
1307 	send_buffer(&result);
1308 	oid_array_clear(&heads);
1309 	strbuf_release(&result);
1310 }
1311 
do_pushkey(struct hg_connection * conn,struct string_list * args)1312 static void do_pushkey(struct hg_connection *conn, struct string_list *args)
1313 {
1314 	struct strbuf result = STRBUF_INIT;
1315 
1316 	if (args->nr != 4)
1317 		exit(1);
1318 
1319 	hg_pushkey(conn, &result, args->items[0].string, args->items[1].string,
1320 		   args->items[2].string, args->items[3].string);
1321 	send_buffer(&result);
1322 	strbuf_release(&result);
1323 }
1324 
do_capable(struct hg_connection * conn,struct string_list * args)1325 static void do_capable(struct hg_connection *conn, struct string_list *args)
1326 {
1327 	struct strbuf result = STRBUF_INIT;
1328 	const char *result_str;
1329 
1330 	if (args->nr != 1)
1331 		exit(1);
1332 
1333 	result_str = hg_get_capability(conn, args->items[0].string);
1334 	if (result_str) {
1335 		strbuf_addstr(&result, result_str);
1336 		send_buffer(&result);
1337 	} else {
1338 		send_buffer(NULL);
1339 	}
1340 	strbuf_release(&result);
1341 }
1342 
do_state(struct hg_connection * conn,struct string_list * args)1343 static void do_state(struct hg_connection *conn, struct string_list *args)
1344 {
1345 	struct strbuf branchmap = STRBUF_INIT;
1346 	struct strbuf heads = STRBUF_INIT;
1347 	struct strbuf bookmarks = STRBUF_INIT;
1348 
1349 	if (args->nr != 0)
1350 		exit(1);
1351 
1352 	hg_get_repo_state(conn, &branchmap, &heads, &bookmarks);
1353 	send_buffer(&branchmap);
1354 	send_buffer(&heads);
1355 	send_buffer(&bookmarks);
1356 	strbuf_release(&branchmap);
1357 	strbuf_release(&heads);
1358 	strbuf_release(&bookmarks);
1359 }
1360 
do_lookup(struct hg_connection * conn,struct string_list * args)1361 static void do_lookup(struct hg_connection *conn, struct string_list *args)
1362 {
1363 	struct strbuf result = STRBUF_INIT;
1364 	if (args->nr != 1)
1365 		exit(1);
1366 
1367 	hg_lookup(conn, &result, args->items[0].string);
1368 	send_buffer(&result);
1369 	strbuf_release(&result);
1370 }
1371 
do_clonebundles(struct hg_connection * conn,struct string_list * args)1372 static void do_clonebundles(struct hg_connection *conn, struct string_list *args)
1373 {
1374 	struct strbuf result = STRBUF_INIT;
1375 	if (args->nr != 0)
1376 		exit(1);
1377 
1378 	hg_clonebundles(conn, &result);
1379 	send_buffer(&result);
1380 	strbuf_release(&result);
1381 }
1382 
do_cinnabarclone(struct hg_connection * conn,struct string_list * args)1383 static void do_cinnabarclone(struct hg_connection *conn, struct string_list *args)
1384 {
1385 	struct strbuf result = STRBUF_INIT;
1386 	if (args->nr != 0)
1387 		exit(1);
1388 
1389 	hg_cinnabarclone(conn, &result);
1390 	send_buffer(&result);
1391 	strbuf_release(&result);
1392 }
1393 
connected_loop(struct hg_connection * conn)1394 static void connected_loop(struct hg_connection *conn)
1395 {
1396 	struct strbuf buf = STRBUF_INIT;
1397 
1398 	while (strbuf_getline(&buf, stdin) != EOF) {
1399 		struct string_list args = STRING_LIST_INIT_NODUP;
1400 		const char *command;
1401 		record_command(&buf);
1402 		split_command(buf.buf, &command, &args);
1403 
1404 		if (!*command) {
1405 			string_list_clear(&args, 0);
1406 			break;
1407 		}
1408 		if (!strcmp("known", command))
1409 			do_known(conn, &args);
1410 		else if (!strcmp("listkeys", command))
1411 			do_listkeys(conn, &args);
1412 		else if (!strcmp("getbundle", command))
1413 			do_getbundle(conn, &args);
1414 		else if (!strcmp("unbundle", command))
1415 			do_unbundle(conn, &args);
1416 		else if (!strcmp("pushkey", command))
1417 			do_pushkey(conn, &args);
1418 		else if (!strcmp("capable", command))
1419 			do_capable(conn, &args);
1420 		else if (!strcmp("state", command))
1421 			do_state(conn, &args);
1422 		else if (!strcmp("lookup", command))
1423 			do_lookup(conn, &args);
1424 		else if (!strcmp("clonebundles", command))
1425 			do_clonebundles(conn, &args);
1426 		else if (!strcmp("cinnabarclone", command))
1427 			do_cinnabarclone(conn, &args);
1428 		else
1429 			die("Unknown command: \"%s\"", command);
1430 
1431 		string_list_clear(&args, 0);
1432 	}
1433 
1434 	strbuf_release(&buf);
1435 }
1436 
do_connect(struct string_list * args)1437 static void do_connect(struct string_list *args)
1438 {
1439 	const char *url;
1440 	struct hg_connection *conn;
1441 
1442 	if (args->nr != 1)
1443 		return;
1444 
1445 	url = args->items[0].string;
1446 
1447 	conn = hg_connect(url, 0);
1448 
1449 	// hg_connect either dies in case of connection failure,
1450 	// or returns NULL, in which case it has sent out a stream
1451 	// to stdout.
1452 	if (conn) {
1453 		write_or_die(1, "ok\n", 3);
1454 		connected_loop(conn);
1455 
1456 		hg_finish_connect(conn);
1457 	}
1458 }
1459 
add_each_head(const struct object_id * oid,void * data)1460 static int add_each_head(const struct object_id *oid, void *data)
1461 {
1462 	struct strbuf *buf = data;
1463 
1464 	strbuf_addstr(buf, oid_to_hex(oid));
1465 	strbuf_addch(buf, '\n');
1466 	return 0;
1467 }
1468 
do_heads(struct string_list * args)1469 static void do_heads(struct string_list *args)
1470 {
1471 	//XXX: Should use hg specific oid array.
1472         struct oid_array *heads = NULL;
1473         struct strbuf heads_buf = STRBUF_INIT;
1474 
1475         if (args->nr != 1)
1476                 die("heads needs 1 argument");
1477 
1478         if (!strcmp(args->items[0].string, "manifests")) {
1479                 heads = &manifest_heads;
1480         } else
1481                 die("Unknown kind: %s", args->items[0].string);
1482 
1483 	ensure_heads(heads);
1484 	oid_array_for_each_unique(heads, add_each_head, &heads_buf);
1485 	send_buffer(&heads_buf);
1486 	strbuf_release(&heads_buf);
1487 }
1488 
reset_heads(struct oid_array * heads)1489 static void reset_heads(struct oid_array *heads)
1490 {
1491 	oid_array_clear(heads);
1492 	// We don't want subsequent ensure_heads to refill the array,
1493 	// so mark it as sorted, which means it's initialized.
1494 	heads->sorted = 1;
1495 }
1496 
do_reset_heads(struct string_list * args)1497 static void do_reset_heads(struct string_list *args)
1498 {
1499         struct oid_array *heads = NULL;
1500 
1501         if (args->nr != 1)
1502                 die("reset-heads needs 1 argument");
1503 
1504         if (!strcmp(args->items[0].string, "manifests")) {
1505                 heads = &manifest_heads;
1506         } else
1507                 die("Unknown kind: %s", args->items[0].string);
1508 
1509 	ensure_heads(heads);
1510 	reset_heads(heads);
1511 }
1512 
1513 struct track_upgrade {
1514 	struct oidset set;
1515 	struct progress *progress;
1516 };
1517 
upgrade_files(const struct old_manifest_tree * tree,struct track_upgrade * track)1518 static void upgrade_files(const struct old_manifest_tree *tree,
1519                           struct track_upgrade *track)
1520 {
1521 	struct old_manifest_tree_state state;
1522 	struct old_manifest_entry entry;
1523 
1524 	state.tree_hg = lookup_tree(the_repository, &tree->hg);
1525 	if (!state.tree_hg)
1526 		goto corrupted;
1527 
1528 	if (state.tree_hg->object.flags & SEEN)
1529 		goto cleanup;
1530 
1531 	if (old_manifest_tree_state_init(tree, &state, NULL))
1532 		goto corrupted;
1533 
1534 	while (old_manifest_tree_entry(&state, &entry)) {
1535 		struct hg_object_id hg_oid;
1536 		struct object_id oid;
1537 		const struct object_id *note;
1538 		if (S_ISDIR(entry.mode)) {
1539 			struct old_manifest_tree subtree;
1540 			oidcpy(&subtree.git, &entry.other_oid);
1541 			oidcpy(&subtree.hg, &entry.oid);
1542 			upgrade_files(&subtree, track);
1543 			continue;
1544 		}
1545 
1546 		oidcpy(&oid, &entry.oid);
1547 		if (oidset_insert(&track->set, &oid))
1548 			continue;
1549 
1550 		oidcpy2hg(&hg_oid, &entry.oid);
1551 		note = get_note_hg(&hg2git, &hg_oid);
1552 		if (!note && !is_empty_hg_file(&hg_oid))
1553 			goto corrupted;
1554 		if (note && oidcmp(note, &entry.other_oid)) {
1555 			struct hg_file file;
1556 			struct strbuf buf = STRBUF_INIT;
1557 			unsigned long len;
1558 			enum object_type t;
1559 			char *content;
1560 			content = read_object_file_extended(
1561 				the_repository, note, &t, &len, 0);
1562 			strbuf_attach(&buf, content, len, len);
1563 			hg_file_init(&file);
1564 			hg_file_from_memory(&file, &hg_oid, &buf);
1565 			remove_note_hg(&hg2git, &hg_oid);
1566 			hg_file_store(&file, NULL);
1567 			hg_file_release(&file);
1568 			note = get_note_hg(&hg2git, &hg_oid);
1569 			if (oidcmp(note, &entry.other_oid))
1570 				goto corrupted;
1571 		}
1572 		display_progress(track->progress,
1573 		                 kh_size(&track->set.set));
1574 	}
1575 
1576 	free_tree_buffer(state.tree_git);
1577 cleanup:
1578 	state.tree_hg->object.flags |= SEEN;
1579 	free_tree_buffer(state.tree_hg);
1580 	return;
1581 corrupted:
1582 	die("Corrupted metadata");
1583 
1584 }
1585 
1586 static struct name_entry *
lazy_tree_entry_by_name(struct manifest_tree_state * state,const struct object_id * tree_id,const char * path)1587 lazy_tree_entry_by_name(struct manifest_tree_state *state,
1588                         const struct object_id *tree_id,
1589                         const char *path)
1590 {
1591 	int cmp;
1592 
1593 	if (!tree_id)
1594 		return NULL;
1595 
1596 	if (!state->tree) {
1597 		if (manifest_tree_state_init(tree_id, state, NULL))
1598 			return NULL;
1599 	}
1600 
1601 	while (state->desc.size &&
1602 	       (cmp = strcmp(state->desc.entry.path, path)) < 0)
1603 		update_tree_entry(&state->desc);
1604 
1605 	if (state->desc.size && cmp == 0)
1606 		return &state->desc.entry;
1607 
1608 	return NULL;
1609 }
1610 
1611 struct track_manifests_upgrade {
1612 	struct progress *progress;
1613 	struct oidset manifests;
1614 	struct hashmap tree_cache;
1615 	struct hashmap commit_cache;
1616 };
1617 
1618 struct old2new_manifest_tree {
1619 	struct hashmap_entry ent;
1620 	struct old_manifest_tree old_tree;
1621 	struct object_id new_tree;
1622 };
1623 
1624 struct oid_map_entry {
1625 	struct hashmap_entry ent;
1626 	struct object_id old_oid;
1627 	struct object_id new_oid;
1628 };
1629 
old2new_manifest_tree_cmp(const void * cmpdata,const struct hashmap_entry * e1,const struct hashmap_entry * e2,const void * keydata)1630 static int old2new_manifest_tree_cmp(const void *cmpdata, const struct hashmap_entry *e1,
1631                                      const struct hashmap_entry *e2, const void *keydata)
1632 {
1633 	const struct old2new_manifest_tree *entry1 =
1634 		container_of(e1, const struct old2new_manifest_tree, ent);
1635 	const struct old2new_manifest_tree *entry2 =
1636 		container_of(e2, const struct old2new_manifest_tree, ent);
1637 
1638 	return memcmp(&entry1->old_tree, &entry2->old_tree,
1639 	              sizeof(struct old_manifest_tree));
1640 }
1641 
oid_map_entry_cmp(const void * cmpdata,const struct hashmap_entry * e1,const struct hashmap_entry * e2,const void * keydata)1642 static int oid_map_entry_cmp(const void *cmpdata, const struct hashmap_entry *e1,
1643                              const struct hashmap_entry *e2, const void *keydata)
1644 {
1645 	const struct oid_map_entry *entry1 =
1646 		container_of(e1, const struct oid_map_entry, ent);
1647 	const struct oid_map_entry *entry2 =
1648 		container_of(e2, const struct oid_map_entry, ent);
1649 
1650 	return oidcmp(&entry1->old_oid, &entry2->old_oid);
1651 }
1652 
upgrade_manifest_tree_v1(const struct object_id * tree_id,const struct object_id * reference,struct object_id * result,struct hashmap * cache)1653 static void upgrade_manifest_tree_v1(const struct object_id *tree_id,
1654                                      const struct object_id *reference,
1655                                      struct object_id *result,
1656                                      struct hashmap *cache)
1657 {
1658 	struct oid_map_entry k, *old2new;
1659 
1660 	oidcpy(&k.old_oid, tree_id);
1661 	hashmap_entry_init(&k.ent, oidhash(&k.old_oid));
1662 	old2new = hashmap_get_entry(cache, &k, ent, NULL);
1663 	if (!old2new) {
1664 		struct strbuf tree_buf = STRBUF_INIT;
1665 		struct strbuf entry_buf = STRBUF_INIT;
1666 		struct tree_desc desc;
1667 		struct manifest_tree_state ref_state = { NULL, };
1668 		struct name_entry entry;
1669 		struct tree *tree = parse_tree_indirect(tree_id);
1670 
1671 		if (!tree)
1672 			die("Corrupted metadata");
1673 
1674 		init_tree_desc(&desc, tree->buffer, tree->size);
1675 
1676 		while (tree_entry(&desc, &entry)) {
1677 			strbuf_addf(&tree_buf, "%o _%s%c",
1678 			            entry.mode, entry.path, '\0');
1679 
1680 			if (S_ISDIR(entry.mode)) {
1681 				struct name_entry *ref_entry;
1682 				struct object_id new_subtree;
1683 				strbuf_addch(&entry_buf, '_');
1684 				strbuf_addstr(&entry_buf, entry.path);
1685 				ref_entry = lazy_tree_entry_by_name(
1686 					&ref_state, reference, entry_buf.buf);
1687 				strbuf_reset(&entry_buf);
1688 				upgrade_manifest_tree_v1(
1689 					&entry.oid,
1690 					ref_entry ? &ref_entry->oid : NULL,
1691 					&new_subtree, cache);
1692 				strbuf_add(&tree_buf, new_subtree.hash, 20);
1693 			} else {
1694 				strbuf_add(&tree_buf, entry.oid.hash, 20);
1695 			}
1696 		}
1697 
1698 		old2new = xmalloc(sizeof(k));
1699 		old2new->ent = k.ent;
1700 		oidcpy(&old2new->old_oid, &k.old_oid);
1701 		oidcpy(&old2new->new_oid, &k.old_oid);
1702 		store_git_tree(&tree_buf, reference, &old2new->new_oid);
1703 		strbuf_release(&tree_buf);
1704 		strbuf_release(&entry_buf);
1705 		hashmap_add(cache, &old2new->ent);
1706 
1707 		free_tree_buffer(tree);
1708 		if (ref_state.tree)
1709 			free_tree_buffer(ref_state.tree);
1710 	}
1711 	oidcpy(result, &old2new->new_oid);
1712 }
1713 
upgrade_manifest_tree(struct old_manifest_tree * tree,const struct object_id * reference,struct object_id * result,struct hashmap * cache)1714 static void upgrade_manifest_tree(struct old_manifest_tree *tree,
1715                                   const struct object_id *reference,
1716                                   struct object_id *result,
1717                                   struct hashmap *cache)
1718 {
1719 	struct old2new_manifest_tree k, *old2new;
1720 
1721 	hashmap_entry_init(&k.ent, memhash(tree, sizeof(*tree)));
1722 	k.old_tree = *tree;
1723 	old2new = hashmap_get_entry(cache, &k, ent, NULL);
1724 	if (!old2new) {
1725 		struct old_manifest_tree_state state;
1726 		struct old_manifest_entry entry;
1727 		struct manifest_tree_state ref_state = { NULL, };
1728 		struct strbuf tree_buf = STRBUF_INIT;
1729 		struct strbuf entry_buf = STRBUF_INIT;
1730 
1731 		if (old_manifest_tree_state_init(tree, &state, NULL))
1732 			die("Corrupted metadata");
1733 
1734 		while (old_manifest_tree_entry(&state, &entry)) {
1735 			struct object_id oid;
1736 			unsigned mode = entry.mode;
1737 			if (S_ISDIR(mode)) {
1738 				struct old_manifest_tree subtree;
1739 				struct name_entry *ref_entry;
1740 				strbuf_addch(&entry_buf, '_');
1741 				strbuf_addstr(&entry_buf, entry.path);
1742 				ref_entry = lazy_tree_entry_by_name(
1743 					&ref_state, reference, entry_buf.buf);
1744 				strbuf_reset(&entry_buf);
1745 				oidcpy(&subtree.git, &entry.other_oid);
1746 				oidcpy(&subtree.hg, &entry.oid);
1747 				upgrade_manifest_tree(
1748 					&subtree,
1749 					ref_entry ? &ref_entry->oid : NULL,
1750 					&oid, cache);
1751 			} else {
1752 				if (S_ISLNK(mode))
1753 					mode = S_IFGITLINK;
1754 				else
1755 					mode |= S_IFGITLINK;
1756 				oidcpy(&oid, &entry.oid);
1757 			}
1758 			strbuf_addf(&tree_buf, "%o _%s%c", mode, entry.path, '\0');
1759 			strbuf_add(&tree_buf, oid.hash, 20);
1760 		}
1761 
1762 		old2new = xmalloc(sizeof(k));
1763 		old2new->ent = k.ent;
1764 		old2new->old_tree = k.old_tree;
1765 		store_git_tree(&tree_buf, reference, &old2new->new_tree);
1766 		strbuf_release(&tree_buf);
1767 		strbuf_release(&entry_buf);
1768 		hashmap_add(cache, &old2new->ent);
1769 
1770 		free_tree_buffer(state.tree_git);
1771 		free_tree_buffer(state.tree_hg);
1772 		if (ref_state.tree)
1773 			free_tree_buffer(ref_state.tree);
1774 	}
1775 	oidcpy(result, &old2new->new_tree);
1776 }
1777 
upgrade_manifest(struct commit * commit,struct track_manifests_upgrade * track)1778 static void upgrade_manifest(struct commit *commit,
1779                              struct track_manifests_upgrade *track)
1780 {
1781 	struct object_id new_tree_id;
1782 	size_t size = 0;
1783 	unsigned long size_l = 0;
1784 	struct strbuf new_commit = STRBUF_INIT;
1785 	const char *buf;
1786 	char *cursor;
1787 	struct hg_object_id oid;
1788 	struct oid_map_entry *entry;
1789 	struct tree *tree;
1790 	struct object_id *ref_tree = NULL;
1791 
1792 	if (parse_commit(commit))
1793 		die("Corrupt mercurial metadata");
1794 
1795 	tree = get_commit_tree(commit);
1796 
1797 	if (parse_tree(tree))
1798 		die("Corrupt mercurial metadata");
1799 
1800 	if (commit->parents) {
1801 		struct oid_map_entry k;
1802 		struct commit *p;
1803 		oidcpy(&k.old_oid, &commit->parents->item->object.oid);
1804 		hashmap_entry_init(&k.ent, oidhash(&k.old_oid));
1805 		entry = hashmap_get_entry(&track->commit_cache, &k, ent, NULL);
1806 		if (!entry)
1807 			die("Something went wrong");
1808 		p = lookup_commit(the_repository, &entry->new_oid);
1809 		if (!p)
1810 			die("Something went wrong");
1811 		ref_tree = get_commit_tree_oid(p);
1812 	}
1813 
1814 	if (metadata_flags & UNIFIED_MANIFESTS) {
1815 		upgrade_manifest_tree_v1(&tree->object.oid, ref_tree,
1816 		                         &new_tree_id, &track->tree_cache);
1817 	} else {
1818 		struct old_manifest_tree manifest_tree;
1819 		if (get_old_manifest_tree(tree, &manifest_tree, NULL))
1820 			die("Corrupt mercurial metadata");
1821 
1822 		upgrade_manifest_tree(&manifest_tree, ref_tree, &new_tree_id,
1823 		                      &track->tree_cache);
1824 	}
1825 
1826 	buf = get_commit_buffer(commit, &size_l);
1827 	size = size_l;
1828 	strbuf_add(&new_commit, buf, size);
1829 	unuse_commit_buffer(commit, buf);
1830 
1831 	cursor = (char *)find_commit_header(new_commit.buf, "tree", &size);
1832 	oid_to_hex_r(cursor, &new_tree_id);
1833 	cursor[40] = '\n';
1834 
1835 	cursor = new_commit.buf;
1836 	while ((cursor = (char *)find_commit_header(cursor, "parent", &size))) {
1837 		struct oid_map_entry k;
1838 		if (get_oid_hex(cursor, &k.old_oid))
1839 			die("Invalid sha1");
1840 		hashmap_entry_init(&k.ent, oidhash(&k.old_oid));
1841 		entry = hashmap_get_entry(&track->commit_cache, &k, ent, NULL);
1842 		if (!entry)
1843 			die("Something went wrong");
1844 		oid_to_hex_r(cursor, &entry->new_oid);
1845 		cursor[40] = '\n';
1846 		cursor += 41;
1847 	}
1848 
1849 	entry = xmalloc(sizeof(*entry));
1850 	hashmap_entry_init(&entry->ent, oidhash(&commit->object.oid));
1851 	oidcpy(&entry->old_oid, &commit->object.oid);
1852 	store_git_commit(&new_commit, &entry->new_oid);
1853 	hashmap_add(&track->commit_cache, &entry->ent);
1854 	oidset_insert(&track->manifests, &entry->new_oid);
1855 
1856 	get_manifest_oid(commit, &oid);
1857 	add_note_hg(&hg2git, &oid, &entry->new_oid, combine_notes_overwrite);
1858 	add_head(&manifest_heads, &entry->new_oid);
1859 
1860 	strbuf_release(&new_commit);
1861 
1862 	display_progress(track->progress,
1863 	                 hashmap_get_size(&track->commit_cache));
1864 }
1865 
revs_add_each_head(const struct object_id * oid,void * data)1866 static int revs_add_each_head(const struct object_id *oid, void *data)
1867 {
1868 	struct rev_info *revs = data;
1869 
1870 	add_pending_oid(revs, oid_to_hex(oid), oid, 0);
1871 
1872 	return 0;
1873 }
1874 
1875 static struct commit *
resolve_manifest_for_upgrade(struct commit * commit,struct track_manifests_upgrade * track)1876 resolve_manifest_for_upgrade(struct commit *commit,
1877                              struct track_manifests_upgrade *track)
1878 {
1879 	const struct object_id *note;
1880 	char *buffer;
1881 	const char *manifest;
1882 	enum object_type type;
1883 	unsigned long size;
1884 	struct hg_object_id manifest_oid;
1885 	const struct object_id *git_manifest;
1886 
1887 	ensure_notes(&git2hg);
1888 	note = get_note(&git2hg, lookup_replace_object(the_repository, &commit->object.oid));
1889 	if (!note)
1890 		goto corrupted;
1891 
1892 	buffer = read_object_file(note, &type, &size);
1893 
1894 	if (!buffer || type != OBJ_BLOB)
1895 		goto corrupted;
1896 
1897 	manifest = strstr(buffer, "manifest ") + sizeof("manifest");
1898 	if (get_sha1_hex(manifest, manifest_oid.hash))
1899 		goto corrupted;
1900 
1901 	git_manifest = resolve_hg2git(&manifest_oid, 40);
1902 	if (!git_manifest)
1903 		goto corrupted;
1904 
1905 	free(buffer);
1906 
1907 	if (oidset_contains(&track->manifests, git_manifest))
1908 		return NULL;
1909 	return lookup_commit(the_repository, git_manifest);
1910 
1911 corrupted:
1912 	die("Corrupt mercurial metadata");
1913 }
1914 
do_upgrade(struct string_list * args)1915 static void do_upgrade(struct string_list *args)
1916 {
1917 	struct rev_info revs;
1918 	struct commit *commit;
1919 
1920         if (args->nr != 0)
1921                 die("upgrade takes no arguments");
1922 
1923 	ensure_notes(&hg2git);
1924 
1925 	init_revisions(&revs, NULL);
1926 
1927 	if (!(metadata_flags & FILES_META)) {
1928 		struct track_upgrade track = { OIDSET_INIT, NULL };
1929 		track.progress = start_progress("Upgrading files metadata", 0);
1930 
1931 		ensure_heads(&manifest_heads);
1932 		oid_array_for_each_unique(&manifest_heads, revs_add_each_head,
1933 		                          &revs);
1934 
1935 		if (prepare_revision_walk(&revs))
1936 			die("revision walk setup failed");
1937 
1938 		while ((commit = get_revision(&revs)) != NULL) {
1939 			struct tree *tree = get_commit_tree(commit);
1940 			if (parse_tree(tree))
1941 				die("Corrupt mercurial metadata");
1942 			struct old_manifest_tree manifest_tree;
1943 			if (get_old_manifest_tree(tree, &manifest_tree,
1944 			                          NULL))
1945 				die("Corrupt mercurial metadata");
1946 			upgrade_files(&manifest_tree, &track);
1947 		}
1948 		stop_progress(&track.progress);
1949 		oidset_clear(&track.set);
1950 		reset_revision_walk();
1951 	}
1952 
1953 	if (!(metadata_flags & UNIFIED_MANIFESTS_v2)) {
1954 		struct track_manifests_upgrade track = { NULL, OIDSET_INIT, };
1955 		track.progress = start_progress("Upgrading manifests metadata", 0);
1956 		if (metadata_flags & UNIFIED_MANIFESTS) {
1957 			hashmap_init(&track.tree_cache, oid_map_entry_cmp, NULL, 0);
1958 		} else {
1959 			hashmap_init(&track.tree_cache, old2new_manifest_tree_cmp, NULL, 0);
1960 		}
1961 		hashmap_init(&track.commit_cache, oid_map_entry_cmp, NULL, 0);
1962 
1963 		reset_heads(&manifest_heads);
1964 		// Normally, we'd operate on manifest_heads, but some might be
1965 		// missing for $reasons, and a partial upgrade would leave things
1966 		// in a very bad shape, so we use changeset_heads instead.
1967 		ensure_heads(&changeset_heads);
1968 		oid_array_for_each_unique(&changeset_heads,
1969 		                          revs_add_each_head, &revs);
1970 
1971 		revs.topo_order = 1;
1972 		revs.limited = 1;
1973 		revs.sort_order = REV_SORT_IN_GRAPH_ORDER;
1974 		revs.reverse = 1;
1975 
1976 		if (prepare_revision_walk(&revs))
1977 			die("revision walk setup failed");
1978 
1979 		while ((commit = get_revision(&revs)) != NULL) {
1980 			struct commit *manifest_commit;
1981 			manifest_commit = resolve_manifest_for_upgrade(commit,
1982 			                                               &track);
1983 			if (manifest_commit) {
1984 				upgrade_manifest(manifest_commit, &track);
1985 				free_tree_buffer(get_commit_tree(manifest_commit));
1986 			}
1987 		}
1988 		hashmap_clear_and_free(&track.commit_cache, struct oid_map_entry, ent);
1989 		hashmap_clear_and_free(&track.tree_cache, struct oid_map_entry, ent);
1990 		oidset_clear(&track.manifests);
1991 		stop_progress(&track.progress);
1992 	}
1993 
1994 	write_or_die(1, "ok\n", 3);
1995 	rev_info_release(&revs);
1996 }
1997 
recurse_create_git_tree(const struct object_id * tree_id,const struct object_id * reference,const struct object_id * merge_tree_id,struct object_id * result,struct hashmap * cache)1998 static void recurse_create_git_tree(const struct object_id *tree_id,
1999                                     const struct object_id *reference,
2000                                     const struct object_id *merge_tree_id,
2001                                     struct object_id *result,
2002 				    struct hashmap *cache)
2003 {
2004 	struct oid_map_entry k, *cache_entry = NULL;
2005 
2006 	if (!merge_tree_id) {
2007 		hashmap_entry_init(&k.ent, oidhash(tree_id));
2008 		oidcpy(&k.old_oid, tree_id);
2009 		cache_entry = hashmap_get_entry(cache, &k, ent, NULL);
2010 	}
2011 	if (!cache_entry) {
2012 		struct merge_manifest_tree_state state;
2013 		struct manifest_tree_state ref_state = { NULL, };
2014 		struct merge_name_entry entries;
2015 		struct strbuf tree_buf = STRBUF_INIT;
2016 
2017 		if (merge_manifest_tree_state_init(tree_id, merge_tree_id, &state, NULL))
2018 			goto corrupted;
2019 
2020 		while (merge_tree_entry(&state, &entries)) {
2021 			struct object_id oid;
2022 			struct name_entry *entry = entries.entry_a ? entries.entry_a : entries.entry_b;
2023 			unsigned mode = entry->mode;
2024 			struct strslice entry_path;
2025 			struct strslice underscore = { 1, "_" };
2026 			if (!strslice_startswith(entries.path, underscore))
2027 				goto corrupted;
2028 			entry_path = strslice_slice(entries.path, 1, SIZE_MAX);
2029 			// In some edge cases, presumably all related to the use of
2030 			// `hg convert` before Mercurial 2.0.1, manifest trees have
2031 			// double slashes, which end up as "_" directories in the
2032 			// corresponding git cinnabar metadata.
2033 			// With further changes in the subsequent Mercurial manifests,
2034 			// those entries with double slashes are superseded with entries
2035 			// with single slash, while still being there. So to create
2036 			// the corresponding git commit, we need to merge both in some
2037 			// manner.
2038 			// Mercurial doesn't actually guarantee which of the paths would
2039 			// actually be checked out when checking out such manifests,
2040 			// but we always choose the single slash path. Most of the time,
2041 			// though, both will have the same contents. At least for files.
2042 			// Sub-directories may differ in what paths they contain, but
2043 			// again, the files they contain are usually identical.
2044 			if (entry_path.len == 0) {
2045 				if (!S_ISDIR(mode))
2046 					goto corrupted;
2047 				if (merge_tree_id)
2048 					continue;
2049 				recurse_create_git_tree(
2050 					tree_id, reference, &entry->oid, result, cache);
2051 				goto cleanup;
2052 			} else if (S_ISDIR(mode)) {
2053 				struct name_entry *ref_entry;
2054 				ref_entry = lazy_tree_entry_by_name(
2055 					&ref_state, reference, entry_path.buf);
2056 				recurse_create_git_tree(
2057 					&entry->oid,
2058 					ref_entry ? &ref_entry->oid : NULL,
2059 					(entries.entry_b && S_ISDIR(entries.entry_b->mode))
2060 						? &entries.entry_b->oid : NULL,
2061 					&oid, cache);
2062 			} else {
2063 				const struct object_id *file_oid;
2064 				struct hg_object_id hg_oid;
2065 				oidcpy2hg(&hg_oid, &entry->oid);
2066 				if (is_empty_hg_file(&hg_oid))
2067 					file_oid = ensure_empty_blob();
2068 				else
2069 					file_oid = resolve_hg2git(&hg_oid, 40);
2070 				if (!file_oid)
2071 					goto corrupted;
2072 				oidcpy(&oid, file_oid);
2073 				mode &= 0777;
2074 				if (!mode)
2075 					mode = S_IFLNK;
2076 				else
2077 					mode = S_IFREG | mode;
2078 			}
2079 			strbuf_addf(&tree_buf, "%o ", canon_mode(mode));
2080 			strbuf_addslice(&tree_buf, entry_path);
2081 			strbuf_addch(&tree_buf, '\0');
2082 			strbuf_add(&tree_buf, oid.hash, 20);
2083 		}
2084 
2085 		if (!merge_tree_id) {
2086 			cache_entry = xmalloc(sizeof(k));
2087 			cache_entry->ent = k.ent;
2088 			cache_entry->old_oid = k.old_oid;
2089 		}
2090 		store_git_tree(&tree_buf, reference, cache_entry ? &cache_entry->new_oid : result);
2091 		strbuf_release(&tree_buf);
2092 		if (!merge_tree_id) {
2093 			hashmap_add(cache, &cache_entry->ent);
2094 		}
2095 
2096 cleanup:
2097 		if (state.state_a.tree)
2098 			free_tree_buffer(state.state_a.tree);
2099 		if (state.state_b.tree)
2100 			free_tree_buffer(state.state_b.tree);
2101 		if (ref_state.tree)
2102 			free_tree_buffer(ref_state.tree);
2103 	}
2104 	if (result && cache_entry)
2105 		oidcpy(result, &cache_entry->new_oid);
2106 	return;
2107 
2108 corrupted:
2109 	die("Corrupt mercurial metadata");
2110 }
2111 
2112 static struct hashmap git_tree_cache;
2113 
do_create_git_tree(struct string_list * args)2114 static void do_create_git_tree(struct string_list *args)
2115 {
2116 	struct hg_object_id hg_oid;
2117 	struct object_id oid;
2118 	const struct object_id *manifest_oid;
2119 	struct commit *commit;
2120 	struct object_id *ref_tree = NULL;
2121 
2122 	if (args->nr == 0 || args->nr > 2)
2123 		die("create-git-tree takes 1 or 2 arguments");
2124 
2125 	if (!strncmp(args->items[0].string, "git:", 4)) {
2126 		if (get_oid_hex(args->items[0].string + 4, &oid))
2127 			goto not_found;
2128 		manifest_oid = &oid;
2129 	} else {
2130 		if (get_sha1_hex(args->items[0].string, hg_oid.hash))
2131 			goto not_found;
2132 
2133 		manifest_oid = resolve_hg2git(&hg_oid, 40);
2134 		if (!manifest_oid)
2135 			goto not_found;
2136 	}
2137 
2138 	commit = lookup_commit(the_repository, manifest_oid);
2139 	if (parse_commit(commit))
2140 		goto not_found;
2141 
2142 	if (args->nr == 2) {
2143 		struct hg_object_id ref_oid;
2144 		const struct object_id *ref_commit_oid;
2145 		struct commit *ref_commit;
2146 		if (get_sha1_hex(args->items[1].string, ref_oid.hash))
2147 			die("invalid argument");
2148 		ref_commit_oid = resolve_hg2git(&ref_oid, 40);
2149 		if (!ref_commit_oid)
2150 			die("invalid argument");
2151 		ref_commit = lookup_commit(the_repository, ref_commit_oid);
2152 		parse_commit_or_die(ref_commit);
2153 		ref_tree = get_commit_tree_oid(ref_commit);
2154 	}
2155 
2156 	recurse_create_git_tree(get_commit_tree_oid(commit), ref_tree, NULL,
2157 	                        &oid, &git_tree_cache);
2158 
2159 	write_or_die(1, oid_to_hex(&oid), 40);
2160 	write_or_die(1, "\n", 1);
2161 	return;
2162 
2163 not_found:
2164 	die("Couldn't find manifest %s", args->items[0].string);
2165 }
2166 
2167 // 12th bit is only used by builtin/blame.c, so it should be safe to use.
2168 #define FSCK_SEEN (1 << 12)
2169 
do_seen(struct string_list * args)2170 static void do_seen(struct string_list *args)
2171 {
2172 	struct object_id oid;
2173 	int seen = 0;
2174 
2175 	if (args->nr != 2)
2176 		die("seen takes two argument");
2177 
2178 	if (get_oid_hex(args->items[1].string, &oid))
2179 		die("Invalid sha1");
2180 
2181 	if (!strcmp(args->items[0].string, "hg2git"))
2182 		seen = oidset_insert(&hg2git_seen, &oid);
2183 	else if (!strcmp(args->items[0].string, "git2hg")) {
2184 		struct commit *c = lookup_commit(the_repository, &oid);
2185 		if (!c)
2186 			die("Unknown commit");
2187 		seen = c->object.flags & FSCK_SEEN;
2188 		c->object.flags |= FSCK_SEEN;
2189 	}
2190 
2191 	if (seen)
2192 		write_or_die(1, "yes\n", 4);
2193 	else
2194 		write_or_die(1, "no\n", 3);
2195 }
2196 
2197 struct dangling_data {
2198 	struct notes_tree *notes;
2199 	struct strbuf *buf;
2200 	int exclude_blobs;
2201 };
2202 
dangling_note(const struct object_id * object_oid,const struct object_id * note_oid,char * note_path,void * cb_data)2203 static int dangling_note(const struct object_id *object_oid,
2204                          const struct object_id *note_oid, char *note_path,
2205                          void *cb_data)
2206 {
2207 	struct dangling_data *data = cb_data;
2208 	struct object_id oid;
2209 	int is_dangling = 0;
2210 
2211 	oidcpy(&oid, object_oid);
2212 	if (data->notes == &hg2git) {
2213 		if (!data->exclude_blobs ||
2214 		    (oid_object_info(the_repository, note_oid, NULL) != OBJ_BLOB))
2215 			is_dangling = !oidset_contains(&hg2git_seen, &oid);
2216 	} else if (data->notes == &git2hg) {
2217 		struct commit *c = lookup_commit(the_repository, &oid);
2218 		is_dangling = !c || !(c->object.flags & FSCK_SEEN);
2219 	}
2220 
2221 	if (is_dangling) {
2222 		strbuf_add(data->buf, oid_to_hex(&oid), 40);
2223 		strbuf_addch(data->buf, '\n');
2224 	}
2225 
2226 	return 0;
2227 }
2228 
do_dangling(struct string_list * args)2229 static void do_dangling(struct string_list *args)
2230 {
2231 	struct strbuf buf = STRBUF_INIT;
2232 	struct dangling_data data = { NULL, &buf, 0 };
2233 
2234         if (args->nr != 1)
2235                 die("dangling takes one argument");
2236 
2237 	if (!strcmp(args->items[0].string, "hg2git-no-blobs")) {
2238 		data.notes = &hg2git;
2239 		data.exclude_blobs = 1;
2240 	} else if (!strcmp(args->items[0].string, "hg2git")) {
2241 		data.notes = &hg2git;
2242 	} else if (!strcmp(args->items[0].string, "git2hg")) {
2243 		data.notes = &git2hg;
2244 	} else {
2245 		die("Unknown argument");
2246 	}
2247 
2248 	ensure_notes(data.notes);
2249 	for_each_note(data.notes, 0, dangling_note, &data);
2250 
2251 	send_buffer(&buf);
2252 	strbuf_release(&buf);
2253 }
2254 
init_config()2255 static void init_config()
2256 {
2257 	struct strbuf conf = STRBUF_INIT;
2258 	if (!config("check", &conf)) {
2259 		struct strbuf **check = strbuf_split(&conf, ',');
2260 		struct strbuf **c;
2261 		for (c = check; *c; c++) {
2262 			// strbuf_split leaves the `,`.
2263 			if ((*c)->buf[(*c) -> len - 1] == ',')
2264 				strbuf_setlen(*c, (*c)->len - 1);
2265 			if (!strcmp((*c)->buf, "true") ||
2266 			    !strcmp((*c)->buf, "all"))
2267 				cinnabar_check = -1;
2268 			else if (!strcmp((*c)->buf, "helper"))
2269 				cinnabar_check |= CHECK_HELPER;
2270 			else if (!strcmp((*c)->buf, "manifests"))
2271 				cinnabar_check |= CHECK_MANIFESTS;
2272 		}
2273 		strbuf_list_free(check);
2274 	}
2275 	strbuf_release(&conf);
2276 
2277 	if (!config("experiments", &conf)) {
2278 		struct strbuf **check = strbuf_split(&conf, ',');
2279 		struct strbuf **c;
2280 		for (c = check; *c; c++) {
2281 			// strbuf_split leaves the `,`.
2282 			if ((*c)->buf[(*c) -> len - 1] == ',')
2283 				strbuf_setlen(*c, (*c)->len - 1);
2284 			if (!strcmp((*c)->buf, "true") ||
2285 			    !strcmp((*c)->buf, "all"))
2286 				cinnabar_experiments = -1;
2287 			else if (!strcmp((*c)->buf, "store"))
2288 				cinnabar_experiments |= EXPERIMENT_STORE;
2289 		}
2290 		strbuf_list_free(check);
2291 	}
2292 	strbuf_release(&conf);
2293 }
2294 
reset_replace_map()2295 static void reset_replace_map()
2296 {
2297 	oidmap_free(the_repository->objects->replace_map, 1);
2298 	FREE_AND_NULL(the_repository->objects->replace_map);
2299 	the_repository->objects->replace_map_initialized = 0;
2300 }
2301 
init_metadata()2302 static void init_metadata()
2303 {
2304 	struct commit *c;
2305 	const char *msg, *body;
2306 	struct strbuf **flags, **f;
2307 	struct tree *tree;
2308 	struct tree_desc desc;
2309 	struct name_entry entry;
2310 	struct replace_object *replace;
2311 
2312 	c = lookup_commit_reference_by_name(METADATA_REF);
2313 	if (!c)
2314 		return;
2315 	msg = get_commit_buffer(c, NULL);
2316 	body = strstr(msg, "\n\n") + 2;
2317 	unuse_commit_buffer(c, msg);
2318 	flags = strbuf_split_str(body, ' ', -1);
2319 	for (f = flags; *f; f++) {
2320 		strbuf_trim(*f);
2321 		if (!strcmp("files-meta", (*f)->buf))
2322 			metadata_flags |= FILES_META;
2323 		else if (!strcmp("unified-manifests", (*f)->buf))
2324 			metadata_flags |= UNIFIED_MANIFESTS;
2325 		else if (!strcmp("unified-manifests-v2", (*f)->buf))
2326 			metadata_flags |= UNIFIED_MANIFESTS_v2;
2327 	}
2328 	strbuf_list_free(flags);
2329 
2330 	reset_replace_map();
2331 	the_repository->objects->replace_map =
2332 		xmalloc(sizeof(*the_repository->objects->replace_map));
2333 	oidmap_init(the_repository->objects->replace_map, 0);
2334 	the_repository->objects->replace_map_initialized = 1;
2335 
2336 	tree = get_commit_tree(c);
2337 	parse_tree(tree);
2338 	init_tree_desc(&desc, tree->buffer, tree->size);
2339 	while (tree_entry(&desc, &entry)) {
2340 		struct object_id original_oid;
2341 		if (entry.pathlen != 40 ||
2342 		    get_oid_hex(entry.path, &original_oid)) {
2343 			struct strbuf buf = STRBUF_INIT;
2344 			strbuf_add(&buf, entry.path, entry.pathlen);
2345 			warning(_("bad replace name: %s"), buf.buf);
2346 			strbuf_release(&buf);
2347 			continue;
2348 		}
2349 		if (oideq(&entry.oid, &original_oid)) {
2350 			warning(_("self-referencing graft: %s"),
2351 				oid_to_hex(&original_oid));
2352 			continue;
2353 		}
2354 		replace = xmalloc(sizeof(*replace));
2355 		oidcpy(&replace->original.oid, &original_oid);
2356 		oidcpy(&replace->replacement, &entry.oid);
2357 		if (oidmap_put(the_repository->objects->replace_map, replace))
2358 			die(_("duplicate replace: %s"),
2359 			    oid_to_hex(&replace->original.oid));
2360 	}
2361 }
2362 
2363 void dump_branches(void);
2364 
do_reload(struct string_list * args)2365 static void do_reload(struct string_list *args)
2366 {
2367         if (args->nr != 0)
2368                 die("reload takes no arguments");
2369 
2370 	if (notes_initialized(&git2hg))
2371 		free_notes(&git2hg);
2372 
2373 	if (notes_initialized(&hg2git))
2374 		free_notes(&hg2git);
2375 
2376 	if (notes_initialized(&files_meta))
2377 		free_notes(&files_meta);
2378 
2379 	oidset_clear(&hg2git_seen);
2380 
2381 	hashmap_clear_and_free(&git_tree_cache, struct oid_map_entry, ent);
2382 	hashmap_init(&git_tree_cache, oid_map_entry_cmp, NULL, 0);
2383 
2384 	oid_array_clear(&manifest_heads);
2385 	oid_array_clear(&changeset_heads);
2386 
2387 	dump_branches();
2388 
2389 	metadata_flags = 0;
2390 	reset_replace_map();
2391 	init_metadata();
2392 }
2393 
2394 int configset_add_value(struct config_set *, const char*, const char *);
2395 
config_set_callback(const char * key,const char * value,void * data)2396 static int config_set_callback(const char *key, const char *value, void *data)
2397 {
2398 	struct config_set *config = data;
2399 	configset_add_value(config, key, value);
2400 	return 0;
2401 }
2402 
init_git_config()2403 static void init_git_config()
2404 {
2405 	struct child_process proc = CHILD_PROCESS_INIT;
2406 	struct strbuf path = STRBUF_INIT;
2407 	const char *env = getenv(EXEC_PATH_ENVIRONMENT);
2408 	/* As the helper is not necessarily built with the same build options
2409 	 * as git (because it's built separately), the way its libgit.a is
2410 	 * going to find the system gitconfig may not match git's, and there
2411 	 * might be important configuration items there (like http.sslcainfo
2412 	 * on git for windows).
2413 	 * Trick git into giving us the path to it system gitconfig. */
2414 	const char *argv[] = {
2415 		"git", "config", "--system", "-e", NULL
2416 	};
2417 	if (env && *env) {
2418 		setup_path();
2419 	}
2420 	proc.argv = argv;
2421 	strvec_push(&proc.env_array, "GIT_EDITOR=echo");
2422 	proc.no_stdin = 1;
2423 	proc.no_stderr = 1;
2424 	/* We don't really care about the capture_command return value. If
2425 	 * the path we get is empty we'll know it failed. */
2426 	capture_command(&proc, &path, 0);
2427 	strbuf_trim_trailing_newline(&path);
2428 	/* Bail early when GIT_CONFIG_NO_SYSTEM is set. */
2429 	if (!git_config_system())
2430 		goto cleanup;
2431 
2432 	/* Avoid future uses of the git_config infrastructure reading the
2433          * config we just read (or the wrong system gitconfig). */
2434 	putenv("GIT_CONFIG_NOSYSTEM=1");
2435 
2436 	/* If we couldn't get a path, then so be it. We may just not have
2437 	 * a complete configuration. */
2438 	if (!path.len || access_or_die(path.buf, R_OK, 0))
2439 		goto cleanup;
2440 
2441 	if (the_repository->config)
2442 		// This shouldn't happen, but just in case...
2443 		git_configset_clear(the_repository->config);
2444 	else
2445 		the_repository->config = xcalloc(1, sizeof(struct config_set));
2446 
2447 	git_configset_init(the_repository->config);
2448 	git_configset_add_file(the_repository->config, path.buf);
2449 	read_early_config(config_set_callback, the_repository->config);
2450 
2451 cleanup:
2452 	strbuf_release(&path);
2453 }
2454 
restore_sigpipe_to_default(void)2455 static void restore_sigpipe_to_default(void)
2456 {
2457 	sigset_t unblock;
2458 
2459 	sigemptyset(&unblock);
2460 	sigaddset(&unblock, SIGPIPE);
2461 	sigprocmask(SIG_UNBLOCK, &unblock, NULL);
2462 	signal(SIGPIPE, SIG_DFL);
2463 }
2464 
main(int argc,const char * argv[])2465 int main(int argc, const char *argv[])
2466 {
2467 	int initialized = 0;
2468 	struct strbuf buf = STRBUF_INIT;
2469 
2470 	// Initialization from common-main.c.
2471 	trace2_initialize_clock();
2472 
2473 	sanitize_stdfds();
2474 	restore_sigpipe_to_default();
2475 
2476 	git_resolve_executable_dir(argv[0]);
2477 
2478 	git_setup_gettext();
2479 
2480 	initialize_the_repository();
2481 
2482 	attr_start();
2483 
2484 	trace2_initialize();
2485 	trace2_cmd_start(argv);
2486 	trace2_collect_process_info(TRACE2_PROCESS_INFO_STARTUP);
2487 
2488 	if (argc > 1) {
2489 		if (argc > 2)
2490 			die("Too many arguments");
2491 		if (!strcmp(argv[1], "--wire")) {
2492 			mode = MODE_WIRE;
2493 		} else if (!strcmp(argv[1], "--import")) {
2494 			mode = MODE_IMPORT;
2495 		}
2496 	}
2497 
2498 	init_git_config();
2499 	git_config(git_default_config, NULL);
2500 	init_config();
2501 	ignore_case = 0;
2502 	save_commit_buffer = 0;
2503 	warn_on_object_refname_ambiguity = 0;
2504 
2505 	while (strbuf_getline(&buf, stdin) != EOF) {
2506 		struct string_list args = STRING_LIST_INIT_NODUP;
2507 		const char *command;
2508 		record_command(&buf);
2509 		split_command(buf.buf, &command, &args);
2510 		if (!strcmp("version", command)) {
2511 			do_version(&args);
2512 			string_list_clear(&args, 0);
2513 			continue;
2514 		} else if (!strcmp("helpercaps", command)) {
2515 			do_helpercaps(&args);
2516 			string_list_clear(&args, 0);
2517 			continue;
2518 		} else if ((mode & MODE_WIRE) && !strcmp("connect", command)) {
2519 			do_connect(&args);
2520 			string_list_clear(&args, 0);
2521 			break;
2522 		}
2523 		if (!(mode & MODE_IMPORT))
2524 			die("Unknown command: \"%s\"", command);
2525 		if (!initialized) {
2526 			setup_git_directory();
2527 			git_config(git_diff_basic_config, NULL);
2528 			ignore_case = 0;
2529 			init_metadata();
2530 			initialized = 1;
2531 			hashmap_init(&git_tree_cache, oid_map_entry_cmp, NULL, 0);
2532 		}
2533 		if (!strcmp("git2hg", command))
2534 			do_get_note(&git2hg, &args);
2535 		else if (!strcmp("file-meta", command))
2536 			// XXX: Should use a different function that reads a hg oid.
2537 			do_get_note(&files_meta, &args);
2538 		else if (!strcmp("hg2git", command))
2539 			do_hg2git(&args);
2540 		else if (!strcmp("manifest", command))
2541 			do_manifest(&args);
2542 		else if (!strcmp("check-manifest", command))
2543 			do_check_manifest(&args);
2544 		else if (!strcmp("check-file", command))
2545 			do_check_file(&args);
2546 		else if (!strcmp("cat-file", command))
2547 			do_cat_file(&args);
2548 		else if (!strcmp("ls-tree", command))
2549 			do_ls_tree(&args);
2550 		else if (!strcmp("rev-list", command))
2551 			do_rev_list(&args);
2552 		else if (!strcmp("diff-tree", command))
2553 			do_diff_tree(&args);
2554 		else if (!strcmp("heads", command))
2555 			do_heads(&args);
2556 		else if (!strcmp("reset-heads", command))
2557 			do_reset_heads(&args);
2558 		else if (!strcmp("upgrade", command))
2559 			do_upgrade(&args);
2560 		else if (!strcmp("create-git-tree", command))
2561 			do_create_git_tree(&args);
2562 		else if (!strcmp("seen", command))
2563 			do_seen(&args);
2564 		else if (!strcmp("dangling", command))
2565 			do_dangling(&args);
2566 		else if (!strcmp("reload", command))
2567 			do_reload(&args);
2568 		else if (!maybe_handle_command(command, &args))
2569 			die("Unknown command: \"%s\"", command);
2570 
2571 		string_list_clear(&args, 0);
2572 	}
2573 
2574 	strbuf_release(&buf);
2575 
2576 	if (notes_initialized(&git2hg))
2577 		free_notes(&git2hg);
2578 
2579 	if (notes_initialized(&hg2git))
2580 		free_notes(&hg2git);
2581 
2582 	if (notes_initialized(&files_meta))
2583 		free_notes(&files_meta);
2584 
2585 	oidset_clear(&hg2git_seen);
2586 	hashmap_clear_and_free(&git_tree_cache, struct oid_map_entry, ent);
2587 	return 0;
2588 }
2589