Merge branch 'rs/cherry'
* rs/cherry: Make git-cherry handle root trees Built-in cherry
This commit is contained in:
commit
56532fa147
4
Makefile
4
Makefile
@ -159,7 +159,7 @@ BASIC_LDFLAGS =
|
||||
|
||||
SCRIPT_SH = \
|
||||
git-bisect.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 \
|
||||
@ -212,7 +212,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))
|
||||
|
||||
|
113
builtin-log.c
113
builtin-log.c
@ -171,8 +171,11 @@ static void reopen_stdout(struct commit *commit, int nr, int keep_subject)
|
||||
static int get_patch_id(struct commit *commit, struct diff_options *options,
|
||||
unsigned char *sha1)
|
||||
{
|
||||
diff_tree_sha1(commit->parents->item->object.sha1, commit->object.sha1,
|
||||
"", options);
|
||||
if (commit->parents)
|
||||
diff_tree_sha1(commit->parents->item->object.sha1,
|
||||
commit->object.sha1, "", options);
|
||||
else
|
||||
diff_root_tree_sha1(commit->object.sha1, "", options);
|
||||
diffcore_std(options);
|
||||
return diff_flush_patch_id(options, sha1);
|
||||
}
|
||||
@ -437,3 +440,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;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ extern int cmd_branch(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);
|
||||
|
2
diff.h
2
diff.h
@ -102,6 +102,8 @@ extern int diff_tree(struct tree_desc *t1, struct tree_desc *t2,
|
||||
const char *base, struct diff_options *opt);
|
||||
extern int diff_tree_sha1(const unsigned char *old, const unsigned char *new,
|
||||
const char *base, struct diff_options *opt);
|
||||
extern int diff_root_tree_sha1(const unsigned char *new, const char *base,
|
||||
struct diff_options *opt);
|
||||
|
||||
struct combine_diff_path {
|
||||
struct combine_diff_path *next;
|
||||
|
1
git.c
1
git.c
@ -226,6 +226,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 },
|
||||
|
26
log-tree.c
26
log-tree.c
@ -252,26 +252,6 @@ int log_tree_diff_flush(struct rev_info *opt)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int diff_root_tree(struct rev_info *opt,
|
||||
const unsigned char *new, const char *base)
|
||||
{
|
||||
int retval;
|
||||
void *tree;
|
||||
struct tree_desc empty, real;
|
||||
|
||||
tree = read_object_with_reference(new, tree_type, &real.size, NULL);
|
||||
if (!tree)
|
||||
die("unable to read root tree (%s)", sha1_to_hex(new));
|
||||
real.buf = tree;
|
||||
|
||||
empty.buf = "";
|
||||
empty.size = 0;
|
||||
retval = diff_tree(&empty, &real, base, &opt->diffopt);
|
||||
free(tree);
|
||||
log_tree_diff_flush(opt);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int do_diff_combined(struct rev_info *opt, struct commit *commit)
|
||||
{
|
||||
unsigned const char *sha1 = commit->object.sha1;
|
||||
@ -297,8 +277,10 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log
|
||||
/* Root commit? */
|
||||
parents = commit->parents;
|
||||
if (!parents) {
|
||||
if (opt->show_root_diff)
|
||||
diff_root_tree(opt, sha1, "");
|
||||
if (opt->show_root_diff) {
|
||||
diff_root_tree_sha1(sha1, "", &opt->diffopt);
|
||||
log_tree_diff_flush(opt);
|
||||
}
|
||||
return !opt->loginfo;
|
||||
}
|
||||
|
||||
|
18
tree-diff.c
18
tree-diff.c
@ -215,6 +215,24 @@ int diff_tree_sha1(const unsigned char *old, const unsigned char *new, const cha
|
||||
return retval;
|
||||
}
|
||||
|
||||
int diff_root_tree_sha1(const unsigned char *new, const char *base, struct diff_options *opt)
|
||||
{
|
||||
int retval;
|
||||
void *tree;
|
||||
struct tree_desc empty, real;
|
||||
|
||||
tree = read_object_with_reference(new, tree_type, &real.size, NULL);
|
||||
if (!tree)
|
||||
die("unable to read root tree (%s)", sha1_to_hex(new));
|
||||
real.buf = tree;
|
||||
|
||||
empty.size = 0;
|
||||
empty.buf = "";
|
||||
retval = diff_tree(&empty, &real, base, opt);
|
||||
free(tree);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int count_paths(const char **paths)
|
||||
{
|
||||
int i = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user