#include "diffcore.h"
#include "quote.h"
#include "xdiff-interface.h"
+ #include "log-tree.h"
static int uninteresting(struct diff_filepair *p)
{
sline->p_lno[i] = sline->p_lno[j];
}
+ static void dump_quoted_path(const char *prefix, const char *path)
+ {
+ fputs(prefix, stdout);
+ if (quote_c_style(path, NULL, NULL, 0))
+ quote_c_style(path, NULL, stdout, 0);
+ else
+ printf("%s", path);
+ putchar('\n');
+ }
+
static int show_patch_diff(struct combine_diff_path *elem, int num_parent,
- int dense, const char *header,
- struct diff_options *opt)
+ int dense, struct rev_info *rev)
{
+ struct diff_options *opt = &rev->diffopt;
unsigned long result_size, cnt, lno;
- char *result, *cp, *ep;
+ char *result, *cp;
struct sline *sline; /* survived lines */
int mode_differs = 0;
int i, show_hunks, shown_header = 0;
cnt++; /* incomplete line */
sline = xcalloc(cnt+2, sizeof(*sline));
- ep = result;
sline[0].bol = result;
for (lno = 0; lno <= cnt + 1; lno++) {
sline[lno].lost_tail = &sline[lno].lost_head;
if (show_hunks || mode_differs || working_tree_file) {
const char *abb;
- if (header) {
- shown_header++;
- printf("%s%c", header, opt->line_termination);
- }
- printf("diff --%s ", dense ? "cc" : "combined");
- if (quote_c_style(elem->path, NULL, NULL, 0))
- quote_c_style(elem->path, NULL, stdout, 0);
- else
- printf("%s", elem->path);
- putchar('\n');
+ if (rev->loginfo)
+ show_log(rev, rev->loginfo, "\n");
+ dump_quoted_path(dense ? "diff --cc " : "diff --combined ", elem->path);
printf("index ");
for (i = 0; i < num_parent; i++) {
abb = find_unique_abbrev(elem->parent[i].sha1,
}
putchar('\n');
}
+ dump_quoted_path("--- a/", elem->path);
+ dump_quoted_path("+++ b/", elem->path);
dump_sline(sline, cnt, num_parent);
}
free(result);
#define COLONS "::::::::::::::::::::::::::::::::"
- static void show_raw_diff(struct combine_diff_path *p, int num_parent, const char *header, struct diff_options *opt)
+ static void show_raw_diff(struct combine_diff_path *p, int num_parent, struct rev_info *rev)
{
- int i, offset, mod_type = 'A';
+ struct diff_options *opt = &rev->diffopt;
+ int i, offset;
const char *prefix;
int line_termination, inter_name_termination;
if (!line_termination)
inter_name_termination = 0;
- if (header)
- printf("%s%c", header, line_termination);
+ if (rev->loginfo)
+ show_log(rev, rev->loginfo, "\n");
- for (i = 0; i < num_parent; i++) {
- if (p->parent[i].mode)
- mod_type = 'M';
- }
- if (!p->mode)
- mod_type = 'D';
-
if (opt->output_format == DIFF_FORMAT_RAW) {
offset = strlen(COLONS) - num_parent;
if (offset < 0)
}
}
- int show_combined_diff(struct combine_diff_path *p,
+ void show_combined_diff(struct combine_diff_path *p,
int num_parent,
int dense,
- const char *header,
- struct diff_options *opt)
+ struct rev_info *rev)
{
+ struct diff_options *opt = &rev->diffopt;
if (!p->len)
- return 0;
+ return;
switch (opt->output_format) {
case DIFF_FORMAT_RAW:
case DIFF_FORMAT_NAME_STATUS:
case DIFF_FORMAT_NAME:
- show_raw_diff(p, num_parent, header, opt);
- return 1;
-
- default:
+ show_raw_diff(p, num_parent, rev);
+ return;
case DIFF_FORMAT_PATCH:
- return show_patch_diff(p, num_parent, dense, header, opt);
+ show_patch_diff(p, num_parent, dense, rev);
+ return;
+ default:
+ return;
}
}
- const char *diff_tree_combined_merge(const unsigned char *sha1,
- const char *header, int dense,
- struct diff_options *opt)
+ void diff_tree_combined_merge(const unsigned char *sha1,
+ int dense, struct rev_info *rev)
{
+ struct diff_options *opt = &rev->diffopt;
struct commit *commit = lookup_commit(sha1);
struct diff_options diffopts;
struct commit_list *parents;
struct combine_diff_path *p, *paths = NULL;
int num_parent, i, num_paths;
+ int do_diffstat;
+ do_diffstat = (opt->output_format == DIFF_FORMAT_DIFFSTAT ||
+ opt->with_stat);
diffopts = *opt;
- diffopts.output_format = DIFF_FORMAT_NO_OUTPUT;
diffopts.with_raw = 0;
+ diffopts.with_stat = 0;
diffopts.recursive = 1;
/* count parents */
parents;
parents = parents->next, i++) {
struct commit *parent = parents->item;
+ /* show stat against the first parent even
+ * when doing combined diff.
+ */
+ if (i == 0 && do_diffstat)
+ diffopts.output_format = DIFF_FORMAT_DIFFSTAT;
+ else
+ diffopts.output_format = DIFF_FORMAT_NO_OUTPUT;
diff_tree_sha1(parent->object.sha1, commit->object.sha1, "",
&diffopts);
diffcore_std(&diffopts);
paths = intersect_paths(paths, i, num_parent);
+
+ if (do_diffstat && rev->loginfo)
+ show_log(rev, rev->loginfo,
+ opt->with_stat ? "---\n" : "\n");
diff_flush(&diffopts);
+ if (opt->with_stat)
+ putchar('\n');
}
/* find out surviving paths */
int saved_format = opt->output_format;
opt->output_format = DIFF_FORMAT_RAW;
for (p = paths; p; p = p->next) {
- if (show_combined_diff(p, num_parent, dense,
- header, opt))
- header = NULL;
+ show_combined_diff(p, num_parent, dense, rev);
}
opt->output_format = saved_format;
putchar(opt->line_termination);
}
for (p = paths; p; p = p->next) {
- if (show_combined_diff(p, num_parent, dense,
- header, opt))
- header = NULL;
+ show_combined_diff(p, num_parent, dense, rev);
}
}
paths = paths->next;
free(tmp);
}
- return header;
}
#include "diff.h"
#include "revision.h"
-/* bits #0-6 in revision.h */
+/* bits #0-15 in revision.h */
-#define COUNTED (1u<<7)
+#define COUNTED (1u<<16)
static const char rev_list_usage[] =
"git-rev-list [OPTION] <commit-id>... [ -- paths... ]\n"
static int bisect_list = 0;
static int show_timestamp = 0;
static int hdr_termination = 0;
+ static const char *header_prefix;
static void show_commit(struct commit *commit)
{
if (show_timestamp)
printf("%lu ", commit->date);
- if (*revs.header_prefix)
- fputs(revs.header_prefix, stdout);
+ if (header_prefix)
+ fputs(header_prefix, stdout);
if (commit->object.flags & BOUNDARY)
putchar('-');
if (revs.abbrev_commit && revs.abbrev)
/* The command line has a --pretty */
hdr_termination = '\n';
if (revs.commit_format == CMIT_FMT_ONELINE)
- revs.header_prefix = "";
+ header_prefix = "";
else
- revs.header_prefix = "commit ";
+ header_prefix = "commit ";
}
+ else if (revs.verbose_header)
+ /* Only --header was specified */
+ revs.commit_format = CMIT_FMT_RAW;
list = revs.commits;
save_commit_buffer = revs.verbose_header;
track_object_refs = 0;
+ if (bisect_list)
+ revs.limited = 1;
prepare_revision_walk(&revs);
if (revs.tree_objects)
revs->topo_setter = topo_sort_default_setter;
revs->topo_getter = topo_sort_default_getter;
- revs->header_prefix = "";
revs->commit_format = CMIT_FMT_DEFAULT;
diff_setup(&revs->diffopt);
}
if (!strcmp(arg, "-v")) {
revs->verbose_header = 1;
- revs->header_prefix = "diff-tree ";
continue;
}
if (!strncmp(arg, "--pretty", 8)) {
revs->verbose_header = 1;
- revs->header_prefix = "diff-tree ";
revs->commit_format = get_commit_format(arg+8);
continue;
}
}
}
+static void mark_boundary_to_show(struct commit *commit)
+{
+ struct commit_list *p = commit->parents;
+ while (p) {
+ commit = p->item;
+ p = p->next;
+ if (commit->object.flags & BOUNDARY)
+ commit->object.flags |= BOUNDARY_SHOW;
+ }
+}
+
struct commit *get_revision(struct rev_info *revs)
{
struct commit_list *list = revs->commits;
}
if (commit->object.flags & SHOWN)
continue;
- if (!(commit->object.flags & BOUNDARY) &&
- (commit->object.flags & UNINTERESTING))
+
+ /* 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,
+ * and there is no point showing boundary parents that
+ * are not shown. After rewrite_parents() rewrites the
+ * parents of a commit that is shown, we mark the boundary
+ * parents with BOUNDARY_SHOW.
+ */
+ if (commit->object.flags & BOUNDARY_SHOW) {
+ commit->object.flags |= SHOWN;
+ return commit;
+ }
+ if (commit->object.flags & UNINTERESTING)
continue;
if (revs->min_age != -1 && (commit->date > revs->min_age))
continue;
if (revs->parents)
rewrite_parents(revs, commit);
}
+ if (revs->boundary)
+ mark_boundary_to_show(commit);
commit->object.flags |= SHOWN;
return commit;
} while (revs->commits);