summaryrefslogtreecommitdiff
path: root/builtin/log.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/log.c')
-rw-r--r--builtin/log.c71
1 files changed, 44 insertions, 27 deletions
diff --git a/builtin/log.c b/builtin/log.c
index c87ce09325..f23ccdbec3 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -37,6 +37,7 @@
#define MAIL_DEFAULT_WRAP 72
#define COVER_FROM_AUTO_MAX_SUBJECT_LEN 100
+#define FORMAT_PATCH_NAME_MAX_DEFAULT 64
/* Set a default date-time format for git log ("log.date" config variable) */
static const char *default_date_mode = NULL;
@@ -50,6 +51,7 @@ static int decoration_style;
static int decoration_given;
static int use_mailmap_config = 1;
static const char *fmt_patch_subject_prefix = "PATCH";
+static int fmt_patch_name_max = FORMAT_PATCH_NAME_MAX_DEFAULT;
static const char *fmt_pretty;
static const char * const builtin_log_usage[] = {
@@ -131,7 +133,6 @@ static int log_line_range_callback(const struct option *option, const char *arg,
static void init_log_defaults(void)
{
- init_grep_defaults(the_repository);
init_diff_ui_defaults();
decoration_style = auto_decoration_style();
@@ -150,6 +151,7 @@ static void cmd_log_init_defaults(struct rev_info *rev)
rev->abbrev_commit = default_abbrev_commit;
rev->show_root_diff = default_show_root;
rev->subject_prefix = fmt_patch_subject_prefix;
+ rev->patch_name_max = fmt_patch_name_max;
rev->show_signature = default_show_signature;
rev->encode_email_headers = default_encode_email_headers;
rev->diffopt.flags.allow_textconv = 1;
@@ -175,7 +177,7 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
const struct option builtin_log_options[] = {
OPT__QUIET(&quiet, N_("suppress diff output")),
OPT_BOOL(0, "source", &source, N_("show source")),
- OPT_BOOL(0, "use-mailmap", &mailmap, N_("Use mail map file")),
+ OPT_BOOL(0, "use-mailmap", &mailmap, N_("use mail map file")),
OPT_ALIAS(0, "mailmap", "use-mailmap"),
OPT_STRING_LIST(0, "decorate-refs", &decorate_refs_include,
N_("pattern"), N_("only decorate refs that match <pattern>")),
@@ -184,7 +186,7 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
OPT_CALLBACK_F(0, "decorate", NULL, NULL, N_("decorate options"),
PARSE_OPT_OPTARG, decorate_callback),
OPT_CALLBACK('L', NULL, &line_cb, "range:file",
- N_("Trace the evolution of line range <start>,<end> or function :<funcname> in <file>"),
+ N_("trace the evolution of line range <start>,<end> or function :<funcname> in <file>"),
log_line_range_callback),
OPT_END()
};
@@ -206,6 +208,9 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
if (argc > 1)
die(_("unrecognized argument: %s"), argv[1]);
+ if (rev->line_level_traverse && rev->prune_data.nr)
+ die(_("-L<range>:<file> cannot be used with pathspec"));
+
memset(&w, 0, sizeof(w));
userformat_find_requirements(NULL, &w);
@@ -454,6 +459,10 @@ static int git_log_config(const char *var, const char *value, void *cb)
return git_config_string(&fmt_pretty, var, value);
if (!strcmp(var, "format.subjectprefix"))
return git_config_string(&fmt_patch_subject_prefix, var, value);
+ if (!strcmp(var, "format.filenamemaxlength")) {
+ fmt_patch_name_max = git_config_int(var, value);
+ return 0;
+ }
if (!strcmp(var, "format.encodeemailheaders")) {
default_encode_email_headers = git_config_bool(var, value);
return 0;
@@ -955,15 +964,9 @@ static int open_next_file(struct commit *commit, const char *subject,
struct rev_info *rev, int quiet)
{
struct strbuf filename = STRBUF_INIT;
- int suffix_len = strlen(rev->patch_suffix) + 1;
if (output_directory) {
strbuf_addstr(&filename, output_directory);
- if (filename.len >=
- PATH_MAX - FORMAT_PATCH_NAME_MAX - suffix_len) {
- strbuf_release(&filename);
- return error(_("name of output directory is too long"));
- }
strbuf_complete(&filename, '/');
}
@@ -1153,7 +1156,7 @@ static void get_notes_args(struct strvec *arg, struct rev_info *rev)
}
}
-static void make_cover_letter(struct rev_info *rev, int use_stdout,
+static void make_cover_letter(struct rev_info *rev, int use_separate_file,
struct commit *origin,
int nr, struct commit **list,
const char *branch_name,
@@ -1173,7 +1176,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
committer = git_committer_info(0);
- if (!use_stdout &&
+ if (use_separate_file &&
open_next_file(NULL, rev->numbered_files ? NULL : "cover-letter", rev, quiet))
die(_("failed to create cover-letter file"));
@@ -1738,7 +1741,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
OPT_CALLBACK_F('N', "no-numbered", &numbered, NULL,
N_("use [PATCH] even with multiple patches"),
PARSE_OPT_NOARG | PARSE_OPT_NONEG, no_numbered_callback),
- OPT_BOOL('s', "signoff", &do_signoff, N_("add Signed-off-by:")),
+ OPT_BOOL('s', "signoff", &do_signoff, N_("add a Signed-off-by trailer")),
OPT_BOOL(0, "stdout", &use_stdout,
N_("print patches to standard out")),
OPT_BOOL(0, "cover-letter", &cover_letter,
@@ -1751,14 +1754,16 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
N_("start numbering patches at <n> instead of 1")),
OPT_INTEGER('v', "reroll-count", &reroll_count,
N_("mark the series as Nth re-roll")),
+ OPT_INTEGER(0, "filename-max-length", &fmt_patch_name_max,
+ N_("max length of output filename")),
OPT_CALLBACK_F(0, "rfc", &rev, NULL,
- N_("Use [RFC PATCH] instead of [PATCH]"),
+ N_("use [RFC PATCH] instead of [PATCH]"),
PARSE_OPT_NOARG | PARSE_OPT_NONEG, rfc_callback),
OPT_STRING(0, "cover-from-description", &cover_from_description_arg,
N_("cover-from-description-mode"),
N_("generate parts of a cover letter based on a branch's description")),
OPT_CALLBACK_F(0, "subject-prefix", &rev, N_("prefix"),
- N_("Use [<prefix>] instead of [PATCH]"),
+ N_("use [<prefix>] instead of [PATCH]"),
PARSE_OPT_NONEG, subject_prefix_callback),
OPT_CALLBACK_F('o', "output-directory", &output_directory,
N_("dir"), N_("store resulting files in <dir>"),
@@ -1851,6 +1856,10 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN |
PARSE_OPT_KEEP_DASHDASH);
+ /* Make sure "0000-$sub.patch" gives non-negative length for $sub */
+ if (fmt_patch_name_max <= strlen("0000-") + strlen(fmt_patch_suffix))
+ fmt_patch_name_max = strlen("0000-") + strlen(fmt_patch_suffix);
+
if (cover_from_description_arg)
cover_from_description_mode = parse_cover_from_description(cover_from_description_arg);
@@ -1935,6 +1944,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
rev.zero_commit = zero_commit;
+ rev.patch_name_max = fmt_patch_name_max;
if (!rev.diffopt.flags.text && !no_binary_diff)
rev.diffopt.flags.binary = 1;
@@ -1942,20 +1952,27 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
if (rev.show_notes)
load_display_notes(&rev.notes_opt);
- if (!output_directory && !use_stdout)
- output_directory = config_output_directory;
+ if (use_stdout + rev.diffopt.close_file + !!output_directory > 1)
+ die(_("--stdout, --output, and --output-directory are mutually exclusive"));
- if (!use_stdout)
- output_directory = set_outdir(prefix, output_directory);
- else
+ if (use_stdout) {
setup_pager();
-
- if (output_directory) {
+ } else if (rev.diffopt.close_file) {
+ /*
+ * The diff code parsed --output; it has already opened the
+ * file, but but we must instruct it not to close after each
+ * diff.
+ */
+ rev.diffopt.close_file = 0;
+ } else {
int saved;
+
+ if (!output_directory)
+ output_directory = config_output_directory;
+ output_directory = set_outdir(prefix, 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?"));
/*
* We consider <outdir> as 'outside of gitdir', therefore avoid
* applying adjust_shared_perm in s-c-l-d.
@@ -2117,7 +2134,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
if (cover_letter) {
if (thread)
gen_message_id(&rev, "cover");
- make_cover_letter(&rev, use_stdout,
+ make_cover_letter(&rev, !!output_directory,
origin, nr, list, branch_name, quiet);
print_bases(&bases, rev.diffopt.file);
print_signature(rev.diffopt.file);
@@ -2172,7 +2189,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
gen_message_id(&rev, oid_to_hex(&commit->object.oid));
}
- if (!use_stdout &&
+ if (output_directory &&
open_next_file(rev.numbered_files ? NULL : commit, NULL, &rev, quiet))
die(_("failed to create output files"));
shown = log_tree_commit(&rev, commit);
@@ -2185,7 +2202,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
* the log; when using one file per patch, we do
* not want the extra blank line.
*/
- if (!use_stdout)
+ if (output_directory)
rev.shown_one = 0;
if (shown) {
print_bases(&bases, rev.diffopt.file);
@@ -2196,7 +2213,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
else
print_signature(rev.diffopt.file);
}
- if (!use_stdout)
+ if (output_directory)
fclose(rev.diffopt.file);
}
stop_progress(&progress);