implement fetching of moved submodules
[gitweb.git] / builtin / log.c
index 57ce470f5094c238ea4d5390f358b5cdd9499a56..d81a09051ead0bb14161c25ef30bf8b0348b3198 100644 (file)
@@ -5,6 +5,7 @@
  *              2006 Junio Hamano
  */
 #include "cache.h"
+#include "config.h"
 #include "refs.h"
 #include "color.h"
 #include "commit.h"
@@ -26,6 +27,7 @@
 #include "version.h"
 #include "mailmap.h"
 #include "gpg-interface.h"
+#include "progress.h"
 
 /* Set a default date-time format for git log ("log.date" config variable) */
 static const char *default_date_mode = NULL;
@@ -57,9 +59,9 @@ static int auto_decoration_style(void)
        return (isatty(1) || pager_in_use()) ? DECORATE_SHORT_REFS : 0;
 }
 
-static int parse_decoration_style(const char *var, const char *value)
+static int parse_decoration_style(const char *value)
 {
-       switch (git_config_maybe_bool(var, value)) {
+       switch (git_parse_maybe_bool(value)) {
        case 1:
                return DECORATE_SHORT_REFS;
        case 0:
@@ -81,7 +83,7 @@ static int decorate_callback(const struct option *opt, const char *arg, int unse
        if (unset)
                decoration_style = 0;
        else if (arg)
-               decoration_style = parse_decoration_style("command line", arg);
+               decoration_style = parse_decoration_style(arg);
        else
                decoration_style = DECORATE_SHORT_REFS;
 
@@ -371,11 +373,14 @@ static int cmd_log_walk(struct rev_info *rev)
                         */
                        rev->max_count++;
                if (!rev->reflog_info) {
-                       /* we allow cycles in reflog ancestry */
+                       /*
+                        * We may show a given commit multiple times when
+                        * walking the reflogs.
+                        */
                        free_commit_buffer(commit);
+                       free_commit_list(commit->parents);
+                       commit->parents = NULL;
                }
-               free_commit_list(commit->parents);
-               commit->parents = NULL;
                if (saved_nrl < rev->diffopt.needed_rename_limit)
                        saved_nrl = rev->diffopt.needed_rename_limit;
                if (rev->diffopt.degraded_cc_to_c)
@@ -408,7 +413,7 @@ static int git_log_config(const char *var, const char *value, void *cb)
        if (!strcmp(var, "log.date"))
                return git_config_string(&default_date_mode, var, value);
        if (!strcmp(var, "log.decorate")) {
-               decoration_style = parse_decoration_style(var, value);
+               decoration_style = parse_decoration_style(value);
                if (decoration_style < 0)
                        decoration_style = 0; /* maybe warn? */
                return 0;
@@ -483,8 +488,8 @@ static int show_blob_object(const struct object_id *oid, struct rev_info *rev, c
            !DIFF_OPT_TST(&rev->diffopt, ALLOW_TEXTCONV))
                return stream_blob_to_fd(1, oid, NULL, 0);
 
-       if (get_sha1_with_context(obj_name, GET_SHA1_RECORD_PATH,
-                                 oidc.hash, &obj_context))
+       if (get_oid_with_context(obj_name, GET_OID_RECORD_PATH,
+                                &oidc, &obj_context))
                die(_("Not a valid object name %s"), obj_name);
        if (!obj_context.path ||
            !textconv_object(obj_context.path, obj_context.mode, &oidc, 1, &buf, &size)) {
@@ -600,7 +605,7 @@ int cmd_show(int argc, const char **argv, const char *prefix)
                        rev.shown_one = 1;
                        if (ret)
                                break;
-                       o = parse_object(t->tagged->oid.hash);
+                       o = parse_object(&t->tagged->oid);
                        if (!o)
                                ret = error(_("Could not read object %s"),
                                            oid_to_hex(&t->tagged->oid));
@@ -820,7 +825,7 @@ static int git_format_config(const char *var, const char *value, void *cb)
                return 0;
        }
        if (!strcmp(var, "format.from")) {
-               int b = git_config_maybe_bool(var, value);
+               int b = git_parse_maybe_bool(value);
                free(from);
                if (b < 0)
                        from = xstrdup(value);
@@ -846,8 +851,10 @@ static int open_next_file(struct commit *commit, const char *subject,
        if (output_directory) {
                strbuf_addstr(&filename, output_directory);
                if (filename.len >=
-                   PATH_MAX - FORMAT_PATCH_NAME_MAX - suffix_len)
+                   PATH_MAX - FORMAT_PATCH_NAME_MAX - suffix_len) {
+                       strbuf_release(&filename);
                        return error(_("name of output directory is too long"));
+               }
                strbuf_complete(&filename, '/');
        }
 
@@ -861,8 +868,11 @@ static int open_next_file(struct commit *commit, const char *subject,
        if (!quiet)
                printf("%s\n", filename.buf + outdir_offset);
 
-       if ((rev->diffopt.file = fopen(filename.buf, "w")) == NULL)
-               return error(_("Cannot open patch file %s"), filename.buf);
+       if ((rev->diffopt.file = fopen(filename.buf, "w")) == NULL) {
+               error_errno(_("Cannot open patch file %s"), filename.buf);
+               strbuf_release(&filename);
+               return -1;
+       }
 
        strbuf_release(&filename);
        return 0;
@@ -882,8 +892,8 @@ static void get_patch_ids(struct rev_info *rev, struct patch_ids *ids)
        o2 = rev->pending.objects[1].item;
        flags1 = o1->flags;
        flags2 = o2->flags;
-       c1 = lookup_commit_reference(o1->oid.hash);
-       c2 = lookup_commit_reference(o2->oid.hash);
+       c1 = lookup_commit_reference(&o1->oid);
+       c2 = lookup_commit_reference(&o2->oid);
 
        if ((flags1 & UNINTERESTING) == (flags2 & UNINTERESTING))
                die(_("Not a range."));
@@ -914,8 +924,8 @@ static void get_patch_ids(struct rev_info *rev, struct patch_ids *ids)
 static void gen_message_id(struct rev_info *info, char *base)
 {
        struct strbuf buf = STRBUF_INIT;
-       strbuf_addf(&buf, "%s.%lu.git.%s", base,
-                   (unsigned long) time(NULL),
+       strbuf_addf(&buf, "%s.%"PRItime".git.%s", base,
+                   (timestamp_t) time(NULL),
                    git_committer_info(IDENT_NO_NAME|IDENT_NO_DATE|IDENT_STRICT));
        info->message_id = strbuf_detach(&buf, NULL);
 }
@@ -1047,9 +1057,9 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
 
        diff_setup_done(&opts);
 
-       diff_tree_sha1(origin->tree->object.oid.hash,
-                      head->tree->object.oid.hash,
-                      "", &opts);
+       diff_tree_oid(&origin->tree->object.oid,
+                     &head->tree->object.oid,
+                     "", &opts);
        diffcore_std(&opts);
        diff_flush(&opts);
 
@@ -1267,7 +1277,7 @@ static struct commit *get_base_commit(const char *base_commit,
 
                        if (get_oid(upstream, &oid))
                                die(_("Failed to resolve '%s' as a valid ref."), upstream);
-                       commit = lookup_commit_or_die(oid.hash, "upstream base");
+                       commit = lookup_commit_or_die(&oid, "upstream base");
                        base_list = get_merge_bases_many(commit, total, list);
                        /* There should be one and only one merge base. */
                        if (!base_list || base_list->next)
@@ -1302,7 +1312,7 @@ static struct commit *get_base_commit(const char *base_commit,
 
                if (rev_nr % 2)
                        rev[i] = rev[2 * i];
-               rev_nr = (rev_nr + 1) / 2;
+               rev_nr = DIV_ROUND_UP(rev_nr, 2);
        }
 
        if (!in_merge_bases(base, rev[0]))
@@ -1358,7 +1368,7 @@ static void prepare_bases(struct base_tree_info *bases,
                struct object_id *patch_id;
                if (commit->util)
                        continue;
-               if (commit_patch_id(commit, &diffopt, oid.hash, 0))
+               if (commit_patch_id(commit, &diffopt, &oid, 0))
                        die(_("cannot get patch id"));
                ALLOC_GROW(bases->patch_id, bases->nr_patch_id + 1, bases->alloc_patch_id);
                patch_id = bases->patch_id + bases->nr_patch_id;
@@ -1413,6 +1423,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
        char *branch_name = NULL;
        char *base_commit = NULL;
        struct base_tree_info bases;
+       int show_progress = 0;
+       struct progress *progress = NULL;
 
        const struct option builtin_format_patch_options[] = {
                { OPTION_CALLBACK, 'n', "numbered", &numbered, NULL,
@@ -1484,6 +1496,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
                OPT_FILENAME(0, "signature-file", &signature_file,
                                N_("add a signature from a file")),
                OPT__QUIET(&quiet, N_("don't print the patch filenames")),
+               OPT_BOOL(0, "progress", &show_progress,
+                        N_("show progress while generating patches")),
                OPT_END()
        };
 
@@ -1646,10 +1660,9 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
                        check_head = 1;
 
                if (check_head) {
-                       struct object_id oid;
                        const char *ref, *v;
                        ref = resolve_ref_unsafe("HEAD", RESOLVE_REF_READING,
-                                                oid.hash, NULL);
+                                                NULL, NULL);
                        if (ref && skip_prefix(ref, "refs/heads/", &v))
                                branch_name = xstrdup(v);
                        else
@@ -1743,8 +1756,12 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
                start_number--;
        }
        rev.add_signoff = do_signoff;
+
+       if (show_progress)
+               progress = start_delayed_progress(_("Generating patches"), total);
        while (0 <= --nr) {
                int shown;
+               display_progress(progress, total - nr);
                commit = list[nr];
                rev.nr = total - nr + (start_number - 1);
                /* Make the second and subsequent mails replies to the first */
@@ -1809,6 +1826,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
                if (!use_stdout)
                        fclose(rev.diffopt.file);
        }
+       stop_progress(&progress);
        free(list);
        free(branch_name);
        string_list_clear(&extra_to, 0);
@@ -1823,7 +1841,7 @@ static int add_pending_commit(const char *arg, struct rev_info *revs, int flags)
 {
        struct object_id oid;
        if (get_oid(arg, &oid) == 0) {
-               struct commit *commit = lookup_commit_reference(oid.hash);
+               struct commit *commit = lookup_commit_reference(&oid);
                if (commit) {
                        commit->object.flags |= flags;
                        add_pending_object(revs, &commit->object, arg);