X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=revision.c;h=ce70f48ce0880e8b43c3f62cd13bc185bfee8c4b;hb=d016a896d4a58a53dbb98cd85ebd033771413079;hp=f23c1d52269576917ac2d8347b322805daa1bac5;hpb=0a98f9d13802880a68ce6564b9f47b1c3e3341c7;p=git.git diff --git a/revision.c b/revision.c index f23c1d522..ce70f48ce 100644 --- a/revision.c +++ b/revision.c @@ -8,6 +8,7 @@ #include "revision.h" #include "grep.h" #include "reflog-walk.h" +#include "patch-ids.h" static char *path_name(struct name_path *path, const char *name) { @@ -422,6 +423,86 @@ static void add_parents_to_list(struct rev_info *revs, struct commit *commit, st } } +static void cherry_pick_list(struct commit_list *list) +{ + struct commit_list *p; + int left_count = 0, right_count = 0; + int left_first; + struct patch_ids ids; + + /* First count the commits on the left and on the right */ + for (p = list; p; p = p->next) { + struct commit *commit = p->item; + unsigned flags = commit->object.flags; + if (flags & BOUNDARY) + ; + else if (flags & SYMMETRIC_LEFT) + left_count++; + else + right_count++; + } + + left_first = left_count < right_count; + init_patch_ids(&ids); + + /* Compute patch-ids for one side */ + for (p = list; p; p = p->next) { + struct commit *commit = p->item; + unsigned flags = commit->object.flags; + + if (flags & BOUNDARY) + continue; + /* + * If we have fewer left, left_first is set and we omit + * commits on the right branch in this loop. If we have + * fewer right, we skip the left ones. + */ + if (left_first != !!(flags & SYMMETRIC_LEFT)) + continue; + commit->util = add_commit_patch_id(commit, &ids); + } + + /* Check the other side */ + for (p = list; p; p = p->next) { + struct commit *commit = p->item; + struct patch_id *id; + unsigned flags = commit->object.flags; + + if (flags & BOUNDARY) + continue; + /* + * If we have fewer left, left_first is set and we omit + * commits on the left branch in this loop. + */ + if (left_first == !!(flags & SYMMETRIC_LEFT)) + continue; + + /* + * Have we seen the same patch id? + */ + id = has_commit_patch_id(commit, &ids); + if (!id) + continue; + id->seen = 1; + commit->object.flags |= SHOWN; + } + + /* Now check the original side for seen ones */ + for (p = list; p; p = p->next) { + struct commit *commit = p->item; + struct patch_id *ent; + + ent = commit->util; + if (!ent) + continue; + if (ent->seen) + commit->object.flags |= SHOWN; + commit->util = NULL; + } + + free_patch_ids(&ids); +} + static void limit_list(struct rev_info *revs) { struct commit_list *list = revs->commits; @@ -449,6 +530,9 @@ static void limit_list(struct rev_info *revs) continue; p = &commit_list_insert(commit, p)->next; } + if (revs->cherry_pick) + cherry_pick_list(newlist); + revs->commits = newlist; } @@ -486,7 +570,7 @@ static void handle_one_reflog_commit(unsigned char *sha1, void *cb_data) add_pending_object(cb->all_revs, o, ""); } else if (!cb->warned_bad_reflog) { - warn("reflog of '%s' references pruned commits", + warning("reflog of '%s' references pruned commits", cb->name_for_errormsg); cb->warned_bad_reflog = 1; } @@ -567,6 +651,7 @@ void init_revisions(struct rev_info *revs, const char *prefix) revs->min_age = -1; revs->skip_count = -1; revs->max_count = -1; + revs->subject_prefix = "PATCH"; revs->prune_fn = NULL; revs->prune_data = NULL; @@ -913,6 +998,10 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch revs->left_right = 1; continue; } + if (!strcmp(arg, "--cherry-pick")) { + revs->cherry_pick = 1; + continue; + } if (!strcmp(arg, "--objects")) { revs->tag_objects = 1; revs->tree_objects = 1;