* tagged commit by specifying both --simplify-by-decoration
* and pathspec.
*/
- if (!revs->prune_data)
+ if (!revs->prune_data.nr)
return REV_TREE_SAME;
}
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) {
left_first = left_count < right_count;
init_patch_ids(&ids);
- if (revs->diffopt.nr_paths) {
- ids.diffopts.nr_paths = revs->diffopt.nr_paths;
- ids.diffopts.paths = revs->diffopt.paths;
- ids.diffopts.pathlens = revs->diffopt.pathlens;
- }
+ ids.diffopts.pathspec = revs->diffopt.pathspec;
/* Compute patch-ids for one side */
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;
revs->diffopt.prefix = prefix;
revs->diffopt.prefix_length = strlen(prefix);
}
+
+ revs->notes_opt.use_default_notes = -1;
}
static void add_pending_commit_list(struct rev_info *revs,
struct cache_entry *ce = active_cache[i];
if (!ce_stage(ce))
continue;
- if (ce_path_match(ce, revs->prune_data)) {
+ if (ce_path_match(ce, &revs->prune_data)) {
prune_num++;
prune = xrealloc(prune, sizeof(*prune) * prune_num);
prune[prune_num-2] = ce->name;
ce_same_name(ce, active_cache[i+1]))
i++;
}
- revs->prune_data = prune;
+ free_pathspec(&revs->prune_data);
+ init_pathspec(&revs->prune_data, prune);
revs->limited = 1;
}
} 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")) {
revs->verbose_header = 1;
revs->pretty_given = 1;
get_commit_format(arg+9, revs);
- } else if (!strcmp(arg, "--show-notes")) {
+ } else if (!strcmp(arg, "--show-notes") || !strcmp(arg, "--notes")) {
revs->show_notes = 1;
revs->show_notes_given = 1;
- } else if (!prefixcmp(arg, "--show-notes=")) {
+ revs->notes_opt.use_default_notes = 1;
+ } else if (!prefixcmp(arg, "--show-notes=") ||
+ !prefixcmp(arg, "--notes=")) {
struct strbuf buf = STRBUF_INIT;
revs->show_notes = 1;
revs->show_notes_given = 1;
- if (!revs->notes_opt.extra_notes_refs)
- revs->notes_opt.extra_notes_refs = xcalloc(1, sizeof(struct string_list));
- if (!prefixcmp(arg+13, "refs/"))
- /* happy */;
- else if (!prefixcmp(arg+13, "notes/"))
- strbuf_addstr(&buf, "refs/");
+ if (!prefixcmp(arg, "--show-notes")) {
+ if (revs->notes_opt.use_default_notes < 0)
+ revs->notes_opt.use_default_notes = 1;
+ strbuf_addstr(&buf, arg+13);
+ }
else
- strbuf_addstr(&buf, "refs/notes/");
- strbuf_addstr(&buf, arg+13);
- string_list_append(revs->notes_opt.extra_notes_refs,
+ strbuf_addstr(&buf, arg+8);
+ expand_notes_ref(&buf);
+ string_list_append(&revs->notes_opt.extra_notes_refs,
strbuf_detach(&buf, NULL));
} else if (!strcmp(arg, "--no-notes")) {
revs->show_notes = 0;
revs->show_notes_given = 1;
+ revs->notes_opt.use_default_notes = -1;
+ /* we have been strdup'ing ourselves, so trick
+ * string_list into free()ing strings */
+ revs->notes_opt.extra_notes_refs.strdup_strings = 1;
+ string_list_clear(&revs->notes_opt.extra_notes_refs, 0);
+ revs->notes_opt.extra_notes_refs.strdup_strings = 0;
} else if (!strcmp(arg, "--standard-notes")) {
revs->show_notes_given = 1;
- revs->notes_opt.suppress_default_notes = 0;
+ revs->notes_opt.use_default_notes = 1;
} else if (!strcmp(arg, "--no-standard-notes")) {
- revs->notes_opt.suppress_default_notes = 1;
+ revs->notes_opt.use_default_notes = 0;
} else if (!strcmp(arg, "--oneline")) {
revs->verbose_header = 1;
get_commit_format("oneline", revs);
}
if (prune_data)
- revs->prune_data = get_pathspec(revs->prefix, prune_data);
+ init_pathspec(&revs->prune_data, get_pathspec(revs->prefix, prune_data));
if (revs->def == NULL)
revs->def = opt ? opt->def : NULL;
if (revs->topo_order)
revs->limited = 1;
- if (revs->prune_data) {
- diff_tree_setup_paths(revs->prune_data, &revs->pruning);
+ if (revs->prune_data.nr) {
+ diff_tree_setup_paths(revs->prune_data.raw, &revs->pruning);
/* Can't prune commits with rename following: the paths change.. */
if (!DIFF_OPT_TST(&revs->diffopt, FOLLOW_RENAMES))
revs->prune = 1;
if (!revs->full_diff)
- diff_tree_setup_paths(revs->prune_data, &revs->diffopt);
+ diff_tree_setup_paths(revs->prune_data.raw, &revs->diffopt);
}
if (revs->combine_merges)
revs->ignore_merges = 0;
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(' ');
+}