Merge branch 'rt/rebase-p-no-merge-summary'
[gitweb.git] / builtin / log.c
index 6e56a50002194e0a452266a580932b9e4e9647c9..77d0f5f3fdbcb48d75aee35a67ed57dd134c907e 100644 (file)
@@ -19,6 +19,7 @@
 #include "remote.h"
 #include "string-list.h"
 #include "parse-options.h"
+#include "line-log.h"
 #include "branch.h"
 #include "streaming.h"
 #include "version.h"
@@ -42,6 +43,12 @@ static const char * const builtin_log_usage[] = {
        NULL
 };
 
+struct line_opt_callback_data {
+       struct rev_info *rev;
+       const char *prefix;
+       struct string_list args;
+};
+
 static int parse_decoration_style(const char *var, const char *value)
 {
        switch (git_config_maybe_bool(var, value)) {
@@ -76,6 +83,19 @@ static int decorate_callback(const struct option *opt, const char *arg, int unse
        return 0;
 }
 
+static int log_line_range_callback(const struct option *option, const char *arg, int unset)
+{
+       struct line_opt_callback_data *data = option->value;
+
+       if (!arg)
+               return -1;
+
+       data->rev->line_level_traverse = 1;
+       string_list_append(&data->args, arg);
+
+       return 0;
+}
+
 static void cmd_log_init_defaults(struct rev_info *rev)
 {
        if (fmt_pretty)
@@ -98,16 +118,23 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
 {
        struct userformat_want w;
        int quiet = 0, source = 0, mailmap = 0;
+       static struct line_opt_callback_data line_cb = {NULL, NULL, STRING_LIST_INIT_DUP};
 
        const struct option builtin_log_options[] = {
-               OPT_BOOL(0, "quiet", &quiet, N_("suppress diff output")),
+               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")),
                { OPTION_CALLBACK, 0, "decorate", NULL, NULL, N_("decorate options"),
                  PARSE_OPT_OPTARG, decorate_callback},
+               OPT_CALLBACK('L', NULL, &line_cb, "n,m:file",
+                            "Process line range n,m in file, counting from 1",
+                            log_line_range_callback),
                OPT_END()
        };
 
+       line_cb.rev = rev;
+       line_cb.prefix = prefix;
+
        mailmap = use_mailmap_config;
        argc = parse_options(argc, argv, prefix,
                             builtin_log_options, builtin_log_usage,
@@ -161,6 +188,10 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
                rev->show_decorations = 1;
                load_ref_decorations(decoration_style);
        }
+
+       if (rev->line_level_traverse)
+               line_log_init(rev, line_cb.prefix, &line_cb.args);
+
        setup_pager();
 }
 
@@ -206,7 +237,7 @@ static void log_show_early(struct rev_info *revs, struct commit_list *list)
        int i = revs->early_output;
        int show_header = 1;
 
-       sort_in_topological_order(&list, revs->lifo);
+       sort_in_topological_order(&list, revs->sort_order);
        while (list && i) {
                struct commit *commit = list->item;
                switch (simplify_commit(revs, commit)) {
@@ -472,7 +503,7 @@ int cmd_show(int argc, const char **argv, const char *prefix)
        init_grep_defaults();
        git_config(git_log_config, NULL);
 
-       init_pathspec(&match_all, NULL);
+       memset(&match_all, 0, sizeof(match_all));
        init_revisions(&rev, prefix);
        rev.diff = 1;
        rev.always_show_header = 1;
@@ -1081,6 +1112,21 @@ static int cc_callback(const struct option *opt, const char *arg, int unset)
        return 0;
 }
 
+static int from_callback(const struct option *opt, const char *arg, int unset)
+{
+       char **from = opt->value;
+
+       free(*from);
+
+       if (unset)
+               *from = NULL;
+       else if (arg)
+               *from = xstrdup(arg);
+       else
+               *from = xstrdup(git_committer_info(IDENT_NO_DATE));
+       return 0;
+}
+
 int cmd_format_patch(int argc, const char **argv, const char *prefix)
 {
        struct commit *commit;
@@ -1103,6 +1149,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
        int quiet = 0;
        int reroll_count = -1;
        char *branch_name = NULL;
+       char *from = NULL;
        const struct option builtin_format_patch_options[] = {
                { OPTION_CALLBACK, 'n', "numbered", &numbered, NULL,
                            N_("use [PATCH n/m] even with a single patch"),
@@ -1132,13 +1179,13 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
                { OPTION_CALLBACK, 'k', "keep-subject", &rev, NULL,
                            N_("don't strip/add [PATCH]"),
                            PARSE_OPT_NOARG | PARSE_OPT_NONEG, keep_callback },
-               OPT_BOOLEAN(0, "no-binary", &no_binary_diff,
-                           N_("don't output binary diffs")),
-               OPT_BOOLEAN(0, "ignore-if-in-upstream", &ignore_if_in_upstream,
-                           N_("don't include a patch matching a commit upstream")),
-               { OPTION_BOOLEAN, 'p', "no-stat", &use_patch_format, NULL,
+               OPT_BOOL(0, "no-binary", &no_binary_diff,
+                        N_("don't output binary diffs")),
+               OPT_BOOL(0, "ignore-if-in-upstream", &ignore_if_in_upstream,
+                        N_("don't include a patch matching a commit upstream")),
+               { OPTION_SET_INT, 'p', "no-stat", &use_patch_format, NULL,
                  N_("show patch format instead of default (patch + stat)"),
-                 PARSE_OPT_NONEG | PARSE_OPT_NOARG },
+                 PARSE_OPT_NONEG | PARSE_OPT_NOARG, NULL, 1},
                OPT_GROUP(N_("Messaging")),
                { OPTION_CALLBACK, 0, "add-header", NULL, N_("header"),
                            N_("add email header"), 0, header_callback },
@@ -1146,6 +1193,9 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
                            0, to_callback },
                { OPTION_CALLBACK, 0, "cc", NULL, N_("email"), N_("add Cc: header"),
                            0, cc_callback },
+               { OPTION_CALLBACK, 0, "from", &from, N_("ident"),
+                           N_("set From address to <ident> (or committer ident if absent)"),
+                           PARSE_OPT_OPTARG, from_callback },
                OPT_STRING(0, "in-reply-to", &in_reply_to, N_("message-id"),
                            N_("make first mail a reply to <message-id>")),
                { OPTION_CALLBACK, 0, "attach", &rev, N_("boundary"),
@@ -1160,8 +1210,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
                            PARSE_OPT_OPTARG, thread_callback },
                OPT_STRING(0, "signature", &signature, N_("signature"),
                            N_("add a signature")),
-               OPT_BOOLEAN(0, "quiet", &quiet,
-                           N_("don't print the patch filenames")),
+               OPT__QUIET(&quiet, N_("don't print the patch filenames")),
                OPT_END()
        };
 
@@ -1233,6 +1282,11 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
 
        rev.extra_headers = strbuf_detach(&buf, NULL);
 
+       if (from) {
+               if (split_ident_line(&rev.from_ident, from, strlen(from)))
+                       die(_("invalid ident line: %s"), from);
+       }
+
        if (start_number < 0)
                start_number = 1;