author | Junio C Hamano <gitster@pobox.com> | |
Sat, 26 Dec 2009 22:03:18 +0000 (14:03 -0800) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Sat, 26 Dec 2009 22:03:18 +0000 (14:03 -0800) |
* jc/1.7.0-diff-whitespace-only-status:
diff.c: fix typoes in comments
Make test case number unique
diff: Rename QUIET internal option to QUICK
diff: change semantics of "ignore whitespace" options
Conflicts:
diff.h
diff.c: fix typoes in comments
Make test case number unique
diff: Rename QUIET internal option to QUICK
diff: change semantics of "ignore whitespace" options
Conflicts:
diff.h
1 | 2 | |||
---|---|---|---|---|
builtin-log.c | patch | | diff1 | | diff2 | | blob | history |
builtin-rev-list.c | patch | | diff1 | | diff2 | | blob | history |
diff-lib.c | patch | | diff1 | | diff2 | | blob | history |
diff.c | patch | | diff1 | | diff2 | | blob | history |
diff.h | patch | | diff1 | | diff2 | | blob | history |
revision.c | patch | | diff1 | | diff2 | | blob | history |
diff --combined builtin-log.c
index 1766349550f5b4204e77f6f6eeca486cee322ca1,7903e5a78f80b55c94b8824260eb21ee95ff1b93..41b6df490f7c52edbee880afa9070c1511cdf442
--- 1/builtin-log.c
--- 2/builtin-log.c
+++ b/builtin-log.c
static const char *fmt_patch_subject_prefix = "PATCH";
static const char *fmt_pretty;
+static const char * const builtin_log_usage =
+ "git log [<options>] [<since>..<until>] [[--] <path>...]\n"
+ " or: git show [options] <object>...";
+
static void cmd_log_init(int argc, const char **argv, const char *prefix,
struct rev_info *rev)
{
int i;
+ int decoration_style = 0;
rev->abbrev = DEFAULT_ABBREV;
rev->commit_format = CMIT_FMT_DEFAULT;
if (default_date_mode)
rev->date_mode = parse_date_format(default_date_mode);
+ /*
+ * Check for -h before setup_revisions(), or "git log -h" will
+ * fail when run without a git directory.
+ */
+ if (argc == 2 && !strcmp(argv[1], "-h"))
+ usage(builtin_log_usage);
argc = setup_revisions(argc, argv, rev, "HEAD");
if (rev->diffopt.pickaxe || rev->diffopt.filter)
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
if (!strcmp(arg, "--decorate")) {
- load_ref_decorations();
- rev->show_decorations = 1;
+ decoration_style = DECORATE_SHORT_REFS;
+ } else if (!prefixcmp(arg, "--decorate=")) {
+ const char *v = skip_prefix(arg, "--decorate=");
+ if (!strcmp(v, "full"))
+ decoration_style = DECORATE_FULL_REFS;
+ else if (!strcmp(v, "short"))
+ decoration_style = DECORATE_SHORT_REFS;
+ else
+ die("invalid --decorate option: %s", arg);
} else if (!strcmp(arg, "--source")) {
rev->show_source = 1;
+ } else if (!strcmp(arg, "-h")) {
+ usage(builtin_log_usage);
} else
die("unrecognized argument: %s", arg);
}
+ if (decoration_style) {
+ rev->show_decorations = 1;
+ load_ref_decorations(decoration_style);
+ }
}
/*
pp_user_info("Tagger", rev->commit_format, &out, buf, rev->date_mode,
git_log_output_encoding ?
git_log_output_encoding: git_commit_encoding);
- printf("%s\n", out.buf);
+ printf("%s", out.buf);
strbuf_release(&out);
}
case OBJ_TAG: {
struct tag *t = (struct tag *)o;
+ if (rev.shown_one)
+ putchar('\n');
printf("%stag %s%s\n",
diff_get_color_opt(&rev.diffopt, DIFF_COMMIT),
t->tag,
diff_get_color_opt(&rev.diffopt, DIFF_RESET));
ret = show_object(o->sha1, 1, &rev);
+ rev.shown_one = 1;
if (ret)
break;
o = parse_object(t->tagged->sha1);
break;
}
case OBJ_TREE:
+ if (rev.shown_one)
+ putchar('\n');
printf("%stree %s%s\n\n",
diff_get_color_opt(&rev.diffopt, DIFF_COMMIT),
name,
diff_get_color_opt(&rev.diffopt, DIFF_RESET));
read_tree_recursive((struct tree *)o, "", 0, 0, NULL,
show_tree_object, NULL);
+ rev.shown_one = 1;
break;
case OBJ_COMMIT:
rev.pending.nr = rev.pending.alloc = 0;
get_patch_filename(commit, rev->nr, fmt_patch_suffix, &filename);
- if (!DIFF_OPT_TST(&rev->diffopt, QUIET))
+ if (!DIFF_OPT_TST(&rev->diffopt, QUICK))
fprintf(realstdout, "%s\n", filename.buf + outdir_offset);
if (freopen(filename.buf, "w", stdout) == NULL)
log_write_email_headers(rev, head, &subject_start, &extra_headers,
&need_8bit_cte);
+ for (i = 0; !need_8bit_cte && i < nr; i++)
+ if (has_non_ascii(list[i]->buffer))
+ need_8bit_cte = 1;
+
msg = body;
pp_user_info(NULL, CMIT_FMT_EMAIL, &sb, committer, DATE_RFC2822,
encoding);
struct patch_ids ids;
char *add_signoff = NULL;
struct strbuf buf = STRBUF_INIT;
+ int use_patch_format = 0;
const struct option builtin_format_patch_options[] = {
{ OPTION_CALLBACK, 'n', "numbered", &numbered, NULL,
"use [PATCH n/m] even with a single patch",
"don't output binary diffs"),
OPT_BOOLEAN(0, "ignore-if-in-upstream", &ignore_if_in_upstream,
"don't include a patch matching a commit upstream"),
+ { OPTION_BOOLEAN, 'p', "no-stat", &use_patch_format, NULL,
+ "show patch format instead of default (patch + stat)",
+ PARSE_OPT_NONEG | PARSE_OPT_NOARG },
OPT_GROUP("Messaging"),
{ OPTION_CALLBACK, 0, "add-header", NULL, "header",
"add email header", PARSE_OPT_NONEG,
*/
argc = parse_options(argc, argv, prefix, builtin_format_patch_options,
builtin_format_patch_usage,
- PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN);
+ PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN |
+ PARSE_OPT_KEEP_DASHDASH);
if (do_signoff) {
const char *committer;
if (argc > 1)
die ("unrecognized argument: %s", argv[1]);
- if (!rev.diffopt.output_format
- || rev.diffopt.output_format == DIFF_FORMAT_PATCH)
- rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY | DIFF_FORMAT_PATCH;
+ if (rev.diffopt.output_format & DIFF_FORMAT_NAME)
+ die("--name-only does not make sense");
+ if (rev.diffopt.output_format & DIFF_FORMAT_NAME_STATUS)
+ die("--name-status does not make sense");
+ if (rev.diffopt.output_format & DIFF_FORMAT_CHECKDIFF)
+ die("--check does not make sense");
+
+ if (!use_patch_format &&
+ (!rev.diffopt.output_format ||
+ rev.diffopt.output_format == DIFF_FORMAT_PATCH))
+ rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY;
+
+ /* Always generate a patch */
+ rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
if (!DIFF_OPT_TST(&rev.diffopt, TEXT) && !no_binary_diff)
DIFF_OPT_SET(&rev.diffopt, BINARY);
argv++;
}
+ if (argc > 1 && !strcmp(argv[1], "-h"))
+ usage(cherry_usage);
+
switch (argc) {
case 4:
limit = argv[3];
if (verbose) {
struct strbuf buf = STRBUF_INIT;
+ struct pretty_print_context ctx = {0};
pretty_print_commit(CMIT_FMT_ONELINE, commit,
- &buf, 0, NULL, NULL, 0, 0);
+ &buf, &ctx);
printf("%c %s %s\n", sign,
sha1_to_hex(commit->object.sha1), buf.buf);
strbuf_release(&buf);
diff --combined builtin-rev-list.c
index 91b604289dd59101cb6477fa49dd9c342e5b39e5,69753dc2060677103f79496c382d2331849c28e5..cd97ded4d249b3beb5179150a283e8be43b9ba44
--- 1/builtin-rev-list.c
--- 2/builtin-rev-list.c
+++ b/builtin-rev-list.c
if (revs->verbose_header && commit->buffer) {
struct strbuf buf = STRBUF_INIT;
- pretty_print_commit(revs->commit_format, commit,
- &buf, revs->abbrev, NULL, NULL,
- revs->date_mode, 0);
+ struct pretty_print_context ctx = {0};
+ ctx.abbrev = revs->abbrev;
+ ctx.date_mode = revs->date_mode;
+ pretty_print_commit(revs->commit_format, commit, &buf, &ctx);
if (revs->graph) {
if (buf.len) {
if (revs->commit_format != CMIT_FMT_ONELINE)
struct rev_info revs;
struct rev_list_info info;
int i;
- int read_from_stdin = 0;
int bisect_list = 0;
int bisect_show_vars = 0;
int bisect_find_all = 0;
memset(&info, 0, sizeof(info));
info.revs = &revs;
+ if (revs.bisect)
+ bisect_list = 1;
- quiet = DIFF_OPT_TST(&revs.diffopt, QUIET);
+ quiet = DIFF_OPT_TST(&revs.diffopt, QUICK);
for (i = 1 ; i < argc; i++) {
const char *arg = argv[i];
bisect_show_vars = 1;
continue;
}
- if (!strcmp(arg, "--stdin")) {
- if (read_from_stdin++)
- die("--stdin given twice?");
- read_revisions_from_stdin(&revs);
- continue;
- }
usage(rev_list_usage);
}
diff --combined diff-lib.c
index adf1c5fdee2bc836f03eaa89160573973bb46a67,b7813af614bc62b563201e22fe0e2bceb2d13833..349f612b615fc152e9d272900b1ac5177f4a025c
--- 1/diff-lib.c
--- 2/diff-lib.c
+++ b/diff-lib.c
struct cache_entry *ce = active_cache[i];
int changed;
- if (DIFF_OPT_TST(&revs->diffopt, QUIET) &&
+ if (DIFF_OPT_TST(&revs->diffopt, QUICK) &&
DIFF_OPT_TST(&revs->diffopt, HAS_CHANGES))
break;
if (ce_uptodate(ce))
continue;
- changed = check_removed(ce, &st);
+ /* If CE_VALID is set, don't look at workdir for file removal */
+ changed = (ce->ce_flags & CE_VALID) ? 0 : check_removed(ce, &st);
if (changed) {
if (changed < 0) {
perror(ce->name);
return 0;
}
-/*
- * This turns all merge entries into "stage 3". That guarantees that
- * when we read in the new tree (into "stage 1"), we won't lose sight
- * of the fact that we had unmerged entries.
- */
-static void mark_merge_entries(void)
-{
- int i;
- for (i = 0; i < active_nr; i++) {
- struct cache_entry *ce = active_cache[i];
- if (!ce_stage(ce))
- continue;
- ce->ce_flags |= CE_STAGEMASK;
- }
-}
-
/*
* This gets a mix of an existing index and a tree, one pathname entry
* at a time. The index entry may be a single stage-0 one, but it could
struct rev_info *revs = o->unpack_data;
int match_missing, cached;
+ /* if the entry is not checked out, don't examine work tree */
+ cached = o->index_only || (idx && (idx->ce_flags & CE_VALID));
/*
* Backward compatibility wart - "diff-index -m" does
* not mean "do not ignore merges", but "match_missing".
* But with the revision flag parsing, that's found in
* "!revs->ignore_merges".
*/
- cached = o->index_only;
match_missing = !revs->ignore_merges;
if (cached && idx && ce_stage(idx)) {
- if (tree)
- diff_unmerge(&revs->diffopt, idx->name, idx->ce_mode, idx->sha1);
+ diff_unmerge(&revs->diffopt, idx->name, idx->ce_mode,
+ idx->sha1);
return;
}
* For diffing, the index is more important, and we only have a
* single tree.
*
- * We're supposed to return how many index entries we want to skip.
+ * We're supposed to advance o->pos to skip what we have already processed.
*
* This wrapper makes it all more readable, and takes care of all
* the fairly complex unpack_trees() semantic requirements, including
struct unpack_trees_options opts;
struct tree_desc t;
- mark_merge_entries();
-
ent = revs->pending.objects[0].item;
tree_name = revs->pending.objects[0].name;
tree = parse_tree_indirect(ent->sha1);
init_revisions(&rev, NULL);
setup_revisions(0, NULL, &rev, def);
- DIFF_OPT_SET(&rev.diffopt, QUIET);
+ DIFF_OPT_SET(&rev.diffopt, QUICK);
DIFF_OPT_SET(&rev.diffopt, EXIT_WITH_STATUS);
rev.diffopt.flags |= diff_flags;
run_diff_index(&rev, 1);
diff --combined diff.c
index 08bbd3e9070996b38f4d34cedf7640d93aa5808d,24bd3fce3f8445e2d9a261a42fcb1eb85d2badfe..57aa72c6c575d1014cbb716d3993f600bdc1f2c5
+++ b/diff.c
#include "utf8.h"
#include "userdiff.h"
#include "sigchain.h"
+#include "submodule.h"
#ifdef NO_FAST_WORKING_DIRECTORY
#define FAST_WORKING_DIRECTORY 0
GIT_COLOR_GREEN, /* NEW */
GIT_COLOR_YELLOW, /* COMMIT */
GIT_COLOR_BG_RED, /* WHITESPACE */
+ GIT_COLOR_NORMAL, /* FUNCINFO */
};
static void diff_filespec_load_driver(struct diff_filespec *one);
return DIFF_COMMIT;
if (!strcasecmp(var+ofs, "whitespace"))
return DIFF_WHITESPACE;
- die("bad config variable '%s'", var);
+ if (!strcasecmp(var+ofs, "func"))
+ return DIFF_FUNCINFO;
+ return -1;
}
static int git_config_rename(const char *var, const char *value)
if (!prefixcmp(var, "diff.color.") || !prefixcmp(var, "color.diff.")) {
int slot = parse_diff_color_slot(var, 11);
+ if (slot < 0)
+ return 0;
if (!value)
return config_error_nonbool(var);
color_parse(value, var, diff_colors[slot]);
char tmp_path[PATH_MAX];
} diff_temp[2];
+typedef unsigned long (*sane_truncate_fn)(char *line, unsigned long len);
+
+struct emit_callback {
+ int color_diff;
+ unsigned ws_rule;
+ int blank_at_eof_in_preimage;
+ int blank_at_eof_in_postimage;
+ int lno_in_preimage;
+ int lno_in_postimage;
+ sane_truncate_fn truncate;
+ const char **label_path;
+ struct diff_words_data *diff_words;
+ int *found_changesp;
+ FILE *file;
+};
+
+static int count_lines(const char *data, int size)
+{
+ int count, ch, completely_empty = 1, nl_just_seen = 0;
+ count = 0;
+ while (0 < size--) {
+ ch = *data++;
+ if (ch == '\n') {
+ count++;
+ nl_just_seen = 1;
+ completely_empty = 0;
+ }
+ else {
+ nl_just_seen = 0;
+ completely_empty = 0;
+ }
+ }
+ if (completely_empty)
+ return 0;
+ if (!nl_just_seen)
+ count++; /* no trailing newline */
+ return count;
+}
+
+static int fill_mmfile(mmfile_t *mf, struct diff_filespec *one)
+{
+ if (!DIFF_FILE_VALID(one)) {
+ mf->ptr = (char *)""; /* does not matter */
+ mf->size = 0;
+ return 0;
+ }
+ else if (diff_populate_filespec(one, 0))
+ return -1;
+
+ mf->ptr = one->data;
+ mf->size = one->size;
+ return 0;
+}
+
+static int count_trailing_blank(mmfile_t *mf, unsigned ws_rule)
+{
+ char *ptr = mf->ptr;
+ long size = mf->size;
+ int cnt = 0;
+
+ if (!size)
+ return cnt;
+ ptr += size - 1; /* pointing at the very end */
+ if (*ptr != '\n')
+ ; /* incomplete line */
+ else
+ ptr--; /* skip the last LF */
+ while (mf->ptr < ptr) {
+ char *prev_eol;
+ for (prev_eol = ptr; mf->ptr <= prev_eol; prev_eol--)
+ if (*prev_eol == '\n')
+ break;
+ if (!ws_blank_line(prev_eol + 1, ptr - prev_eol, ws_rule))
+ break;
+ cnt++;
+ ptr = prev_eol - 1;
+ }
+ return cnt;
+}
+
+static void check_blank_at_eof(mmfile_t *mf1, mmfile_t *mf2,
+ struct emit_callback *ecbdata)
+{
+ int l1, l2, at;
+ unsigned ws_rule = ecbdata->ws_rule;
+ l1 = count_trailing_blank(mf1, ws_rule);
+ l2 = count_trailing_blank(mf2, ws_rule);
+ if (l2 <= l1) {
+ ecbdata->blank_at_eof_in_preimage = 0;
+ ecbdata->blank_at_eof_in_postimage = 0;
+ return;
+ }
+ at = count_lines(mf1->ptr, mf1->size);
+ ecbdata->blank_at_eof_in_preimage = (at - l1) + 1;
+
+ at = count_lines(mf2->ptr, mf2->size);
+ ecbdata->blank_at_eof_in_postimage = (at - l2) + 1;
+}
+
+static void emit_line_0(FILE *file, const char *set, const char *reset,
+ int first, const char *line, int len)
+{
+ int has_trailing_newline, has_trailing_carriage_return;
+ int nofirst;
+
+ if (len == 0) {
+ has_trailing_newline = (first == '\n');
+ has_trailing_carriage_return = (!has_trailing_newline &&
+ (first == '\r'));
+ nofirst = has_trailing_newline || has_trailing_carriage_return;
+ } else {
+ has_trailing_newline = (len > 0 && line[len-1] == '\n');
+ if (has_trailing_newline)
+ len--;
+ has_trailing_carriage_return = (len > 0 && line[len-1] == '\r');
+ if (has_trailing_carriage_return)
+ len--;
+ nofirst = 0;
+ }
+
+ if (len || !nofirst) {
+ fputs(set, file);
+ if (!nofirst)
+ fputc(first, file);
+ fwrite(line, len, 1, file);
+ fputs(reset, file);
+ }
+ if (has_trailing_carriage_return)
+ fputc('\r', file);
+ if (has_trailing_newline)
+ fputc('\n', file);
+}
+
+static void emit_line(FILE *file, const char *set, const char *reset,
+ const char *line, int len)
+{
+ emit_line_0(file, set, reset, line[0], line+1, len-1);
+}
+
+static int new_blank_line_at_eof(struct emit_callback *ecbdata, const char *line, int len)
+{
+ if (!((ecbdata->ws_rule & WS_BLANK_AT_EOF) &&
+ ecbdata->blank_at_eof_in_preimage &&
+ ecbdata->blank_at_eof_in_postimage &&
+ ecbdata->blank_at_eof_in_preimage <= ecbdata->lno_in_preimage &&
+ ecbdata->blank_at_eof_in_postimage <= ecbdata->lno_in_postimage))
+ return 0;
+ return ws_blank_line(line, len, ecbdata->ws_rule);
+}
+
+static void emit_add_line(const char *reset,
+ struct emit_callback *ecbdata,
+ const char *line, int len)
+{
+ const char *ws = diff_get_color(ecbdata->color_diff, DIFF_WHITESPACE);
+ const char *set = diff_get_color(ecbdata->color_diff, DIFF_FILE_NEW);
+
+ if (!*ws)
+ emit_line_0(ecbdata->file, set, reset, '+', line, len);
+ else if (new_blank_line_at_eof(ecbdata, line, len))
+ /* Blank line at EOF - paint '+' as well */
+ emit_line_0(ecbdata->file, ws, reset, '+', line, len);
+ else {
+ /* Emit just the prefix, then the rest. */
+ emit_line_0(ecbdata->file, set, reset, '+', "", 0);
+ ws_check_emit(line, len, ecbdata->ws_rule,
+ ecbdata->file, set, reset, ws);
+ }
+}
+
+static void emit_hunk_header(struct emit_callback *ecbdata,
+ const char *line, int len)
+{
+ const char *plain = diff_get_color(ecbdata->color_diff, DIFF_PLAIN);
+ const char *frag = diff_get_color(ecbdata->color_diff, DIFF_FRAGINFO);
+ const char *func = diff_get_color(ecbdata->color_diff, DIFF_FUNCINFO);
+ const char *reset = diff_get_color(ecbdata->color_diff, DIFF_RESET);
+ static const char atat[2] = { '@', '@' };
+ const char *cp, *ep;
+
+ /*
+ * As a hunk header must begin with "@@ -<old>, +<new> @@",
+ * it always is at least 10 bytes long.
+ */
+ if (len < 10 ||
+ memcmp(line, atat, 2) ||
+ !(ep = memmem(line + 2, len - 2, atat, 2))) {
+ emit_line(ecbdata->file, plain, reset, line, len);
+ return;
+ }
+ ep += 2; /* skip over @@ */
+
+ /* The hunk header in fraginfo color */
+ emit_line(ecbdata->file, frag, reset, line, ep - line);
+
+ /* blank before the func header */
+ for (cp = ep; ep - line < len; ep++)
+ if (*ep != ' ' && *ep != '\t')
+ break;
+ if (ep != cp)
+ emit_line(ecbdata->file, plain, reset, cp, ep - cp);
+
+ if (ep < line + len)
+ emit_line(ecbdata->file, func, reset, ep, line + len - ep);
+}
+
static struct diff_tempfile *claim_diff_tempfile(void) {
int i;
for (i = 0; i < ARRAY_SIZE(diff_temp); i++)
raise(signo);
}
-static int count_lines(const char *data, int size)
-{
- int count, ch, completely_empty = 1, nl_just_seen = 0;
- count = 0;
- while (0 < size--) {
- ch = *data++;
- if (ch == '\n') {
- count++;
- nl_just_seen = 1;
- completely_empty = 0;
- }
- else {
- nl_just_seen = 0;
- completely_empty = 0;
- }
- }
- if (completely_empty)
- return 0;
- if (!nl_just_seen)
- count++; /* no trailing newline */
- return count;
-}
-
static void print_line_count(FILE *file, int count)
{
switch (count) {
}
}
-static void copy_file_with_prefix(FILE *file,
- int prefix, const char *data, int size,
- const char *set, const char *reset)
+static void emit_rewrite_lines(struct emit_callback *ecb,
+ int prefix, const char *data, int size)
{
- int ch, nl_just_seen = 1;
- while (0 < size--) {
- ch = *data++;
- if (nl_just_seen) {
- fputs(set, file);
- putc(prefix, file);
+ const char *endp = NULL;
+ static const char *nneof = " No newline at end of file\n";
+ const char *old = diff_get_color(ecb->color_diff, DIFF_FILE_OLD);
+ const char *reset = diff_get_color(ecb->color_diff, DIFF_RESET);
+
+ while (0 < size) {
+ int len;
+
+ endp = memchr(data, '\n', size);
+ len = endp ? (endp - data + 1) : size;
+ if (prefix != '+') {
+ ecb->lno_in_preimage++;
+ emit_line_0(ecb->file, old, reset, '-',
+ data, len);
+ } else {
+ ecb->lno_in_postimage++;
+ emit_add_line(reset, ecb, data, len);
}
- if (ch == '\n') {
- nl_just_seen = 1;
- fputs(reset, file);
- } else
- nl_just_seen = 0;
- putc(ch, file);
+ size -= len;
+ data += len;
+ }
+ if (!endp) {
+ const char *plain = diff_get_color(ecb->color_diff,
+ DIFF_PLAIN);
+ emit_line_0(ecb->file, plain, reset, '\\',
+ nneof, strlen(nneof));
}
- if (!nl_just_seen)
- fprintf(file, "%s\n\\ No newline at end of file\n", reset);
}
static void emit_rewrite_diff(const char *name_a,
const char *name_a_tab, *name_b_tab;
const char *metainfo = diff_get_color(color_diff, DIFF_METAINFO);
const char *fraginfo = diff_get_color(color_diff, DIFF_FRAGINFO);
- const char *old = diff_get_color(color_diff, DIFF_FILE_OLD);
- const char *new = diff_get_color(color_diff, DIFF_FILE_NEW);
const char *reset = diff_get_color(color_diff, DIFF_RESET);
static struct strbuf a_name = STRBUF_INIT, b_name = STRBUF_INIT;
const char *a_prefix, *b_prefix;
const char *data_one, *data_two;
size_t size_one, size_two;
+ struct emit_callback ecbdata;
if (diff_mnemonic_prefix && DIFF_OPT_TST(o, REVERSE_DIFF)) {
a_prefix = o->b_prefix;
size_two = two->size;
}
+ memset(&ecbdata, 0, sizeof(ecbdata));
+ ecbdata.color_diff = color_diff;
+ ecbdata.found_changesp = &o->found_changes;
+ ecbdata.ws_rule = whitespace_rule(name_b ? name_b : name_a);
+ ecbdata.file = o->file;
+ if (ecbdata.ws_rule & WS_BLANK_AT_EOF) {
+ mmfile_t mf1, mf2;
+ mf1.ptr = (char *)data_one;
+ mf2.ptr = (char *)data_two;
+ mf1.size = size_one;
+ mf2.size = size_two;
+ check_blank_at_eof(&mf1, &mf2, &ecbdata);
+ }
+ ecbdata.lno_in_preimage = 1;
+ ecbdata.lno_in_postimage = 1;
+
lc_a = count_lines(data_one, size_one);
lc_b = count_lines(data_two, size_two);
fprintf(o->file,
print_line_count(o->file, lc_b);
fprintf(o->file, " @@%s\n", reset);
if (lc_a)
- copy_file_with_prefix(o->file, '-', data_one, size_one, old, reset);
+ emit_rewrite_lines(&ecbdata, '-', data_one, size_one);
if (lc_b)
- copy_file_with_prefix(o->file, '+', data_two, size_two, new, reset);
-}
-
-static int fill_mmfile(mmfile_t *mf, struct diff_filespec *one)
-{
- if (!DIFF_FILE_VALID(one)) {
- mf->ptr = (char *)""; /* does not matter */
- mf->size = 0;
- return 0;
- }
- else if (diff_populate_filespec(one, 0))
- return -1;
-
- mf->ptr = one->data;
- mf->size = one->size;
- return 0;
+ emit_rewrite_lines(&ecbdata, '+', data_two, size_two);
}
struct diff_words_buffer {
diff_words->minus.text.size = diff_words->plus.text.size = 0;
}
-typedef unsigned long (*sane_truncate_fn)(char *line, unsigned long len);
-
-struct emit_callback {
- int nparents, color_diff;
- unsigned ws_rule;
- sane_truncate_fn truncate;
- const char **label_path;
- struct diff_words_data *diff_words;
- int *found_changesp;
- FILE *file;
-};
+/* In "color-words" mode, show word-diff of words accumulated in the buffer */
+static void diff_words_flush(struct emit_callback *ecbdata)
+{
+ if (ecbdata->diff_words->minus.text.size ||
+ ecbdata->diff_words->plus.text.size)
+ diff_words_show(ecbdata->diff_words);
+}
static void free_diff_words_data(struct emit_callback *ecbdata)
{
if (ecbdata->diff_words) {
- /* flush buffers */
- if (ecbdata->diff_words->minus.text.size ||
- ecbdata->diff_words->plus.text.size)
- diff_words_show(ecbdata->diff_words);
-
+ diff_words_flush(ecbdata);
free (ecbdata->diff_words->minus.text.ptr);
free (ecbdata->diff_words->minus.orig);
free (ecbdata->diff_words->plus.text.ptr);
return "";
}
-static void emit_line(FILE *file, const char *set, const char *reset, const char *line, int len)
-{
- int has_trailing_newline, has_trailing_carriage_return;
-
- has_trailing_newline = (len > 0 && line[len-1] == '\n');
- if (has_trailing_newline)
- len--;
- has_trailing_carriage_return = (len > 0 && line[len-1] == '\r');
- if (has_trailing_carriage_return)
- len--;
-
- fputs(set, file);
- fwrite(line, len, 1, file);
- fputs(reset, file);
- if (has_trailing_carriage_return)
- fputc('\r', file);
- if (has_trailing_newline)
- fputc('\n', file);
-}
-
-static void emit_add_line(const char *reset, struct emit_callback *ecbdata, const char *line, int len)
-{
- const char *ws = diff_get_color(ecbdata->color_diff, DIFF_WHITESPACE);
- const char *set = diff_get_color(ecbdata->color_diff, DIFF_FILE_NEW);
-
- if (!*ws)
- emit_line(ecbdata->file, set, reset, line, len);
- else {
- /* Emit just the prefix, then the rest. */
- emit_line(ecbdata->file, set, reset, line, ecbdata->nparents);
- ws_check_emit(line + ecbdata->nparents,
- len - ecbdata->nparents, ecbdata->ws_rule,
- ecbdata->file, set, reset, ws);
- }
-}
-
static unsigned long sane_truncate_line(struct emit_callback *ecb, char *line, unsigned long len)
{
const char *cp;
return allot - l;
}
+static void find_lno(const char *line, struct emit_callback *ecbdata)
+{
+ const char *p;
+ ecbdata->lno_in_preimage = 0;
+ ecbdata->lno_in_postimage = 0;
+ p = strchr(line, '-');
+ if (!p)
+ return; /* cannot happen */
+ ecbdata->lno_in_preimage = strtol(p + 1, NULL, 10);
+ p = strchr(p, '+');
+ if (!p)
+ return; /* cannot happen */
+ ecbdata->lno_in_postimage = strtol(p + 1, NULL, 10);
+}
+
static void fn_out_consume(void *priv, char *line, unsigned long len)
{
- int i;
- int color;
struct emit_callback *ecbdata = priv;
const char *meta = diff_get_color(ecbdata->color_diff, DIFF_METAINFO);
const char *plain = diff_get_color(ecbdata->color_diff, DIFF_PLAIN);
len = 1;
}
- /* This is not really necessary for now because
- * this codepath only deals with two-way diffs.
- */
- for (i = 0; i < len && line[i] == '@'; i++)
- ;
- if (2 <= i && i < len && line[i] == ' ') {
- ecbdata->nparents = i - 1;
+ if (line[0] == '@') {
+ if (ecbdata->diff_words)
+ diff_words_flush(ecbdata);
len = sane_truncate_line(ecbdata, line, len);
- emit_line(ecbdata->file,
- diff_get_color(ecbdata->color_diff, DIFF_FRAGINFO),
- reset, line, len);
+ find_lno(line, ecbdata);
+ emit_hunk_header(ecbdata, line, len);
if (line[len-1] != '\n')
putc('\n', ecbdata->file);
return;
}
- if (len < ecbdata->nparents) {
+ if (len < 1) {
emit_line(ecbdata->file, reset, reset, line, len);
return;
}
- color = DIFF_PLAIN;
- if (ecbdata->diff_words && ecbdata->nparents != 1)
- /* fall back to normal diff */
- free_diff_words_data(ecbdata);
if (ecbdata->diff_words) {
if (line[0] == '-') {
diff_words_append(line, len,
&ecbdata->diff_words->plus);
return;
}
- if (ecbdata->diff_words->minus.text.size ||
- ecbdata->diff_words->plus.text.size)
- diff_words_show(ecbdata->diff_words);
+ diff_words_flush(ecbdata);
line++;
len--;
emit_line(ecbdata->file, plain, reset, line, len);
return;
}
- for (i = 0; i < ecbdata->nparents && len; i++) {
- if (line[i] == '-')
- color = DIFF_FILE_OLD;
- else if (line[i] == '+')
- color = DIFF_FILE_NEW;
- }
- if (color != DIFF_FILE_NEW) {
- emit_line(ecbdata->file,
- diff_get_color(ecbdata->color_diff, color),
- reset, line, len);
- return;
+ if (line[0] != '+') {
+ const char *color =
+ diff_get_color(ecbdata->color_diff,
+ line[0] == '-' ? DIFF_FILE_OLD : DIFF_PLAIN);
+ ecbdata->lno_in_preimage++;
+ if (line[0] == ' ')
+ ecbdata->lno_in_postimage++;
+ emit_line(ecbdata->file, color, reset, line, len);
+ } else {
+ ecbdata->lno_in_postimage++;
+ emit_add_line(reset, ecbdata, line + 1, len - 1);
}
- emit_add_line(reset, ecbdata, line, len);
}
static char *pprint_rename(const char *a, const char *b)
total_files, adds, dels);
}
-static void show_shortstats(struct diffstat_t* data, struct diff_options *options)
+static void show_shortstats(struct diffstat_t *data, struct diff_options *options)
{
int i, adds = 0, dels = 0, total_files = data->nr;
struct diff_options *o;
unsigned ws_rule;
unsigned status;
- int trailing_blanks_start;
};
static int is_conflict_marker(const char *line, unsigned long len)
if (line[0] == '+') {
unsigned bad;
data->lineno++;
- if (!ws_blank_line(line + 1, len - 1, data->ws_rule))
- data->trailing_blanks_start = 0;
- else if (!data->trailing_blanks_start)
- data->trailing_blanks_start = data->lineno;
if (is_conflict_marker(line + 1, len - 1)) {
data->status |= 1;
fprintf(data->o->file,
data->o->file, set, reset, ws);
} else if (line[0] == ' ') {
data->lineno++;
- data->trailing_blanks_start = 0;
} else if (line[0] == '@') {
char *plus = strchr(line, '+');
if (plus)
data->lineno = strtol(plus, NULL, 10) - 1;
else
die("invalid diff");
- data->trailing_blanks_start = 0;
}
}
const char *a_prefix, *b_prefix;
const char *textconv_one = NULL, *textconv_two = NULL;
+ if (DIFF_OPT_TST(o, SUBMODULE_LOG) &&
+ (!one->mode || S_ISGITLINK(one->mode)) &&
+ (!two->mode || S_ISGITLINK(two->mode))) {
+ const char *del = diff_get_color_opt(o, DIFF_FILE_OLD);
+ const char *add = diff_get_color_opt(o, DIFF_FILE_NEW);
+ show_submodule_summary(o->file, one ? one->path : two->path,
+ one->sha1, two->sha1,
+ del, add, reset);
+ return;
+ }
+
if (DIFF_OPT_TST(o, ALLOW_TEXTCONV)) {
textconv_one = get_textconv(one);
textconv_two = get_textconv(two);
ecbdata.color_diff = DIFF_OPT_TST(o, COLOR_DIFF);
ecbdata.found_changesp = &o->found_changes;
ecbdata.ws_rule = whitespace_rule(name_b ? name_b : name_a);
+ if (ecbdata.ws_rule & WS_BLANK_AT_EOF)
+ check_blank_at_eof(&mf1, &mf2, &ecbdata);
ecbdata.file = o->file;
xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts;
xecfg.ctxlen = o->context;
xdi_diff_outf(&mf1, &mf2, checkdiff_consume, &data,
&xpp, &xecfg, &ecb);
- if ((data.ws_rule & WS_TRAILING_SPACE) &&
- data.trailing_blanks_start) {
- fprintf(o->file, "%s:%d: ends with blank lines.\n",
- data.filename, data.trailing_blanks_start);
- data.status = 1; /* report errors */
+ if (data.ws_rule & WS_BLANK_AT_EOF) {
+ struct emit_callback ecbdata;
+ int blank_at_eof;
+
+ ecbdata.ws_rule = data.ws_rule;
+ check_blank_at_eof(&mf1, &mf2, &ecbdata);
+ blank_at_eof = ecbdata.blank_at_eof_in_preimage;
+
+ if (blank_at_eof) {
+ static char *err;
+ if (!err)
+ err = whitespace_error_string(WS_BLANK_AT_EOF);
+ fprintf(o->file, "%s:%d: %s.\n",
+ data.filename, blank_at_eof, err);
+ data.status = 1; /* report errors */
+ }
}
}
free_and_return:
if (count > 1)
die("--name-only, --name-status, --check and -s are mutually exclusive");
+ /*
+ * Most of the time we can say "there are changes"
+ * only by checking if there are changed paths, but
+ * --ignore-whitespace* options force us to look
+ * inside contents.
+ */
+
+ if (DIFF_XDL_TST(options, IGNORE_WHITESPACE) ||
+ DIFF_XDL_TST(options, IGNORE_WHITESPACE_CHANGE) ||
+ DIFF_XDL_TST(options, IGNORE_WHITESPACE_AT_EOL))
+ DIFF_OPT_SET(options, DIFF_FROM_CONTENTS);
+ else
+ DIFF_OPT_CLR(options, DIFF_FROM_CONTENTS);
+
if (DIFF_OPT_TST(options, FIND_COPIES_HARDER))
options->detect_rename = DIFF_DETECT_COPY;
* to have found. It does not make sense not to return with
* exit code in such a case either.
*/
- if (DIFF_OPT_TST(options, QUIET)) {
+ if (DIFF_OPT_TST(options, QUICK)) {
options->output_format = DIFF_FORMAT_NO_OUTPUT;
DIFF_OPT_SET(options, EXIT_WITH_STATUS);
}
else if (!strcmp(arg, "--exit-code"))
DIFF_OPT_SET(options, EXIT_WITH_STATUS);
else if (!strcmp(arg, "--quiet"))
- DIFF_OPT_SET(options, QUIET);
+ DIFF_OPT_SET(options, QUICK);
else if (!strcmp(arg, "--ext-diff"))
DIFF_OPT_SET(options, ALLOW_EXTERNAL);
else if (!strcmp(arg, "--no-ext-diff"))
DIFF_OPT_CLR(options, ALLOW_TEXTCONV);
else if (!strcmp(arg, "--ignore-submodules"))
DIFF_OPT_SET(options, IGNORE_SUBMODULES);
+ else if (!strcmp(arg, "--submodule"))
+ DIFF_OPT_SET(options, SUBMODULE_LOG);
+ else if (!prefixcmp(arg, "--submodule=")) {
+ if (!strcmp(arg + 12, "log"))
+ DIFF_OPT_SET(options, SUBMODULE_LOG);
+ }
/* misc options */
else if (!strcmp(arg, "-z"))
num = 0;
scale = 1;
dot = 0;
- for(;;) {
+ for (;;) {
ch = *cp;
if ( !dot && ch == '.' ) {
scale = 1;
q->nr = q->alloc = 0;
if (options->close_file)
fclose(options->file);
+
+ /*
+ * Report the content-level differences with HAS_CHANGES;
+ * diff_addremove/diff_change does not set the bit when
+ * DIFF_FROM_CONTENTS is in effect (e.g. with -w).
+ */
+ if (DIFF_OPT_TST(options, DIFF_FROM_CONTENTS)) {
+ if (options->found_changes)
+ DIFF_OPT_SET(options, HAS_CHANGES);
+ else
+ DIFF_OPT_CLR(options, HAS_CHANGES);
+ }
}
static void diffcore_apply_filter(const char *filter)
diff_resolve_rename_copy();
diffcore_apply_filter(options->filter);
- if (diff_queued_diff.nr)
+ if (diff_queued_diff.nr && !DIFF_OPT_TST(options, DIFF_FROM_CONTENTS))
DIFF_OPT_SET(options, HAS_CHANGES);
else
DIFF_OPT_CLR(options, HAS_CHANGES);
fill_filespec(two, sha1, mode);
diff_queue(&diff_queued_diff, one, two);
- DIFF_OPT_SET(options, HAS_CHANGES);
+ if (!DIFF_OPT_TST(options, DIFF_FROM_CONTENTS))
+ DIFF_OPT_SET(options, HAS_CHANGES);
}
void diff_change(struct diff_options *options,
fill_filespec(two, new_sha1, new_mode);
diff_queue(&diff_queued_diff, one, two);
- DIFF_OPT_SET(options, HAS_CHANGES);
+ if (!DIFF_OPT_TST(options, DIFF_FROM_CONTENTS))
+ DIFF_OPT_SET(options, HAS_CHANGES);
}
void diff_unmerge(struct diff_options *options,
diff --combined diff.h
index 15fcecdecd9b033700902de44138eafdb66932eb,a7e7ccbd4230ca5cc65ea7e9255ecc345eb8f169..6f6d0ed01d9212289784cf7250358320f64b72cc
+++ b/diff.h
#define DIFF_OPT_COLOR_DIFF (1 << 8)
#define DIFF_OPT_COLOR_DIFF_WORDS (1 << 9)
#define DIFF_OPT_HAS_CHANGES (1 << 10)
- #define DIFF_OPT_QUIET (1 << 11)
+ #define DIFF_OPT_QUICK (1 << 11)
#define DIFF_OPT_NO_INDEX (1 << 12)
#define DIFF_OPT_ALLOW_EXTERNAL (1 << 13)
#define DIFF_OPT_EXIT_WITH_STATUS (1 << 14)
#define DIFF_OPT_DIRSTAT_CUMULATIVE (1 << 19)
#define DIFF_OPT_DIRSTAT_BY_FILE (1 << 20)
#define DIFF_OPT_ALLOW_TEXTCONV (1 << 21)
-
+ #define DIFF_OPT_DIFF_FROM_CONTENTS (1 << 22)
+#define DIFF_OPT_SUBMODULE_LOG (1 << 23)
+
#define DIFF_OPT_TST(opts, flag) ((opts)->flags & DIFF_OPT_##flag)
#define DIFF_OPT_SET(opts, flag) ((opts)->flags |= DIFF_OPT_##flag)
#define DIFF_OPT_CLR(opts, flag) ((opts)->flags &= ~DIFF_OPT_##flag)
DIFF_FILE_NEW = 5,
DIFF_COMMIT = 6,
DIFF_WHITESPACE = 7,
+ DIFF_FUNCINFO = 8,
};
const char *diff_get_color(int diff_use_color, enum color_diff ix);
#define diff_get_color_opt(o, ix) \
diff --combined revision.c
index a8a3c3a4bdf5bd9287cb820330e73e8c28b88564,b8afc7c2b56263135a416253a2afb93a2f12940d..25fa14d93e04531e8d1dde3d9ac8408670adf32a
--- 1/revision.c
--- 2/revision.c
+++ b/revision.c
revs->ignore_merges = 1;
revs->simplify_history = 1;
DIFF_OPT_SET(&revs->pruning, RECURSIVE);
- DIFF_OPT_SET(&revs->pruning, QUIET);
+ DIFF_OPT_SET(&revs->pruning, QUICK);
revs->pruning.add_remove = file_add_remove;
revs->pruning.change = file_change;
revs->lifo = 1;
return 0;
}
-void read_revisions_from_stdin(struct rev_info *revs)
+static void read_pathspec_from_stdin(struct rev_info *revs, struct strbuf *sb, const char ***prune_data)
{
- char line[1000];
+ const char **prune = *prune_data;
+ int prune_nr;
+ int prune_alloc;
- while (fgets(line, sizeof(line), stdin) != NULL) {
- int len = strlen(line);
- if (len && line[len - 1] == '\n')
- line[--len] = '\0';
+ /* count existing ones */
+ if (!prune)
+ prune_nr = 0;
+ else
+ for (prune_nr = 0; prune[prune_nr]; prune_nr++)
+ ;
+ prune_alloc = prune_nr; /* not really, but we do not know */
+
+ while (strbuf_getwholeline(sb, stdin, '\n') != EOF) {
+ int len = sb->len;
+ if (len && sb->buf[len - 1] == '\n')
+ sb->buf[--len] = '\0';
+ ALLOC_GROW(prune, prune_nr+1, prune_alloc);
+ prune[prune_nr++] = xstrdup(sb->buf);
+ }
+ if (prune) {
+ ALLOC_GROW(prune, prune_nr+1, prune_alloc);
+ prune[prune_nr] = NULL;
+ }
+ *prune_data = prune;
+}
+
+static void read_revisions_from_stdin(struct rev_info *revs, const char ***prune)
+{
+ struct strbuf sb;
+ int seen_dashdash = 0;
+
+ strbuf_init(&sb, 1000);
+ while (strbuf_getwholeline(&sb, stdin, '\n') != EOF) {
+ int len = sb.len;
+ if (len && sb.buf[len - 1] == '\n')
+ sb.buf[--len] = '\0';
if (!len)
break;
- if (line[0] == '-')
+ if (sb.buf[0] == '-') {
+ if (len == 2 && sb.buf[1] == '-') {
+ seen_dashdash = 1;
+ break;
+ }
die("options not supported in --stdin mode");
- if (handle_revision_arg(line, revs, 0, 1))
- die("bad revision '%s'", line);
+ }
+ if (handle_revision_arg(sb.buf, revs, 0, 1))
+ die("bad revision '%s'", sb.buf);
}
+ if (seen_dashdash)
+ read_pathspec_from_stdin(revs, &sb, prune);
+ strbuf_release(&sb);
}
static void add_grep(struct rev_info *revs, const char *ptn, enum grep_pat_token what)
if (!strcmp(arg, "--all") || !strcmp(arg, "--branches") ||
!strcmp(arg, "--tags") || !strcmp(arg, "--remotes") ||
!strcmp(arg, "--reflog") || !strcmp(arg, "--not") ||
- !strcmp(arg, "--no-walk") || !strcmp(arg, "--do-walk"))
+ !strcmp(arg, "--no-walk") || !strcmp(arg, "--do-walk") ||
+ !strcmp(arg, "--bisect"))
{
unkv[(*unkc)++] = arg;
return 1;
revs->simplify_by_decoration = 1;
revs->limited = 1;
revs->prune = 1;
- load_ref_decorations();
+ load_ref_decorations(DECORATE_SHORT_REFS);
} else if (!strcmp(arg, "--date-order")) {
revs->lifo = 0;
revs->topo_order = 1;
revs->simplify_history = 0;
} else if (!strcmp(arg, "--relative-date")) {
revs->date_mode = DATE_RELATIVE;
+ revs->date_mode_explicit = 1;
} else if (!strncmp(arg, "--date=", 7)) {
revs->date_mode = parse_date_format(arg + 7);
+ revs->date_mode_explicit = 1;
} else if (!strcmp(arg, "--log-size")) {
revs->show_log_size = 1;
}
ctx->argc -= n;
}
+static int for_each_bad_bisect_ref(each_ref_fn fn, void *cb_data)
+{
+ return for_each_ref_in("refs/bisect/bad", fn, cb_data);
+}
+
+static int for_each_good_bisect_ref(each_ref_fn fn, void *cb_data)
+{
+ return for_each_ref_in("refs/bisect/good", fn, cb_data);
+}
+
+static void append_prune_data(const char ***prune_data, const char **av)
+{
+ const char **prune = *prune_data;
+ int prune_nr;
+ int prune_alloc;
+
+ if (!prune) {
+ *prune_data = av;
+ return;
+ }
+
+ /* count existing ones */
+ for (prune_nr = 0; prune[prune_nr]; prune_nr++)
+ ;
+ prune_alloc = prune_nr; /* not really, but we do not know */
+
+ while (*av) {
+ ALLOC_GROW(prune, prune_nr+1, prune_alloc);
+ prune[prune_nr++] = *av;
+ av++;
+ }
+ if (prune) {
+ ALLOC_GROW(prune, prune_nr+1, prune_alloc);
+ prune[prune_nr] = NULL;
+ }
+ *prune_data = prune;
+}
+
/*
* Parse revision information, filling in the "rev_info" structure,
* and removing the used arguments from the argument list.
*/
int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def)
{
- int i, flags, left, seen_dashdash;
+ int i, flags, left, seen_dashdash, read_from_stdin;
+ const char **prune_data = NULL;
/* First, search for "--" */
seen_dashdash = 0;
argv[i] = NULL;
argc = i;
if (argv[i + 1])
- revs->prune_data = get_pathspec(revs->prefix, argv + i + 1);
+ prune_data = argv + i + 1;
seen_dashdash = 1;
break;
}
/* Second, deal with arguments and options */
flags = 0;
+ read_from_stdin = 0;
for (left = i = 1; i < argc; i++) {
const char *arg = argv[i];
if (*arg == '-') {
handle_refs(revs, flags, for_each_branch_ref);
continue;
}
+ if (!strcmp(arg, "--bisect")) {
+ handle_refs(revs, flags, for_each_bad_bisect_ref);
+ handle_refs(revs, flags ^ UNINTERESTING, for_each_good_bisect_ref);
+ revs->bisect = 1;
+ continue;
+ }
if (!strcmp(arg, "--tags")) {
handle_refs(revs, flags, for_each_tag_ref);
continue;
revs->no_walk = 0;
continue;
}
+ if (!strcmp(arg, "--stdin")) {
+ if (revs->disable_stdin) {
+ argv[left++] = arg;
+ continue;
+ }
+ if (read_from_stdin++)
+ die("--stdin given twice?");
+ read_revisions_from_stdin(revs, &prune_data);
+ continue;
+ }
opts = handle_revision_opt(revs, argc - i, argv + i, &left, argv);
if (opts > 0) {
for (j = i; j < argc; j++)
verify_filename(revs->prefix, argv[j]);
- revs->prune_data = get_pathspec(revs->prefix,
- argv + i);
+ append_prune_data(&prune_data, argv + i);
break;
}
}
+ if (prune_data)
+ revs->prune_data = get_pathspec(revs->prefix, prune_data);
+
if (revs->def == NULL)
revs->def = def;
if (revs->show_merge)
return (revs->rewrite_parents || revs->children.name);
}
-enum commit_action simplify_commit(struct rev_info *revs, struct commit *commit)
+enum commit_action get_commit_action(struct rev_info *revs, struct commit *commit)
{
if (commit->object.flags & SHOWN)
return commit_ignore;
if (!commit->parents || !commit->parents->next)
return commit_ignore;
}
- if (want_ancestry(revs) && rewrite_parents(revs, commit) < 0)
- return commit_error;
}
return commit_show;
}
+enum commit_action simplify_commit(struct rev_info *revs, struct commit *commit)
+{
+ enum commit_action action = get_commit_action(revs, commit);
+
+ if (action == commit_show &&
+ !revs->show_all &&
+ revs->prune && revs->dense && want_ancestry(revs)) {
+ if (rewrite_parents(revs, commit) < 0)
+ return commit_error;
+ }
+ return action;
+}
+
static struct commit *get_revision_1(struct rev_info *revs)
{
if (!revs->commits)