int left_count = 0, right_count = 0;
int left_first;
struct patch_ids ids;
+ unsigned cherry_flag;
/* First count the commits on the left and on the right */
for (p = list; p; p = p->next) {
commit->util = add_commit_patch_id(commit, &ids);
}
+ /* either cherry_mark or cherry_pick are true */
+ cherry_flag = revs->cherry_mark ? PATCHSAME : SHOWN;
+
/* Check the other side */
for (p = list; p; p = p->next) {
struct commit *commit = p->item;
if (!id)
continue;
id->seen = 1;
- commit->object.flags |= SHOWN;
+ commit->object.flags |= cherry_flag;
}
/* Now check the original side for seen ones */
if (!ent)
continue;
if (ent->seen)
- commit->object.flags |= SHOWN;
+ commit->object.flags |= cherry_flag;
commit->util = NULL;
}
return bottom;
}
+/* Assumes either left_only or right_only is set */
+static void limit_left_right(struct commit_list *list, struct rev_info *revs)
+{
+ struct commit_list *p;
+
+ for (p = list; p; p = p->next) {
+ struct commit *commit = p->item;
+
+ if (revs->right_only) {
+ if (commit->object.flags & SYMMETRIC_LEFT)
+ commit->object.flags |= SHOWN;
+ } else /* revs->left_only is set */
+ if (!(commit->object.flags & SYMMETRIC_LEFT))
+ commit->object.flags |= SHOWN;
+ }
+}
+
static int limit_list(struct rev_info *revs)
{
int slop = SLOP;
show(revs, newlist);
show_early_output = NULL;
}
- if (revs->cherry_pick)
+ if (revs->cherry_pick || revs->cherry_mark)
cherry_pick_list(newlist, revs);
+ if (revs->left_only || revs->right_only)
+ limit_left_right(newlist, revs);
+
if (bottom) {
limit_to_ancestry(bottom, newlist);
free_commit_list(bottom);
revs->min_age = -1;
revs->skip_count = -1;
revs->max_count = -1;
+ revs->max_parents = -1;
revs->commit_format = CMIT_FMT_DEFAULT;
} else if (!strcmp(arg, "--remove-empty")) {
revs->remove_empty_trees = 1;
} else if (!strcmp(arg, "--merges")) {
- revs->merges_only = 1;
+ revs->min_parents = 2;
} else if (!strcmp(arg, "--no-merges")) {
- revs->no_merges = 1;
+ revs->max_parents = 1;
+ } else if (!prefixcmp(arg, "--min-parents=")) {
+ revs->min_parents = atoi(arg+14);
+ } else if (!prefixcmp(arg, "--no-min-parents")) {
+ revs->min_parents = 0;
+ } else if (!prefixcmp(arg, "--max-parents=")) {
+ revs->max_parents = atoi(arg+14);
+ } else if (!prefixcmp(arg, "--no-max-parents")) {
+ revs->max_parents = -1;
} else if (!strcmp(arg, "--boundary")) {
revs->boundary = 1;
} else if (!strcmp(arg, "--left-right")) {
revs->left_right = 1;
+ } else if (!strcmp(arg, "--left-only")) {
+ if (revs->right_only)
+ die("--left-only is incompatible with --right-only"
+ " or --cherry");
+ revs->left_only = 1;
+ } else if (!strcmp(arg, "--right-only")) {
+ if (revs->left_only)
+ die("--right-only is incompatible with --left-only");
+ revs->right_only = 1;
+ } else if (!strcmp(arg, "--cherry")) {
+ if (revs->left_only)
+ die("--cherry is incompatible with --left-only");
+ revs->cherry_mark = 1;
+ revs->right_only = 1;
+ revs->max_parents = 1;
+ revs->limited = 1;
} else if (!strcmp(arg, "--count")) {
revs->count = 1;
+ } else if (!strcmp(arg, "--cherry-mark")) {
+ if (revs->cherry_pick)
+ die("--cherry-mark is incompatible with --cherry-pick");
+ revs->cherry_mark = 1;
+ revs->limited = 1; /* needs limit_list() */
} else if (!strcmp(arg, "--cherry-pick")) {
+ if (revs->cherry_mark)
+ die("--cherry-pick is incompatible with --cherry-mark");
revs->cherry_pick = 1;
revs->limited = 1;
} else if (!strcmp(arg, "--objects")) {
return commit_ignore;
if (revs->min_age != -1 && (commit->date > revs->min_age))
return commit_ignore;
- if (revs->no_merges && commit->parents && commit->parents->next)
- return commit_ignore;
- if (revs->merges_only && !(commit->parents && commit->parents->next))
- return commit_ignore;
+ if (revs->min_parents || (revs->max_parents >= 0)) {
+ int n = 0;
+ struct commit_list *p;
+ for (p = commit->parents; p; p = p->next)
+ n++;
+ if ((n < revs->min_parents) ||
+ ((revs->max_parents >= 0) && (n > revs->max_parents)))
+ return commit_ignore;
+ }
if (!commit_match(commit, revs))
return commit_ignore;
if (revs->prune && revs->dense) {
graph_update(revs->graph, c);
return c;
}
+
+char *get_revision_mark(const struct rev_info *revs, const struct commit *commit)
+{
+ if (commit->object.flags & BOUNDARY)
+ return "-";
+ else if (commit->object.flags & UNINTERESTING)
+ return "^";
+ else if (commit->object.flags & PATCHSAME)
+ return "=";
+ else if (!revs || revs->left_right) {
+ if (commit->object.flags & SYMMETRIC_LEFT)
+ return "<";
+ else
+ return ">";
+ } else if (revs->graph)
+ return "*";
+ else if (revs->cherry_mark)
+ return "+";
+ return "";
+}
+
+void put_revision_mark(const struct rev_info *revs, const struct commit *commit)
+{
+ char *mark = get_revision_mark(revs, commit);
+ if (!strlen(mark))
+ return;
+ fputs(mark, stdout);
+ putchar(' ');
+}