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:
@ -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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user