static void file_add_remove(struct diff_options *options,
int addremove, unsigned mode,
const unsigned char *sha1,
+ int sha1_valid,
const char *fullpath, unsigned dirty_submodule)
{
int diff = addremove == '+' ? REV_TREE_NEW : REV_TREE_OLD;
unsigned old_mode, unsigned new_mode,
const unsigned char *old_sha1,
const unsigned char *new_sha1,
+ int old_sha1_valid, int new_sha1_valid,
const char *fullpath,
unsigned old_dirty_submodule, unsigned new_dirty_submodule)
{
revs->commit_format = CMIT_FMT_DEFAULT;
+ init_grep_defaults();
+ grep_init(&revs->grep_filter, prefix);
revs->grep_filter.status_only = 1;
- revs->grep_filter.pattern_tail = &(revs->grep_filter.pattern_list);
- revs->grep_filter.header_tail = &(revs->grep_filter.header_list);
revs->grep_filter.regflags = REG_NEWLINE;
diff_setup(&revs->diffopt);
const char *this = arg;
int symmetric = *next == '.';
unsigned int flags_exclude = flags ^ UNINTERESTING;
+ static const char head_by_default[] = "HEAD";
unsigned int a_flags;
*dotdot = 0;
next += symmetric;
if (!*next)
- next = "HEAD";
+ next = head_by_default;
if (dotdot == arg)
- this = "HEAD";
+ this = head_by_default;
+ if (this == head_by_default && next == head_by_default &&
+ !symmetric) {
+ /*
+ * Just ".."? That is not a range but the
+ * pathspec for the parent directory.
+ */
+ if (!cant_be_filename) {
+ *dotdot = '.';
+ return -1;
+ }
+ }
if (!get_sha1_committish(this, from_sha1) &&
!get_sha1_committish(next, sha1)) {
struct commit *a, *b;
!strcmp(arg, "--no-walk") || !strcmp(arg, "--do-walk") ||
!strcmp(arg, "--bisect") || !prefixcmp(arg, "--glob=") ||
!prefixcmp(arg, "--branches=") || !prefixcmp(arg, "--tags=") ||
- !prefixcmp(arg, "--remotes="))
+ !prefixcmp(arg, "--remotes=") || !prefixcmp(arg, "--no-walk="))
{
unkv[(*unkc)++] = arg;
return 1;
} else if ((argcount = parse_long_opt("committer", argv, &optarg))) {
add_header_grep(revs, GREP_HEADER_COMMITTER, optarg);
return argcount;
+ } else if ((argcount = parse_long_opt("grep-reflog", argv, &optarg))) {
+ add_header_grep(revs, GREP_HEADER_REFLOG, optarg);
+ return argcount;
} else if ((argcount = parse_long_opt("grep", argv, &optarg))) {
add_message_grep(revs, optarg);
return argcount;
+ } else if (!strcmp(arg, "--grep-debug")) {
+ revs->grep_filter.debug = 1;
+ } else if (!strcmp(arg, "--basic-regexp")) {
+ grep_set_pattern_type_option(GREP_PATTERN_TYPE_BRE, &revs->grep_filter);
} else if (!strcmp(arg, "--extended-regexp") || !strcmp(arg, "-E")) {
- revs->grep_filter.regflags |= REG_EXTENDED;
+ grep_set_pattern_type_option(GREP_PATTERN_TYPE_ERE, &revs->grep_filter);
} else if (!strcmp(arg, "--regexp-ignore-case") || !strcmp(arg, "-i")) {
revs->grep_filter.regflags |= REG_ICASE;
DIFF_OPT_SET(&revs->diffopt, PICKAXE_IGNORE_CASE);
} else if (!strcmp(arg, "--fixed-strings") || !strcmp(arg, "-F")) {
- revs->grep_filter.fixed = 1;
+ grep_set_pattern_type_option(GREP_PATTERN_TYPE_FIXED, &revs->grep_filter);
+ } else if (!strcmp(arg, "--perl-regexp")) {
+ grep_set_pattern_type_option(GREP_PATTERN_TYPE_PCRE, &revs->grep_filter);
} else if (!strcmp(arg, "--all-match")) {
revs->grep_filter.all_match = 1;
} else if ((argcount = parse_long_opt("encoding", argv, &optarg))) {
} else if (!strcmp(arg, "--not")) {
*flags ^= UNINTERESTING;
} else if (!strcmp(arg, "--no-walk")) {
- revs->no_walk = 1;
+ revs->no_walk = REVISION_WALK_NO_WALK_SORTED;
+ } else if (!prefixcmp(arg, "--no-walk=")) {
+ /*
+ * Detached form ("--no-walk X" as opposed to "--no-walk=X")
+ * not allowed, since the argument is optional.
+ */
+ if (!strcmp(arg + 10, "sorted"))
+ revs->no_walk = REVISION_WALK_NO_WALK_SORTED;
+ else if (!strcmp(arg + 10, "unsorted"))
+ revs->no_walk = REVISION_WALK_NO_WALK_UNSORTED;
+ else
+ return error("invalid argument to --no-walk");
} else if (!strcmp(arg, "--do-walk")) {
revs->no_walk = 0;
} else {
if (revs->combine_merges)
revs->ignore_merges = 0;
revs->diffopt.abbrev = revs->abbrev;
- if (diff_setup_done(&revs->diffopt) < 0)
- die("diff_setup_done failed");
+ diff_setup_done(&revs->diffopt);
+ grep_commit_pattern_type(GREP_PATTERN_TYPE_UNSPECIFIED,
+ &revs->grep_filter);
compile_grep_patterns(&revs->grep_filter);
if (revs->reverse && revs->reflog_info)
if (revs->reflog_info && revs->graph)
die("cannot combine --walk-reflogs with --graph");
+ if (!revs->reflog_info && revs->grep_filter.use_reflog_filter)
+ die("cannot use --grep-reflog without --walk-reflogs");
return left;
}
}
e++;
}
- commit_list_sort_by_date(&revs->commits);
if (!revs->leak_pending)
free(list);
+ if (revs->no_walk != REVISION_WALK_NO_WALK_UNSORTED)
+ commit_list_sort_by_date(&revs->commits);
if (revs->no_walk)
return 0;
if (revs->limited)
static int commit_match(struct commit *commit, struct rev_info *opt)
{
+ int retval;
+ struct strbuf buf = STRBUF_INIT;
if (!opt->grep_filter.pattern_list && !opt->grep_filter.header_list)
return 1;
- return grep_buffer(&opt->grep_filter,
- commit->buffer, strlen(commit->buffer));
+
+ /* Prepend "fake" headers as needed */
+ if (opt->grep_filter.use_reflog_filter) {
+ strbuf_addstr(&buf, "reflog ");
+ get_reflog_message(&buf, opt->reflog_info);
+ strbuf_addch(&buf, '\n');
+ }
+
+ /* Copy the commit to temporary if we are using "fake" headers */
+ if (buf.len)
+ strbuf_addstr(&buf, commit->buffer);
+
+ /* Append "fake" message parts as needed */
+ if (opt->show_notes) {
+ if (!buf.len)
+ strbuf_addstr(&buf, commit->buffer);
+ format_display_notes(commit->object.sha1, &buf,
+ get_log_output_encoding(), 0);
+ }
+
+ /* Find either in the commit object, or in the temporary */
+ if (buf.len)
+ retval = grep_buffer(&opt->grep_filter, buf.buf, buf.len);
+ else
+ retval = grep_buffer(&opt->grep_filter,
+ commit->buffer, strlen(commit->buffer));
+ strbuf_release(&buf);
+ return retval;
}
static inline int want_ancestry(struct rev_info *revs)
}
/*
- * Now pick up what they want to give us
+ * If our max_count counter has reached zero, then we are done. We
+ * don't simply return NULL because we still might need to show
+ * boundary commits. But we want to avoid calling get_revision_1, which
+ * might do a considerable amount of work finding the next commit only
+ * for us to throw it away.
+ *
+ * If it is non-zero, then either we don't have a max_count at all
+ * (-1), or it is still counting, in which case we decrement.
*/
- c = get_revision_1(revs);
- if (c) {
- while (0 < revs->skip_count) {
- revs->skip_count--;
- c = get_revision_1(revs);
- if (!c)
- break;
+ if (revs->max_count) {
+ c = get_revision_1(revs);
+ if (c) {
+ while (0 < revs->skip_count) {
+ revs->skip_count--;
+ c = get_revision_1(revs);
+ if (!c)
+ break;
+ }
}
- }
- /*
- * Check the max_count.
- */
- switch (revs->max_count) {
- case -1:
- break;
- case 0:
- c = NULL;
- break;
- default:
- revs->max_count--;
+ if (revs->max_count > 0)
+ revs->max_count--;
}
if (c)