if (revs->max_age != -1 && (commit->date < revs->max_age))
obj->flags |= UNINTERESTING;
- if (revs->unpacked &&
- has_sha1_pack(obj->sha1, revs->ignore_packed))
- obj->flags |= UNINTERESTING;
add_parents_to_list(revs, commit, &list);
if (obj->flags & UNINTERESTING) {
mark_parents_uninteresting(commit);
static int all_flags;
static struct rev_info *all_revs;
-static int handle_one_ref(const char *path, const unsigned char *sha1)
+static int handle_one_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
{
struct object *object = get_reference(all_revs, path, sha1, all_flags);
add_pending_object(all_revs, object, "");
{
all_revs = revs;
all_flags = flags;
- for_each_ref(handle_one_ref);
+ for_each_ref(handle_one_ref, NULL);
}
static int add_parents_only(struct rev_info *revs, const char *arg, int flags)
return 0;
*dotdot = '^';
}
+ dotdot = strstr(arg, "^!");
+ if (dotdot && !dotdot[2]) {
+ *dotdot = 0;
+ if (!add_parents_only(revs, arg, flags ^ UNINTERESTING))
+ *dotdot = '^';
+ }
+
local_flags = 0;
if (*arg == '^') {
local_flags = UNINTERESTING;
return 0;
}
-static void add_header_grep(struct rev_info *revs, const char *field, const char *pattern)
+static void add_grep(struct rev_info *revs, const char *ptn, enum grep_pat_token what)
{
- char *pat;
- int patlen, fldlen;
-
- if (!revs->header_filter) {
+ 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->header_filter = opt;
+ revs->grep_filter = opt;
}
+ 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)
+{
+ char *pat;
+ const char *prefix;
+ int patlen, fldlen;
fldlen = strlen(field);
patlen = strlen(pattern);
- pat = xmalloc(patlen + fldlen + 3);
- sprintf(pat, "^%s %s", field, pattern);
- append_grep_pattern(revs->header_filter, pat,
- "command line", 0, GREP_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);
}
static void add_message_grep(struct rev_info *revs, const char *pattern)
{
- if (!revs->message_filter) {
- struct grep_opt *opt = xcalloc(1, sizeof(*opt));
- opt->status_only = 1;
- opt->pattern_tail = &(opt->pattern_list);
- opt->regflags = REG_NEWLINE;
- revs->message_filter = opt;
- }
- append_grep_pattern(revs->message_filter, pattern,
- "command line", 0, GREP_PATTERN);
+ add_grep(revs, pattern, GREP_PATTERN_BODY);
}
static void add_ignore_packed(struct rev_info *revs, const char *name)
int i, flags, seen_dashdash, show_merge;
const char **unrecognized = argv + 1;
int left = 1;
+ int all_match = 0;
/* First, search for "--" */
seen_dashdash = 0;
revs->relative_date = 1;
continue;
}
+
+ /*
+ * Grepping the commit log
+ */
if (!strncmp(arg, "--author=", 9)) {
add_header_grep(revs, "author", arg+9);
continue;
add_message_grep(revs, arg+7);
continue;
}
+ if (!strcmp(arg, "--all-match")) {
+ all_match = 1;
+ continue;
+ }
+
opts = diff_opt_parse(&revs->diffopt, argv+i, argc-i);
if (opts > 0) {
revs->diff = 1;
add_pending_object(revs, object, def);
}
- if (revs->topo_order || revs->unpacked)
+ if (revs->topo_order)
revs->limited = 1;
if (revs->prune_data) {
if (diff_setup_done(&revs->diffopt) < 0)
die("diff_setup_done failed");
- if (revs->header_filter)
- compile_grep_patterns(revs->header_filter);
- if (revs->message_filter)
- compile_grep_patterns(revs->message_filter);
+ if (revs->grep_filter) {
+ revs->grep_filter->all_match = all_match;
+ compile_grep_patterns(revs->grep_filter);
+ }
return left;
}
static int commit_match(struct commit *commit, struct rev_info *opt)
{
- char *header, *message;
- unsigned long header_len, message_len;
-
- if (!opt->header_filter && !opt->message_filter)
+ if (!opt->grep_filter)
return 1;
-
- header = commit->buffer;
- message = strstr(header, "\n\n");
- if (message) {
- message += 2;
- header_len = message - header - 1;
- message_len = strlen(message);
- }
- else {
- header_len = strlen(header);
- message = header;
- message_len = 0;
- }
-
- if (opt->header_filter &&
- !grep_buffer(opt->header_filter, NULL, header, header_len))
- return 0;
-
- if (opt->message_filter &&
- !grep_buffer(opt->message_filter, NULL, message, message_len))
- return 0;
-
- return 1;
+ return grep_buffer(opt->grep_filter,
+ NULL, /* we say nothing, not even filename */
+ commit->buffer, strlen(commit->buffer));
}
struct commit *get_revision(struct rev_info *revs)
* that we'd otherwise have done in limit_list().
*/
if (!revs->limited) {
- if ((revs->unpacked &&
- has_sha1_pack(commit->object.sha1,
- revs->ignore_packed)) ||
- (revs->max_age != -1 &&
- (commit->date < revs->max_age)))
+ if (revs->max_age != -1 &&
+ (commit->date < revs->max_age))
continue;
add_parents_to_list(revs, commit, &revs->commits);
}
if (commit->object.flags & SHOWN)
continue;
+ if (revs->unpacked && has_sha1_pack(commit->object.sha1,
+ revs->ignore_packed))
+ continue;
+
/* We want to show boundary commits only when their
* children are shown. When path-limiter is in effect,
* rewrite_parents() drops some commits from getting shown,