revs->commit_format = CMIT_FMT_DEFAULT;
+ revs->grep_filter.status_only = 1;
+ revs->grep_filter.pattern_tail = &(revs->grep_filter.pattern_list);
+ revs->grep_filter.regflags = REG_NEWLINE;
+
diff_setup(&revs->diffopt);
if (prefix && !revs->diffopt.prefix) {
revs->diffopt.prefix = prefix;
static void add_grep(struct rev_info *revs, const char *ptn, enum grep_pat_token what)
{
- if (!revs->grep_filter) {
- struct grep_opt *opt = xcalloc(1, sizeof(*opt));
- opt->status_only = 1;
- opt->pattern_tail = &(opt->pattern_list);
- opt->regflags = REG_NEWLINE;
- revs->grep_filter = opt;
- }
- append_grep_pattern(revs->grep_filter, ptn,
- "command line", 0, what);
+ append_grep_pattern(&revs->grep_filter, ptn, "command line", 0, what);
}
-static void add_header_grep(struct rev_info *revs, const char *field, const char *pattern)
+static void add_header_grep(struct rev_info *revs, enum grep_header_field field, const char *pattern)
{
- char *pat;
- const char *prefix;
- int patlen, fldlen;
-
- fldlen = strlen(field);
- patlen = strlen(pattern);
- pat = xmalloc(patlen + fldlen + 10);
- prefix = ".*";
- if (*pattern == '^') {
- prefix = "";
- pattern++;
- }
- sprintf(pat, "^%s %s%s", field, prefix, pattern);
- add_grep(revs, pat, GREP_PATTERN_HEAD);
+ append_header_grep_pattern(&revs->grep_filter, field, pattern);
}
static void add_message_grep(struct rev_info *revs, const char *pattern)
* Grepping the commit log
*/
else if (!prefixcmp(arg, "--author=")) {
- add_header_grep(revs, "author", arg+9);
+ add_header_grep(revs, GREP_HEADER_AUTHOR, arg+9);
} else if (!prefixcmp(arg, "--committer=")) {
- add_header_grep(revs, "committer", arg+12);
+ add_header_grep(revs, GREP_HEADER_COMMITTER, arg+12);
} else if (!prefixcmp(arg, "--grep=")) {
add_message_grep(revs, arg+7);
} else if (!strcmp(arg, "--extended-regexp") || !strcmp(arg, "-E")) {
- if (revs->grep_filter)
- revs->grep_filter->regflags |= REG_EXTENDED;
+ revs->grep_filter.regflags |= REG_EXTENDED;
} else if (!strcmp(arg, "--regexp-ignore-case") || !strcmp(arg, "-i")) {
- if (revs->grep_filter)
- revs->grep_filter->regflags |= REG_ICASE;
+ revs->grep_filter.regflags |= REG_ICASE;
} else if (!strcmp(arg, "--fixed-strings") || !strcmp(arg, "-F")) {
- if (revs->grep_filter)
- revs->grep_filter->fixed = 1;
+ revs->grep_filter.fixed = 1;
} else if (!strcmp(arg, "--all-match")) {
- if (revs->grep_filter)
- revs->grep_filter->all_match = 1;
+ revs->grep_filter.all_match = 1;
} else if (!prefixcmp(arg, "--encoding=")) {
arg += 11;
if (strcmp(arg, "none"))
if (diff_setup_done(&revs->diffopt) < 0)
die("diff_setup_done failed");
- if (revs->grep_filter) {
- compile_grep_patterns(revs->grep_filter);
- }
+ compile_grep_patterns(&revs->grep_filter);
if (revs->reverse && revs->reflog_info)
die("cannot combine --reverse with --walk-reflogs");
return surviving_parents;
}
-static struct commit_list **simplify_one(struct commit *commit, struct commit_list **tail)
+struct merge_simplify_state {
+ struct commit *simplified;
+};
+
+static struct merge_simplify_state *locate_simplify_state(struct rev_info *revs, struct commit *commit)
+{
+ struct merge_simplify_state *st;
+
+ st = lookup_decoration(&revs->merge_simplification, &commit->object);
+ if (!st) {
+ st = xcalloc(1, sizeof(*st));
+ add_decoration(&revs->merge_simplification, &commit->object, st);
+ }
+ return st;
+}
+
+static struct commit_list **simplify_one(struct rev_info *revs, struct commit *commit, struct commit_list **tail)
{
struct commit_list *p;
+ struct merge_simplify_state *st, *pst;
int cnt;
+ st = locate_simplify_state(revs, commit);
+
/*
- * We store which commit each one simplifies to in its util field.
* Have we handled this one?
*/
- if (commit->util)
+ if (st->simplified)
return tail;
/*
* anyway.
*/
if ((commit->object.flags & UNINTERESTING) || !commit->parents) {
- commit->util = commit;
+ st->simplified = commit;
return tail;
}
* Otherwise we are not ready to rewrite this one yet.
*/
for (cnt = 0, p = commit->parents; p; p = p->next) {
- if (!p->item->util) {
+ pst = locate_simplify_state(revs, p->item);
+ if (!pst->simplified) {
tail = &commit_list_insert(p->item, tail)->next;
cnt++;
}
}
- if (cnt)
+ if (cnt) {
+ tail = &commit_list_insert(commit, tail)->next;
return tail;
+ }
/*
* Rewrite our list of parents.
*/
- for (p = commit->parents; p; p = p->next)
- p->item = p->item->util;
+ for (p = commit->parents; p; p = p->next) {
+ pst = locate_simplify_state(revs, p->item);
+ p->item = pst->simplified;
+ }
cnt = remove_duplicate_parents(commit);
/*
(commit->object.flags & UNINTERESTING) ||
!(commit->object.flags & TREESAME) ||
(1 < cnt))
- commit->util = commit;
- else
- commit->util = commit->parents->item->util;
+ st->simplified = commit;
+ else {
+ pst = locate_simplify_state(revs, commit->parents->item);
+ st->simplified = pst->simplified;
+ }
return tail;
}
struct commit_list *list;
struct commit_list *yet_to_do, **tail;
- sort_in_topological_order(&revs->commits, revs->lifo);
+ if (!revs->topo_order)
+ sort_in_topological_order(&revs->commits, revs->lifo);
+ if (!revs->prune)
+ return;
/* feed the list reversed */
yet_to_do = NULL;
struct commit_list *next = list->next;
free(list);
list = next;
- tail = simplify_one(commit, tail);
+ tail = simplify_one(revs, commit, tail);
}
}
while (list) {
struct commit *commit = list->item;
struct commit_list *next = list->next;
+ struct merge_simplify_state *st;
free(list);
list = next;
- if (commit->util == commit)
+ st = locate_simplify_state(revs, commit);
+ if (st->simplified == commit)
tail = &commit_list_insert(commit, tail)->next;
}
}
static int commit_match(struct commit *commit, struct rev_info *opt)
{
- if (!opt->grep_filter)
+ if (!opt->grep_filter.pattern_list)
return 1;
- return grep_buffer(opt->grep_filter,
+ return grep_buffer(&opt->grep_filter,
NULL, /* we say nothing, not even filename */
commit->buffer, strlen(commit->buffer));
}
return c;
}
- if (revs->reverse) {
- int limit = -1;
-
- if (0 <= revs->max_count) {
- limit = revs->max_count;
- if (0 < revs->skip_count)
- limit += revs->skip_count;
- }
- l = NULL;
- while ((c = get_revision_1(revs))) {
- commit_list_insert(c, &l);
- if ((0 < limit) && !--limit)
- break;
- }
- revs->commits = l;
- revs->reverse = 0;
- revs->max_count = -1;
- c = NULL;
- }
-
/*
* Now pick up what they want to give us
*/
struct commit *get_revision(struct rev_info *revs)
{
- struct commit *c = get_revision_internal(revs);
+ struct commit *c;
+ struct commit_list *reversed;
+
+ if (revs->reverse) {
+ reversed = NULL;
+ while ((c = get_revision_internal(revs))) {
+ commit_list_insert(c, &reversed);
+ }
+ revs->commits = reversed;
+ revs->reverse = 0;
+ revs->reverse_output_stage = 1;
+ }
+
+ if (revs->reverse_output_stage)
+ return pop_commit(&revs->commits);
+
+ c = get_revision_internal(revs);
if (c && revs->graph)
graph_update(revs->graph, c);
return c;