summaryrefslogtreecommitdiff
path: root/missing-revs.c
blob: afe41e33d488b41251f0bf483c8a8bf42a1f865c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include "cache.h"
#include "rev-cache.h"

static const char missing_revs_usage[] =
"git-missing-revs <rev-cache-file> <want-sha1>...";

#define REV_WANT 01
#define REV_HAVE 02

static void process(struct rev_cache *head_list)
{
	while (head_list) {
		struct rev_cache *rc = head_list;
		struct rev_list_elem *e;
		head_list = rc->head_list;
		rc->head_list = NULL;
		if (has_sha1_file(rc->sha1)) {
			rc->work |= REV_HAVE;
			continue;
		}
		if (rc->work & (REV_WANT|REV_HAVE))
			continue;
		rc->work |= REV_WANT;
		printf("%s\n", sha1_to_hex(rc->sha1));
		for (e = rc->parents; e; e = e->next) {
			if (e->ri->work & REV_HAVE)
				continue;
			e->ri->head_list = head_list;
			head_list = e->ri;
		}
	}
}

int main(int ac, char **av)
{
	const char *rev_cache_file;
	struct rev_cache *head_list = NULL;
	int i;

	if (ac < 3)
		usage(missing_revs_usage);
	rev_cache_file = av[1];
	read_rev_cache(rev_cache_file, NULL, 0);
	for (i = 2; i < ac; i++) {
		unsigned char sha1[20];
		int pos;
		struct rev_cache *rc;
		if (get_sha1_hex(av[i], sha1))
			die("%s: not an SHA1", av[i]);
		if ((pos = find_rev_cache(sha1)) < 0) {
			/* We could be asked for tags, which would not
			 * appear in the rev-cache.
			 */
			puts(av[i]);
			continue;
		}
		rc = rev_cache[pos];
		rc->head_list = head_list;
		head_list = rc;
	}
	process(head_list);
	return 0;
}