зеркало из https://github.com/microsoft/git.git
Merge branch 'js/log-to-diffopt-file'
The commands in the "log/diff" family have had an FILE* pointer in the data structure they pass around for a long time, but some codepaths used to always write to the standard output. As a preparatory step to make "git format-patch" available to the internal callers, these codepaths have been updated to consistently write into that FILE* instead. * js/log-to-diffopt-file: mingw: fix the shortlog --output=<file> test diff: do not color output when --color=auto and --output=<file> is given t4211: ensure that log respects --output=<file> shortlog: respect the --output=<file> setting format-patch: use stdout directly format-patch: avoid freopen() format-patch: explicitly switch off color when writing to files shortlog: support outputting to streams other than stdout graph: respect the diffopt.file setting line-log: respect diffopt's configured output file stream log-tree: respect diffopt's configured output file stream log: prepare log/log-tree to reuse the diffopt.close_file attribute
This commit is contained in:
Коммит
63641fb071
|
@ -238,16 +238,17 @@ static void show_early_header(struct rev_info *rev, const char *stage, int nr)
|
|||
if (rev->commit_format != CMIT_FMT_ONELINE)
|
||||
putchar(rev->diffopt.line_termination);
|
||||
}
|
||||
printf(_("Final output: %d %s\n"), nr, stage);
|
||||
fprintf(rev->diffopt.file, _("Final output: %d %s\n"), nr, stage);
|
||||
}
|
||||
|
||||
static struct itimerval early_output_timer;
|
||||
|
||||
static void log_show_early(struct rev_info *revs, struct commit_list *list)
|
||||
{
|
||||
int i = revs->early_output;
|
||||
int i = revs->early_output, close_file = revs->diffopt.close_file;
|
||||
int show_header = 1;
|
||||
|
||||
revs->diffopt.close_file = 0;
|
||||
sort_in_topological_order(&list, revs->sort_order);
|
||||
while (list && i) {
|
||||
struct commit *commit = list->item;
|
||||
|
@ -264,14 +265,19 @@ static void log_show_early(struct rev_info *revs, struct commit_list *list)
|
|||
case commit_ignore:
|
||||
break;
|
||||
case commit_error:
|
||||
if (close_file)
|
||||
fclose(revs->diffopt.file);
|
||||
return;
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
/* Did we already get enough commits for the early output? */
|
||||
if (!i)
|
||||
if (!i) {
|
||||
if (close_file)
|
||||
fclose(revs->diffopt.file);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* ..if no, then repeat it twice a second until we
|
||||
|
@ -333,7 +339,7 @@ static int cmd_log_walk(struct rev_info *rev)
|
|||
{
|
||||
struct commit *commit;
|
||||
int saved_nrl = 0;
|
||||
int saved_dcctc = 0;
|
||||
int saved_dcctc = 0, close_file = rev->diffopt.close_file;
|
||||
|
||||
if (rev->early_output)
|
||||
setup_early_output(rev);
|
||||
|
@ -349,6 +355,7 @@ static int cmd_log_walk(struct rev_info *rev)
|
|||
* and HAS_CHANGES being accumulated in rev->diffopt, so be careful to
|
||||
* retain that state information if replacing rev->diffopt in this loop
|
||||
*/
|
||||
rev->diffopt.close_file = 0;
|
||||
while ((commit = get_revision(rev)) != NULL) {
|
||||
if (!log_tree_commit(rev, commit) && rev->max_count >= 0)
|
||||
/*
|
||||
|
@ -369,6 +376,8 @@ static int cmd_log_walk(struct rev_info *rev)
|
|||
}
|
||||
rev->diffopt.degraded_cc_to_c = saved_dcctc;
|
||||
rev->diffopt.needed_rename_limit = saved_nrl;
|
||||
if (close_file)
|
||||
fclose(rev->diffopt.file);
|
||||
|
||||
if (rev->diffopt.output_format & DIFF_FORMAT_CHECKDIFF &&
|
||||
DIFF_OPT_TST(&rev->diffopt, CHECK_FAILED)) {
|
||||
|
@ -451,7 +460,7 @@ static void show_tagger(char *buf, int len, struct rev_info *rev)
|
|||
pp.fmt = rev->commit_format;
|
||||
pp.date_mode = rev->date_mode;
|
||||
pp_user_info(&pp, "Tagger", &out, buf, get_log_output_encoding());
|
||||
printf("%s", out.buf);
|
||||
fprintf(rev->diffopt.file, "%s", out.buf);
|
||||
strbuf_release(&out);
|
||||
}
|
||||
|
||||
|
@ -462,7 +471,7 @@ static int show_blob_object(const unsigned char *sha1, struct rev_info *rev, con
|
|||
char *buf;
|
||||
unsigned long size;
|
||||
|
||||
fflush(stdout);
|
||||
fflush(rev->diffopt.file);
|
||||
if (!DIFF_OPT_TOUCHED(&rev->diffopt, ALLOW_TEXTCONV) ||
|
||||
!DIFF_OPT_TST(&rev->diffopt, ALLOW_TEXTCONV))
|
||||
return stream_blob_to_fd(1, sha1, NULL, 0);
|
||||
|
@ -502,7 +511,7 @@ static int show_tag_object(const unsigned char *sha1, struct rev_info *rev)
|
|||
}
|
||||
|
||||
if (offset < size)
|
||||
fwrite(buf + offset, size - offset, 1, stdout);
|
||||
fwrite(buf + offset, size - offset, 1, rev->diffopt.file);
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
@ -511,7 +520,8 @@ static int show_tree_object(const unsigned char *sha1,
|
|||
struct strbuf *base,
|
||||
const char *pathname, unsigned mode, int stage, void *context)
|
||||
{
|
||||
printf("%s%s\n", pathname, S_ISDIR(mode) ? "/" : "");
|
||||
FILE *file = context;
|
||||
fprintf(file, "%s%s\n", pathname, S_ISDIR(mode) ? "/" : "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -571,7 +581,7 @@ int cmd_show(int argc, const char **argv, const char *prefix)
|
|||
|
||||
if (rev.shown_one)
|
||||
putchar('\n');
|
||||
printf("%stag %s%s\n",
|
||||
fprintf(rev.diffopt.file, "%stag %s%s\n",
|
||||
diff_get_color_opt(&rev.diffopt, DIFF_COMMIT),
|
||||
t->tag,
|
||||
diff_get_color_opt(&rev.diffopt, DIFF_RESET));
|
||||
|
@ -590,12 +600,12 @@ int cmd_show(int argc, const char **argv, const char *prefix)
|
|||
case OBJ_TREE:
|
||||
if (rev.shown_one)
|
||||
putchar('\n');
|
||||
printf("%stree %s%s\n\n",
|
||||
fprintf(rev.diffopt.file, "%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, &match_all,
|
||||
show_tree_object, NULL);
|
||||
show_tree_object, rev.diffopt.file);
|
||||
rev.shown_one = 1;
|
||||
break;
|
||||
case OBJ_COMMIT:
|
||||
|
@ -801,11 +811,10 @@ static int git_format_config(const char *var, const char *value, void *cb)
|
|||
return git_log_config(var, value, cb);
|
||||
}
|
||||
|
||||
static FILE *realstdout = NULL;
|
||||
static const char *output_directory = NULL;
|
||||
static int outdir_offset;
|
||||
|
||||
static int reopen_stdout(struct commit *commit, const char *subject,
|
||||
static int open_next_file(struct commit *commit, const char *subject,
|
||||
struct rev_info *rev, int quiet)
|
||||
{
|
||||
struct strbuf filename = STRBUF_INIT;
|
||||
|
@ -827,9 +836,9 @@ static int reopen_stdout(struct commit *commit, const char *subject,
|
|||
fmt_output_subject(&filename, subject, rev);
|
||||
|
||||
if (!quiet)
|
||||
fprintf(realstdout, "%s\n", filename.buf + outdir_offset);
|
||||
printf("%s\n", filename.buf + outdir_offset);
|
||||
|
||||
if (freopen(filename.buf, "w", stdout) == NULL)
|
||||
if ((rev->diffopt.file = fopen(filename.buf, "w")) == NULL)
|
||||
return error(_("Cannot open patch file %s"), filename.buf);
|
||||
|
||||
strbuf_release(&filename);
|
||||
|
@ -888,15 +897,15 @@ static void gen_message_id(struct rev_info *info, char *base)
|
|||
info->message_id = strbuf_detach(&buf, NULL);
|
||||
}
|
||||
|
||||
static void print_signature(void)
|
||||
static void print_signature(FILE *file)
|
||||
{
|
||||
if (!signature || !*signature)
|
||||
return;
|
||||
|
||||
printf("-- \n%s", signature);
|
||||
fprintf(file, "-- \n%s", signature);
|
||||
if (signature[strlen(signature)-1] != '\n')
|
||||
putchar('\n');
|
||||
putchar('\n');
|
||||
putc('\n', file);
|
||||
putc('\n', file);
|
||||
}
|
||||
|
||||
static void add_branch_description(struct strbuf *buf, const char *branch_name)
|
||||
|
@ -965,7 +974,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
|
|||
committer = git_committer_info(0);
|
||||
|
||||
if (!use_stdout &&
|
||||
reopen_stdout(NULL, rev->numbered_files ? NULL : "cover-letter", rev, quiet))
|
||||
open_next_file(NULL, rev->numbered_files ? NULL : "cover-letter", rev, quiet))
|
||||
return;
|
||||
|
||||
log_write_email_headers(rev, head, &pp.subject, &pp.after_subject,
|
||||
|
@ -988,7 +997,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
|
|||
pp_title_line(&pp, &msg, &sb, encoding, need_8bit_cte);
|
||||
pp_remainder(&pp, &msg, &sb, 0);
|
||||
add_branch_description(&sb, branch_name);
|
||||
printf("%s\n", sb.buf);
|
||||
fprintf(rev->diffopt.file, "%s\n", sb.buf);
|
||||
|
||||
strbuf_release(&sb);
|
||||
|
||||
|
@ -997,6 +1006,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
|
|||
log.wrap = 72;
|
||||
log.in1 = 2;
|
||||
log.in2 = 4;
|
||||
log.file = rev->diffopt.file;
|
||||
for (i = 0; i < nr; i++)
|
||||
shortlog_add_commit(&log, list[i]);
|
||||
|
||||
|
@ -1019,8 +1029,8 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
|
|||
diffcore_std(&opts);
|
||||
diff_flush(&opts);
|
||||
|
||||
printf("\n");
|
||||
print_signature();
|
||||
fprintf(rev->diffopt.file, "\n");
|
||||
print_signature(rev->diffopt.file);
|
||||
}
|
||||
|
||||
static const char *clean_message_id(const char *msg_id)
|
||||
|
@ -1330,7 +1340,7 @@ static void prepare_bases(struct base_tree_info *bases,
|
|||
}
|
||||
}
|
||||
|
||||
static void print_bases(struct base_tree_info *bases)
|
||||
static void print_bases(struct base_tree_info *bases, FILE *file)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -1339,11 +1349,11 @@ static void print_bases(struct base_tree_info *bases)
|
|||
return;
|
||||
|
||||
/* Show the base commit */
|
||||
printf("base-commit: %s\n", oid_to_hex(&bases->base_commit));
|
||||
fprintf(file, "base-commit: %s\n", oid_to_hex(&bases->base_commit));
|
||||
|
||||
/* Show the prerequisite patches */
|
||||
for (i = bases->nr_patch_id - 1; i >= 0; i--)
|
||||
printf("prerequisite-patch-id: %s\n", oid_to_hex(&bases->patch_id[i]));
|
||||
fprintf(file, "prerequisite-patch-id: %s\n", oid_to_hex(&bases->patch_id[i]));
|
||||
|
||||
free(bases->patch_id);
|
||||
bases->nr_patch_id = 0;
|
||||
|
@ -1575,6 +1585,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
|||
setup_pager();
|
||||
|
||||
if (output_directory) {
|
||||
if (rev.diffopt.use_color != GIT_COLOR_ALWAYS)
|
||||
rev.diffopt.use_color = GIT_COLOR_NEVER;
|
||||
if (use_stdout)
|
||||
die(_("standard output, or directory, which one?"));
|
||||
if (mkdir(output_directory, 0777) < 0 && errno != EEXIST)
|
||||
|
@ -1632,9 +1644,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
|||
get_patch_ids(&rev, &ids);
|
||||
}
|
||||
|
||||
if (!use_stdout)
|
||||
realstdout = xfdopen(xdup(1), "w");
|
||||
|
||||
if (prepare_revision_walk(&rev))
|
||||
die(_("revision walk setup failed"));
|
||||
rev.boundary = 1;
|
||||
|
@ -1699,7 +1708,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
|||
gen_message_id(&rev, "cover");
|
||||
make_cover_letter(&rev, use_stdout,
|
||||
origin, nr, list, branch_name, quiet);
|
||||
print_bases(&bases);
|
||||
print_bases(&bases, rev.diffopt.file);
|
||||
total++;
|
||||
start_number--;
|
||||
}
|
||||
|
@ -1745,7 +1754,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
|||
}
|
||||
|
||||
if (!use_stdout &&
|
||||
reopen_stdout(rev.numbered_files ? NULL : commit, NULL, &rev, quiet))
|
||||
open_next_file(rev.numbered_files ? NULL : commit, NULL, &rev, quiet))
|
||||
die(_("Failed to create output files"));
|
||||
shown = log_tree_commit(&rev, commit);
|
||||
free_commit_buffer(commit);
|
||||
|
@ -1760,15 +1769,15 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
|||
rev.shown_one = 0;
|
||||
if (shown) {
|
||||
if (rev.mime_boundary)
|
||||
printf("\n--%s%s--\n\n\n",
|
||||
fprintf(rev.diffopt.file, "\n--%s%s--\n\n\n",
|
||||
mime_boundary_leader,
|
||||
rev.mime_boundary);
|
||||
else
|
||||
print_signature();
|
||||
print_bases(&bases);
|
||||
print_signature(rev.diffopt.file);
|
||||
print_bases(&bases, rev.diffopt.file);
|
||||
}
|
||||
if (!use_stdout)
|
||||
fclose(stdout);
|
||||
fclose(rev.diffopt.file);
|
||||
}
|
||||
free(list);
|
||||
free(branch_name);
|
||||
|
@ -1800,15 +1809,15 @@ static const char * const cherry_usage[] = {
|
|||
};
|
||||
|
||||
static void print_commit(char sign, struct commit *commit, int verbose,
|
||||
int abbrev)
|
||||
int abbrev, FILE *file)
|
||||
{
|
||||
if (!verbose) {
|
||||
printf("%c %s\n", sign,
|
||||
fprintf(file, "%c %s\n", sign,
|
||||
find_unique_abbrev(commit->object.oid.hash, abbrev));
|
||||
} else {
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
pp_commit_easy(CMIT_FMT_ONELINE, commit, &buf);
|
||||
printf("%c %s %s\n", sign,
|
||||
fprintf(file, "%c %s %s\n", sign,
|
||||
find_unique_abbrev(commit->object.oid.hash, abbrev),
|
||||
buf.buf);
|
||||
strbuf_release(&buf);
|
||||
|
@ -1889,7 +1898,7 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
|
|||
commit = list->item;
|
||||
if (has_commit_patch_id(commit, &ids))
|
||||
sign = '-';
|
||||
print_commit(sign, commit, verbose, abbrev);
|
||||
print_commit(sign, commit, verbose, abbrev, revs.diffopt.file);
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
|
|
|
@ -276,6 +276,7 @@ parse_done:
|
|||
|
||||
log.user_format = rev.commit_format == CMIT_FMT_USERFORMAT;
|
||||
log.abbrev = rev.abbrev;
|
||||
log.file = rev.diffopt.file;
|
||||
|
||||
/* assume HEAD if from a tty */
|
||||
if (!nongit && !rev.pending.nr && isatty(0))
|
||||
|
@ -289,6 +290,8 @@ parse_done:
|
|||
get_from_rev(&rev, &log);
|
||||
|
||||
shortlog_output(&log);
|
||||
if (log.file != stdout)
|
||||
fclose(log.file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -310,22 +313,24 @@ void shortlog_output(struct shortlog *log)
|
|||
for (i = 0; i < log->list.nr; i++) {
|
||||
const struct string_list_item *item = &log->list.items[i];
|
||||
if (log->summary) {
|
||||
printf("%6d\t%s\n", (int)UTIL_TO_INT(item), item->string);
|
||||
fprintf(log->file, "%6d\t%s\n",
|
||||
(int)UTIL_TO_INT(item), item->string);
|
||||
} else {
|
||||
struct string_list *onelines = item->util;
|
||||
printf("%s (%d):\n", item->string, onelines->nr);
|
||||
fprintf(log->file, "%s (%d):\n",
|
||||
item->string, onelines->nr);
|
||||
for (j = onelines->nr - 1; j >= 0; j--) {
|
||||
const char *msg = onelines->items[j].string;
|
||||
|
||||
if (log->wrap_lines) {
|
||||
strbuf_reset(&sb);
|
||||
add_wrapped_shortlog_msg(&sb, msg, log);
|
||||
fwrite(sb.buf, sb.len, 1, stdout);
|
||||
fwrite(sb.buf, sb.len, 1, log->file);
|
||||
}
|
||||
else
|
||||
printf(" %s\n", msg);
|
||||
fprintf(log->file, " %s\n", msg);
|
||||
}
|
||||
putchar('\n');
|
||||
putc('\n', log->file);
|
||||
onelines->strdup_strings = 1;
|
||||
string_list_clear(onelines, 0);
|
||||
free(onelines);
|
||||
|
|
2
diff.c
2
diff.c
|
@ -3977,6 +3977,8 @@ int diff_opt_parse(struct diff_options *options,
|
|||
if (!options->file)
|
||||
die_errno("Could not open '%s'", path);
|
||||
options->close_file = 1;
|
||||
if (options->use_color != GIT_COLOR_ALWAYS)
|
||||
options->use_color = GIT_COLOR_NEVER;
|
||||
return argcount;
|
||||
} else
|
||||
return 0;
|
||||
|
|
30
graph.c
30
graph.c
|
@ -17,8 +17,8 @@
|
|||
static void graph_padding_line(struct git_graph *graph, struct strbuf *sb);
|
||||
|
||||
/*
|
||||
* Print a strbuf to stdout. If the graph is non-NULL, all lines but the
|
||||
* first will be prefixed with the graph output.
|
||||
* Print a strbuf. If the graph is non-NULL, all lines but the first will be
|
||||
* prefixed with the graph output.
|
||||
*
|
||||
* If the strbuf ends with a newline, the output will end after this
|
||||
* newline. A new graph line will not be printed after the final newline.
|
||||
|
@ -1200,9 +1200,10 @@ void graph_show_commit(struct git_graph *graph)
|
|||
|
||||
while (!shown_commit_line && !graph_is_commit_finished(graph)) {
|
||||
shown_commit_line = graph_next_line(graph, &msgbuf);
|
||||
fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout);
|
||||
fwrite(msgbuf.buf, sizeof(char), msgbuf.len,
|
||||
graph->revs->diffopt.file);
|
||||
if (!shown_commit_line)
|
||||
putchar('\n');
|
||||
putc('\n', graph->revs->diffopt.file);
|
||||
strbuf_setlen(&msgbuf, 0);
|
||||
}
|
||||
|
||||
|
@ -1217,7 +1218,7 @@ void graph_show_oneline(struct git_graph *graph)
|
|||
return;
|
||||
|
||||
graph_next_line(graph, &msgbuf);
|
||||
fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout);
|
||||
fwrite(msgbuf.buf, sizeof(char), msgbuf.len, graph->revs->diffopt.file);
|
||||
strbuf_release(&msgbuf);
|
||||
}
|
||||
|
||||
|
@ -1229,7 +1230,7 @@ void graph_show_padding(struct git_graph *graph)
|
|||
return;
|
||||
|
||||
graph_padding_line(graph, &msgbuf);
|
||||
fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout);
|
||||
fwrite(msgbuf.buf, sizeof(char), msgbuf.len, graph->revs->diffopt.file);
|
||||
strbuf_release(&msgbuf);
|
||||
}
|
||||
|
||||
|
@ -1246,12 +1247,13 @@ int graph_show_remainder(struct git_graph *graph)
|
|||
|
||||
for (;;) {
|
||||
graph_next_line(graph, &msgbuf);
|
||||
fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout);
|
||||
fwrite(msgbuf.buf, sizeof(char), msgbuf.len,
|
||||
graph->revs->diffopt.file);
|
||||
strbuf_setlen(&msgbuf, 0);
|
||||
shown = 1;
|
||||
|
||||
if (!graph_is_commit_finished(graph))
|
||||
putchar('\n');
|
||||
putc('\n', graph->revs->diffopt.file);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
@ -1266,7 +1268,8 @@ static void graph_show_strbuf(struct git_graph *graph, struct strbuf const *sb)
|
|||
char *p;
|
||||
|
||||
if (!graph) {
|
||||
fwrite(sb->buf, sizeof(char), sb->len, stdout);
|
||||
fwrite(sb->buf, sizeof(char), sb->len,
|
||||
graph->revs->diffopt.file);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1284,7 +1287,7 @@ static void graph_show_strbuf(struct git_graph *graph, struct strbuf const *sb)
|
|||
} else {
|
||||
len = (sb->buf + sb->len) - p;
|
||||
}
|
||||
fwrite(p, sizeof(char), len, stdout);
|
||||
fwrite(p, sizeof(char), len, graph->revs->diffopt.file);
|
||||
if (next_p && *next_p != '\0')
|
||||
graph_show_oneline(graph);
|
||||
p = next_p;
|
||||
|
@ -1304,7 +1307,8 @@ void graph_show_commit_msg(struct git_graph *graph,
|
|||
* CMIT_FMT_USERFORMAT are already missing a terminating
|
||||
* newline. All of the other formats should have it.
|
||||
*/
|
||||
fwrite(sb->buf, sizeof(char), sb->len, stdout);
|
||||
fwrite(sb->buf, sizeof(char), sb->len,
|
||||
graph->revs->diffopt.file);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1325,7 +1329,7 @@ void graph_show_commit_msg(struct git_graph *graph,
|
|||
* new line.
|
||||
*/
|
||||
if (!newline_terminated)
|
||||
putchar('\n');
|
||||
putc('\n', graph->revs->diffopt.file);
|
||||
|
||||
graph_show_remainder(graph);
|
||||
|
||||
|
@ -1333,6 +1337,6 @@ void graph_show_commit_msg(struct git_graph *graph,
|
|||
* If sb ends with a newline, our output should too.
|
||||
*/
|
||||
if (newline_terminated)
|
||||
putchar('\n');
|
||||
putc('\n', graph->revs->diffopt.file);
|
||||
}
|
||||
}
|
||||
|
|
34
line-log.c
34
line-log.c
|
@ -840,7 +840,7 @@ static char *get_nth_line(long line, unsigned long *ends, void *data)
|
|||
|
||||
static void print_line(const char *prefix, char first,
|
||||
long line, unsigned long *ends, void *data,
|
||||
const char *color, const char *reset)
|
||||
const char *color, const char *reset, FILE *file)
|
||||
{
|
||||
char *begin = get_nth_line(line, ends, data);
|
||||
char *end = get_nth_line(line+1, ends, data);
|
||||
|
@ -851,14 +851,14 @@ static void print_line(const char *prefix, char first,
|
|||
had_nl = 1;
|
||||
}
|
||||
|
||||
fputs(prefix, stdout);
|
||||
fputs(color, stdout);
|
||||
putchar(first);
|
||||
fwrite(begin, 1, end-begin, stdout);
|
||||
fputs(reset, stdout);
|
||||
putchar('\n');
|
||||
fputs(prefix, file);
|
||||
fputs(color, file);
|
||||
putc(first, file);
|
||||
fwrite(begin, 1, end-begin, file);
|
||||
fputs(reset, file);
|
||||
putc('\n', file);
|
||||
if (!had_nl)
|
||||
fputs("\\ No newline at end of file\n", stdout);
|
||||
fputs("\\ No newline at end of file\n", file);
|
||||
}
|
||||
|
||||
static char *output_prefix(struct diff_options *opt)
|
||||
|
@ -897,12 +897,12 @@ static void dump_diff_hacky_one(struct rev_info *rev, struct line_log_data *rang
|
|||
fill_line_ends(pair->one, &p_lines, &p_ends);
|
||||
fill_line_ends(pair->two, &t_lines, &t_ends);
|
||||
|
||||
printf("%s%sdiff --git a/%s b/%s%s\n", prefix, c_meta, pair->one->path, pair->two->path, c_reset);
|
||||
printf("%s%s--- %s%s%s\n", prefix, c_meta,
|
||||
fprintf(opt->file, "%s%sdiff --git a/%s b/%s%s\n", prefix, c_meta, pair->one->path, pair->two->path, c_reset);
|
||||
fprintf(opt->file, "%s%s--- %s%s%s\n", prefix, c_meta,
|
||||
pair->one->sha1_valid ? "a/" : "",
|
||||
pair->one->sha1_valid ? pair->one->path : "/dev/null",
|
||||
c_reset);
|
||||
printf("%s%s+++ b/%s%s\n", prefix, c_meta, pair->two->path, c_reset);
|
||||
fprintf(opt->file, "%s%s+++ b/%s%s\n", prefix, c_meta, pair->two->path, c_reset);
|
||||
for (i = 0; i < range->ranges.nr; i++) {
|
||||
long p_start, p_end;
|
||||
long t_start = range->ranges.ranges[i].start;
|
||||
|
@ -944,7 +944,7 @@ static void dump_diff_hacky_one(struct rev_info *rev, struct line_log_data *rang
|
|||
}
|
||||
|
||||
/* Now output a diff hunk for this range */
|
||||
printf("%s%s@@ -%ld,%ld +%ld,%ld @@%s\n",
|
||||
fprintf(opt->file, "%s%s@@ -%ld,%ld +%ld,%ld @@%s\n",
|
||||
prefix, c_frag,
|
||||
p_start+1, p_end-p_start, t_start+1, t_end-t_start,
|
||||
c_reset);
|
||||
|
@ -952,18 +952,18 @@ static void dump_diff_hacky_one(struct rev_info *rev, struct line_log_data *rang
|
|||
int k;
|
||||
for (; t_cur < diff->target.ranges[j].start; t_cur++)
|
||||
print_line(prefix, ' ', t_cur, t_ends, pair->two->data,
|
||||
c_context, c_reset);
|
||||
c_context, c_reset, opt->file);
|
||||
for (k = diff->parent.ranges[j].start; k < diff->parent.ranges[j].end; k++)
|
||||
print_line(prefix, '-', k, p_ends, pair->one->data,
|
||||
c_old, c_reset);
|
||||
c_old, c_reset, opt->file);
|
||||
for (; t_cur < diff->target.ranges[j].end && t_cur < t_end; t_cur++)
|
||||
print_line(prefix, '+', t_cur, t_ends, pair->two->data,
|
||||
c_new, c_reset);
|
||||
c_new, c_reset, opt->file);
|
||||
j++;
|
||||
}
|
||||
for (; t_cur < t_end; t_cur++)
|
||||
print_line(prefix, ' ', t_cur, t_ends, pair->two->data,
|
||||
c_context, c_reset);
|
||||
c_context, c_reset, opt->file);
|
||||
}
|
||||
|
||||
free(p_ends);
|
||||
|
@ -976,7 +976,7 @@ static void dump_diff_hacky_one(struct rev_info *rev, struct line_log_data *rang
|
|||
*/
|
||||
static void dump_diff_hacky(struct rev_info *rev, struct line_log_data *range)
|
||||
{
|
||||
puts(output_prefix(&rev->diffopt));
|
||||
fprintf(rev->diffopt.file, "%s\n", output_prefix(&rev->diffopt));
|
||||
while (range) {
|
||||
dump_diff_hacky_one(rev, range);
|
||||
range = range->next;
|
||||
|
|
69
log-tree.c
69
log-tree.c
|
@ -159,12 +159,12 @@ void load_ref_decorations(int flags)
|
|||
}
|
||||
}
|
||||
|
||||
static void show_parents(struct commit *commit, int abbrev)
|
||||
static void show_parents(struct commit *commit, int abbrev, FILE *file)
|
||||
{
|
||||
struct commit_list *p;
|
||||
for (p = commit->parents; p ; p = p->next) {
|
||||
struct commit *parent = p->item;
|
||||
printf(" %s", find_unique_abbrev(parent->object.oid.hash, abbrev));
|
||||
fprintf(file, " %s", find_unique_abbrev(parent->object.oid.hash, abbrev));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,7 +172,7 @@ static void show_children(struct rev_info *opt, struct commit *commit, int abbre
|
|||
{
|
||||
struct commit_list *p = lookup_decoration(&opt->children, &commit->object);
|
||||
for ( ; p; p = p->next) {
|
||||
printf(" %s", find_unique_abbrev(p->item->object.oid.hash, abbrev));
|
||||
fprintf(opt->diffopt.file, " %s", find_unique_abbrev(p->item->object.oid.hash, abbrev));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -286,11 +286,11 @@ void show_decorations(struct rev_info *opt, struct commit *commit)
|
|||
struct strbuf sb = STRBUF_INIT;
|
||||
|
||||
if (opt->show_source && commit->util)
|
||||
printf("\t%s", (char *) commit->util);
|
||||
fprintf(opt->diffopt.file, "\t%s", (char *) commit->util);
|
||||
if (!opt->show_decorations)
|
||||
return;
|
||||
format_decorations(&sb, commit, opt->diffopt.use_color);
|
||||
fputs(sb.buf, stdout);
|
||||
fputs(sb.buf, opt->diffopt.file);
|
||||
strbuf_release(&sb);
|
||||
}
|
||||
|
||||
|
@ -364,18 +364,18 @@ void log_write_email_headers(struct rev_info *opt, struct commit *commit,
|
|||
subject = "Subject: ";
|
||||
}
|
||||
|
||||
printf("From %s Mon Sep 17 00:00:00 2001\n", name);
|
||||
fprintf(opt->diffopt.file, "From %s Mon Sep 17 00:00:00 2001\n", name);
|
||||
graph_show_oneline(opt->graph);
|
||||
if (opt->message_id) {
|
||||
printf("Message-Id: <%s>\n", opt->message_id);
|
||||
fprintf(opt->diffopt.file, "Message-Id: <%s>\n", opt->message_id);
|
||||
graph_show_oneline(opt->graph);
|
||||
}
|
||||
if (opt->ref_message_ids && opt->ref_message_ids->nr > 0) {
|
||||
int i, n;
|
||||
n = opt->ref_message_ids->nr;
|
||||
printf("In-Reply-To: <%s>\n", opt->ref_message_ids->items[n-1].string);
|
||||
fprintf(opt->diffopt.file, "In-Reply-To: <%s>\n", opt->ref_message_ids->items[n-1].string);
|
||||
for (i = 0; i < n; i++)
|
||||
printf("%s<%s>\n", (i > 0 ? "\t" : "References: "),
|
||||
fprintf(opt->diffopt.file, "%s<%s>\n", (i > 0 ? "\t" : "References: "),
|
||||
opt->ref_message_ids->items[i].string);
|
||||
graph_show_oneline(opt->graph);
|
||||
}
|
||||
|
@ -432,7 +432,7 @@ static void show_sig_lines(struct rev_info *opt, int status, const char *bol)
|
|||
reset = diff_get_color_opt(&opt->diffopt, DIFF_RESET);
|
||||
while (*bol) {
|
||||
eol = strchrnul(bol, '\n');
|
||||
printf("%s%.*s%s%s", color, (int)(eol - bol), bol, reset,
|
||||
fprintf(opt->diffopt.file, "%s%.*s%s%s", color, (int)(eol - bol), bol, reset,
|
||||
*eol ? "\n" : "");
|
||||
graph_show_oneline(opt->graph);
|
||||
bol = (*eol) ? (eol + 1) : eol;
|
||||
|
@ -553,17 +553,17 @@ void show_log(struct rev_info *opt)
|
|||
|
||||
if (!opt->graph)
|
||||
put_revision_mark(opt, commit);
|
||||
fputs(find_unique_abbrev(commit->object.oid.hash, abbrev_commit), stdout);
|
||||
fputs(find_unique_abbrev(commit->object.oid.hash, abbrev_commit), opt->diffopt.file);
|
||||
if (opt->print_parents)
|
||||
show_parents(commit, abbrev_commit);
|
||||
show_parents(commit, abbrev_commit, opt->diffopt.file);
|
||||
if (opt->children.name)
|
||||
show_children(opt, commit, abbrev_commit);
|
||||
show_decorations(opt, commit);
|
||||
if (opt->graph && !graph_is_commit_finished(opt->graph)) {
|
||||
putchar('\n');
|
||||
putc('\n', opt->diffopt.file);
|
||||
graph_show_remainder(opt->graph);
|
||||
}
|
||||
putchar(opt->diffopt.line_termination);
|
||||
putc(opt->diffopt.line_termination, opt->diffopt.file);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -589,7 +589,7 @@ void show_log(struct rev_info *opt)
|
|||
if (opt->diffopt.line_termination == '\n' &&
|
||||
!opt->missing_newline)
|
||||
graph_show_padding(opt->graph);
|
||||
putchar(opt->diffopt.line_termination);
|
||||
putc(opt->diffopt.line_termination, opt->diffopt.file);
|
||||
}
|
||||
opt->shown_one = 1;
|
||||
|
||||
|
@ -607,28 +607,28 @@ void show_log(struct rev_info *opt)
|
|||
log_write_email_headers(opt, commit, &ctx.subject, &extra_headers,
|
||||
&ctx.need_8bit_cte);
|
||||
} else if (opt->commit_format != CMIT_FMT_USERFORMAT) {
|
||||
fputs(diff_get_color_opt(&opt->diffopt, DIFF_COMMIT), stdout);
|
||||
fputs(diff_get_color_opt(&opt->diffopt, DIFF_COMMIT), opt->diffopt.file);
|
||||
if (opt->commit_format != CMIT_FMT_ONELINE)
|
||||
fputs("commit ", stdout);
|
||||
fputs("commit ", opt->diffopt.file);
|
||||
|
||||
if (!opt->graph)
|
||||
put_revision_mark(opt, commit);
|
||||
fputs(find_unique_abbrev(commit->object.oid.hash, abbrev_commit),
|
||||
stdout);
|
||||
opt->diffopt.file);
|
||||
if (opt->print_parents)
|
||||
show_parents(commit, abbrev_commit);
|
||||
show_parents(commit, abbrev_commit, opt->diffopt.file);
|
||||
if (opt->children.name)
|
||||
show_children(opt, commit, abbrev_commit);
|
||||
if (parent)
|
||||
printf(" (from %s)",
|
||||
fprintf(opt->diffopt.file, " (from %s)",
|
||||
find_unique_abbrev(parent->object.oid.hash,
|
||||
abbrev_commit));
|
||||
fputs(diff_get_color_opt(&opt->diffopt, DIFF_RESET), stdout);
|
||||
fputs(diff_get_color_opt(&opt->diffopt, DIFF_RESET), opt->diffopt.file);
|
||||
show_decorations(opt, commit);
|
||||
if (opt->commit_format == CMIT_FMT_ONELINE) {
|
||||
putchar(' ');
|
||||
putc(' ', opt->diffopt.file);
|
||||
} else {
|
||||
putchar('\n');
|
||||
putc('\n', opt->diffopt.file);
|
||||
graph_show_oneline(opt->graph);
|
||||
}
|
||||
if (opt->reflog_info) {
|
||||
|
@ -704,7 +704,7 @@ void show_log(struct rev_info *opt)
|
|||
}
|
||||
|
||||
if (opt->show_log_size) {
|
||||
printf("log size %i\n", (int)msgbuf.len);
|
||||
fprintf(opt->diffopt.file, "log size %i\n", (int)msgbuf.len);
|
||||
graph_show_oneline(opt->graph);
|
||||
}
|
||||
|
||||
|
@ -720,11 +720,11 @@ void show_log(struct rev_info *opt)
|
|||
if (opt->graph)
|
||||
graph_show_commit_msg(opt->graph, &msgbuf);
|
||||
else
|
||||
fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout);
|
||||
fwrite(msgbuf.buf, sizeof(char), msgbuf.len, opt->diffopt.file);
|
||||
if (opt->use_terminator && !commit_format_is_empty(opt->commit_format)) {
|
||||
if (!opt->missing_newline)
|
||||
graph_show_padding(opt->graph);
|
||||
putchar(opt->diffopt.line_termination);
|
||||
putc(opt->diffopt.line_termination, opt->diffopt.file);
|
||||
}
|
||||
|
||||
strbuf_release(&msgbuf);
|
||||
|
@ -761,7 +761,7 @@ int log_tree_diff_flush(struct rev_info *opt)
|
|||
struct strbuf *msg = NULL;
|
||||
msg = opt->diffopt.output_prefix(&opt->diffopt,
|
||||
opt->diffopt.output_prefix_data);
|
||||
fwrite(msg->buf, msg->len, 1, stdout);
|
||||
fwrite(msg->buf, msg->len, 1, opt->diffopt.file);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -776,8 +776,8 @@ int log_tree_diff_flush(struct rev_info *opt)
|
|||
*/
|
||||
if (!opt->shown_dashes &&
|
||||
(pch & opt->diffopt.output_format) == pch)
|
||||
printf("---");
|
||||
putchar('\n');
|
||||
fprintf(opt->diffopt.file, "---");
|
||||
putc('\n', opt->diffopt.file);
|
||||
}
|
||||
}
|
||||
diff_flush(&opt->diffopt);
|
||||
|
@ -864,17 +864,18 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log
|
|||
int log_tree_commit(struct rev_info *opt, struct commit *commit)
|
||||
{
|
||||
struct log_info log;
|
||||
int shown;
|
||||
int shown, close_file = opt->diffopt.close_file;
|
||||
|
||||
log.commit = commit;
|
||||
log.parent = NULL;
|
||||
opt->loginfo = &log;
|
||||
opt->diffopt.close_file = 0;
|
||||
|
||||
if (opt->line_level_traverse)
|
||||
return line_log_print(opt, commit);
|
||||
|
||||
if (opt->track_linear && !opt->linear && !opt->reverse_output_stage)
|
||||
printf("\n%s\n", opt->break_bar);
|
||||
fprintf(opt->diffopt.file, "\n%s\n", opt->break_bar);
|
||||
shown = log_tree_diff(opt, commit, &log);
|
||||
if (!shown && opt->loginfo && opt->always_show_header) {
|
||||
log.parent = NULL;
|
||||
|
@ -882,8 +883,10 @@ int log_tree_commit(struct rev_info *opt, struct commit *commit)
|
|||
shown = 1;
|
||||
}
|
||||
if (opt->track_linear && !opt->linear && opt->reverse_output_stage)
|
||||
printf("\n%s\n", opt->break_bar);
|
||||
fprintf(opt->diffopt.file, "\n%s\n", opt->break_bar);
|
||||
opt->loginfo = NULL;
|
||||
maybe_flush_or_die(stdout, "stdout");
|
||||
maybe_flush_or_die(opt->diffopt.file, "stdout");
|
||||
if (close_file)
|
||||
fclose(opt->diffopt.file);
|
||||
return shown;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ struct shortlog {
|
|||
char *common_repo_prefix;
|
||||
int email;
|
||||
struct string_list mailmap;
|
||||
FILE *file;
|
||||
};
|
||||
|
||||
void shortlog_init(struct shortlog *log);
|
||||
|
|
|
@ -184,4 +184,10 @@ test_expect_success 'shortlog with revision pseudo options' '
|
|||
git shortlog --exclude=refs/heads/m* --all
|
||||
'
|
||||
|
||||
test_expect_success 'shortlog with --output=<file>' '
|
||||
git shortlog --output=shortlog -1 master >output &&
|
||||
test ! -s output &&
|
||||
test_line_count = 3 shortlog
|
||||
'
|
||||
|
||||
test_done
|
||||
|
|
|
@ -99,4 +99,11 @@ test_expect_success '-L with --first-parent and a merge' '
|
|||
git log --first-parent -L 1,1:b.c
|
||||
'
|
||||
|
||||
test_expect_success '-L with --output' '
|
||||
git checkout parallel-change &&
|
||||
git log --output=log -L :main:b.c >output &&
|
||||
test ! -s output &&
|
||||
test_line_count = 70 log
|
||||
'
|
||||
|
||||
test_done
|
||||
|
|
Загрузка…
Ссылка в новой задаче