Built-in cherry
This replaces the shell script git-cherry with a version written in C. The behaviour of the new version differs from the original in two points: it has no long help any more, and it is handling the (optional) third parameter a bit differently. Basically, it does the equivalent of ours=`git-rev-list $ours ^$limit ^$upstream` instead of ours=`git-rev-list $ours ^$limit` Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:

committed by
Junio C Hamano

parent
1259404c7e
commit
e827633a5d
106
builtin-log.c
106
builtin-log.c
@ -437,3 +437,109 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_pending_commit(const char *arg, struct rev_info *revs, int flags)
|
||||
{
|
||||
unsigned char sha1[20];
|
||||
if (get_sha1(arg, sha1) == 0) {
|
||||
struct commit *commit = lookup_commit_reference(sha1);
|
||||
if (commit) {
|
||||
commit->object.flags |= flags;
|
||||
add_pending_object(revs, &commit->object, arg);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char cherry_usage[] =
|
||||
"git-cherry [-v] <upstream> [<head>] [<limit>]";
|
||||
int cmd_cherry(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
struct rev_info revs;
|
||||
struct diff_options patch_id_opts;
|
||||
struct commit *commit;
|
||||
struct commit_list *list = NULL;
|
||||
const char *upstream;
|
||||
const char *head = "HEAD";
|
||||
const char *limit = NULL;
|
||||
int verbose = 0;
|
||||
|
||||
if (argc > 1 && !strcmp(argv[1], "-v")) {
|
||||
verbose = 1;
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
switch (argc) {
|
||||
case 4:
|
||||
limit = argv[3];
|
||||
/* FALLTHROUGH */
|
||||
case 3:
|
||||
head = argv[2];
|
||||
/* FALLTHROUGH */
|
||||
case 2:
|
||||
upstream = argv[1];
|
||||
break;
|
||||
default:
|
||||
usage(cherry_usage);
|
||||
}
|
||||
|
||||
init_revisions(&revs, prefix);
|
||||
revs.diff = 1;
|
||||
revs.combine_merges = 0;
|
||||
revs.ignore_merges = 1;
|
||||
revs.diffopt.recursive = 1;
|
||||
|
||||
if (add_pending_commit(head, &revs, 0))
|
||||
die("Unknown commit %s", head);
|
||||
if (add_pending_commit(upstream, &revs, UNINTERESTING))
|
||||
die("Unknown commit %s", upstream);
|
||||
|
||||
/* Don't say anything if head and upstream are the same. */
|
||||
if (revs.pending.nr == 2) {
|
||||
struct object_array_entry *o = revs.pending.objects;
|
||||
if (hashcmp(o[0].item->sha1, o[1].item->sha1) == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
get_patch_ids(&revs, &patch_id_opts, prefix);
|
||||
|
||||
if (limit && add_pending_commit(limit, &revs, UNINTERESTING))
|
||||
die("Unknown commit %s", limit);
|
||||
|
||||
/* reverse the list of commits */
|
||||
prepare_revision_walk(&revs);
|
||||
while ((commit = get_revision(&revs)) != NULL) {
|
||||
/* ignore merges */
|
||||
if (commit->parents && commit->parents->next)
|
||||
continue;
|
||||
|
||||
commit_list_insert(commit, &list);
|
||||
}
|
||||
|
||||
while (list) {
|
||||
unsigned char sha1[20];
|
||||
char sign = '+';
|
||||
|
||||
commit = list->item;
|
||||
if (!get_patch_id(commit, &patch_id_opts, sha1) &&
|
||||
lookup_object(sha1))
|
||||
sign = '-';
|
||||
|
||||
if (verbose) {
|
||||
static char buf[16384];
|
||||
pretty_print_commit(CMIT_FMT_ONELINE, commit, ~0,
|
||||
buf, sizeof(buf), 0, NULL, NULL, 0);
|
||||
printf("%c %s %s\n", sign,
|
||||
sha1_to_hex(commit->object.sha1), buf);
|
||||
}
|
||||
else {
|
||||
printf("%c %s\n", sign,
|
||||
sha1_to_hex(commit->object.sha1));
|
||||
}
|
||||
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user