Skip to content

Commit

Permalink
Built-in cherry
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Rene Scharfe authored and Junio C Hamano committed Oct 24, 2006
1 parent 1259404 commit e827633
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 93 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ BASIC_LDFLAGS =

SCRIPT_SH = \
git-bisect.sh git-branch.sh git-checkout.sh \
git-cherry.sh git-clean.sh git-clone.sh git-commit.sh \
git-clean.sh git-clone.sh git-commit.sh \
git-fetch.sh \
git-ls-remote.sh \
git-merge-one-file.sh git-parse-remote.sh \
Expand Down Expand Up @@ -210,7 +210,7 @@ PROGRAMS = \
EXTRA_PROGRAMS =

BUILT_INS = \
git-format-patch$X git-show$X git-whatchanged$X \
git-format-patch$X git-show$X git-whatchanged$X git-cherry$X \
git-get-tar-commit-id$X \
$(patsubst builtin-%.o,git-%$X,$(BUILTIN_OBJS))

Expand Down
106 changes: 106 additions & 0 deletions builtin-log.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
1 change: 1 addition & 0 deletions builtin.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ extern int cmd_archive(int argc, const char **argv, const char *prefix);
extern int cmd_cat_file(int argc, const char **argv, const char *prefix);
extern int cmd_checkout_index(int argc, const char **argv, const char *prefix);
extern int cmd_check_ref_format(int argc, const char **argv, const char *prefix);
extern int cmd_cherry(int argc, const char **argv, const char *prefix);
extern int cmd_commit_tree(int argc, const char **argv, const char *prefix);
extern int cmd_count_objects(int argc, const char **argv, const char *prefix);
extern int cmd_diff_files(int argc, const char **argv, const char *prefix);
Expand Down
91 changes: 0 additions & 91 deletions git-cherry.sh

This file was deleted.

1 change: 1 addition & 0 deletions git.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
{ "cat-file", cmd_cat_file, RUN_SETUP },
{ "checkout-index", cmd_checkout_index, RUN_SETUP },
{ "check-ref-format", cmd_check_ref_format },
{ "cherry", cmd_cherry, RUN_SETUP },
{ "commit-tree", cmd_commit_tree, RUN_SETUP },
{ "count-objects", cmd_count_objects, RUN_SETUP },
{ "diff", cmd_diff, RUN_SETUP | USE_PAGER },
Expand Down

0 comments on commit e827633

Please sign in to comment.