git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
blob 4efd324d5d95c667bcd286ee828b8c2eb80a67ef 2811 bytes (raw)
name: builtin/ahead-behind.c 	 # note: path name is non-authoritative(*)

  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
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
 
#include "builtin.h"
#include "parse-options.h"
#include "config.h"
#include "commit.h"
#include "commit-reach.h"

static const char * const ahead_behind_usage[] = {
	N_("git ahead-behind --base=<ref> [ --contains ] [ --stdin | <revs> ]"),
	NULL
};

static int ignore_missing;

static int handle_arg(struct string_list *tips, const char *arg)
{
	struct string_list_item *item;
	struct commit *c = lookup_commit_reference_by_name(arg);

	if (!c) {
		if (ignore_missing)
			return 0;
		return error(_("could not resolve '%s'"), arg);
	}

	item = string_list_append(tips, arg);
	item->util = c;
	return 0;
}

int cmd_ahead_behind(int argc, const char **argv, const char *prefix)
{
	const char *base_ref = NULL;
	struct commit *base;
	int from_stdin = 0, contains = 0;
	struct string_list tips = STRING_LIST_INIT_DUP;
	struct commit **commits;
	struct ahead_behind_count *counts;
	size_t i;

	struct option ahead_behind_opts[] = {
		OPT_STRING('b', "base", &base_ref, N_("base"), N_("base reference to process")),
		OPT_BOOL(0 , "stdin", &from_stdin, N_("read rev names from stdin")),
		OPT_BOOL(0 , "ignore-missing", &ignore_missing, N_("ignore missing tip references")),
		OPT_BOOL(0 , "contains", &contains, N_("only check that tips are reachable from the base")),
		OPT_END()
	};

	argc = parse_options(argc, argv, NULL, ahead_behind_opts,
			     ahead_behind_usage, PARSE_OPT_KEEP_UNKNOWN_OPT);

	if (!base_ref)
		usage_with_options(ahead_behind_usage, ahead_behind_opts);

	git_config(git_default_config, NULL);

	base = lookup_commit_reference_by_name(base_ref);
	if (!base)
		die(_("could not resolve '%s'"), base_ref);

	if (from_stdin) {
		struct strbuf line = STRBUF_INIT;

		while (strbuf_getline(&line, stdin) != EOF) {
			if (!line.len)
				break;

			if (handle_arg(&tips, line.buf))
				return 1;
		}

		strbuf_release(&line);
	} else {
		int i;
		for (i = 0; i < argc; ++i) {
			if (handle_arg(&tips, argv[i]))
				return 1;
		}
	}

	/* Early return for no tips. */
	if (!tips.nr)
		return 0;

	if (contains) {
		struct string_list_item *item;

		/* clear out */
		for_each_string_list_item(item, &tips)
			item->util = NULL;

		tips_reachable_from_base(base, &tips);

		for_each_string_list_item(item, &tips) {
			if (item->util)
				printf("%s\n", item->string);
		}

		return 0;
	}
	/* else: not --contains, but normal ahead-behind counting. */

	ALLOC_ARRAY(commits, tips.nr + 1);
	ALLOC_ARRAY(counts, tips.nr);

	for (i = 0; i < tips.nr; i++) {
		commits[i] = tips.items[i].util;
		counts[i].tip_index = i;
		counts[i].base_index = tips.nr;
	}
	commits[tips.nr] = base;

	ahead_behind(commits, tips.nr + 1, counts, tips.nr);

	for (i = 0; i < tips.nr; i++)
		printf("%s %d %d\n", tips.items[i].string,
		       counts[i].ahead, counts[i].behind);

	free(counts);
	free(commits);
	return 0;
}

debug log:

solving 4efd324d5d9 ...
found 4efd324d5d9 in https://public-inbox.org/git/07eb2cbb699c875e5fdca86d675c97d4d434f511.1678111599.git.gitgitgadget@gmail.com/
found c06b95b5f37 in https://public-inbox.org/git/b8c55ecf88d6229f13e05e8369adaf9e70ae1de0.1678111599.git.gitgitgadget@gmail.com/
found e4f65fc0548 in https://public-inbox.org/git/b1d022c7cac5aed6e2d64b45f20dba5b3297536c.1678111599.git.gitgitgadget@gmail.com/
found c1212cc8d46 in https://public-inbox.org/git/08fc0710017d4b6178a8c5772e0f15fc69c84ad6.1678111599.git.gitgitgadget@gmail.com/
found a56cc565def in https://public-inbox.org/git/0fd18b6d740f1e8a6f62a25947bc3ad49c2674a6.1678111599.git.gitgitgadget@gmail.com/

applying [1/5] https://public-inbox.org/git/0fd18b6d740f1e8a6f62a25947bc3ad49c2674a6.1678111599.git.gitgitgadget@gmail.com/
diff --git a/builtin/ahead-behind.c b/builtin/ahead-behind.c
new file mode 100644
index 00000000000..a56cc565def


applying [2/5] https://public-inbox.org/git/08fc0710017d4b6178a8c5772e0f15fc69c84ad6.1678111599.git.gitgitgadget@gmail.com/
diff --git a/builtin/ahead-behind.c b/builtin/ahead-behind.c
index a56cc565def..c1212cc8d46 100644


applying [3/5] https://public-inbox.org/git/b1d022c7cac5aed6e2d64b45f20dba5b3297536c.1678111599.git.gitgitgadget@gmail.com/
diff --git a/builtin/ahead-behind.c b/builtin/ahead-behind.c
index c1212cc8d46..e4f65fc0548 100644


applying [4/5] https://public-inbox.org/git/b8c55ecf88d6229f13e05e8369adaf9e70ae1de0.1678111599.git.gitgitgadget@gmail.com/
diff --git a/builtin/ahead-behind.c b/builtin/ahead-behind.c
index e4f65fc0548..c06b95b5f37 100644


applying [5/5] https://public-inbox.org/git/07eb2cbb699c875e5fdca86d675c97d4d434f511.1678111599.git.gitgitgadget@gmail.com/
diff --git a/builtin/ahead-behind.c b/builtin/ahead-behind.c
index c06b95b5f37..4efd324d5d9 100644

Checking patch builtin/ahead-behind.c...
Applied patch builtin/ahead-behind.c cleanly.
Checking patch builtin/ahead-behind.c...
Applied patch builtin/ahead-behind.c cleanly.
Checking patch builtin/ahead-behind.c...
Applied patch builtin/ahead-behind.c cleanly.
Checking patch builtin/ahead-behind.c...
Applied patch builtin/ahead-behind.c cleanly.
Checking patch builtin/ahead-behind.c...
Applied patch builtin/ahead-behind.c cleanly.

index at:
100644 4efd324d5d95c667bcd286ee828b8c2eb80a67ef	builtin/ahead-behind.c

(*) Git path names are given by the tree(s) the blob belongs to.
    Blobs themselves have no identifier aside from the hash of its contents.^

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).