travis-ci: record and skip successfully built trees
[gitweb.git] / revision.c
index f88c14bab3188c65631593640289b26d00a6a3fc..2631b013a52980f1c338ba1cd539da50784475f4 100644 (file)
@@ -148,16 +148,14 @@ static void add_pending_object_with_path(struct rev_info *revs,
        if (revs->reflog_info && obj->type == OBJ_COMMIT) {
                struct strbuf buf = STRBUF_INIT;
                int len = interpret_branch_name(name, 0, &buf, 0);
-               int st;
 
                if (0 < len && name[len] && buf.len)
                        strbuf_addstr(&buf, name + len);
-               st = add_reflog_for_walk(revs->reflog_info,
-                                        (struct commit *)obj,
-                                        buf.buf[0] ? buf.buf: name);
+               add_reflog_for_walk(revs->reflog_info,
+                                   (struct commit *)obj,
+                                   buf.buf[0] ? buf.buf: name);
                strbuf_release(&buf);
-               if (st)
-                       return;
+               return; /* do not add the commit itself */
        }
        add_object_array_with_path(obj, name, &revs->pending, mode, path);
 }
@@ -401,8 +399,8 @@ static int tree_difference = REV_TREE_SAME;
 
 static void file_add_remove(struct diff_options *options,
                    int addremove, unsigned mode,
-                   const unsigned char *sha1,
-                   int sha1_valid,
+                   const struct object_id *oid,
+                   int oid_valid,
                    const char *fullpath, unsigned dirty_submodule)
 {
        int diff = addremove == '+' ? REV_TREE_NEW : REV_TREE_OLD;
@@ -414,9 +412,9 @@ static void file_add_remove(struct diff_options *options,
 
 static void file_change(struct diff_options *options,
                 unsigned old_mode, unsigned new_mode,
-                const unsigned char *old_sha1,
-                const unsigned char *new_sha1,
-                int old_sha1_valid, int new_sha1_valid,
+                const struct object_id *old_oid,
+                const struct object_id *new_oid,
+                int old_oid_valid, int new_oid_valid,
                 const char *fullpath,
                 unsigned old_dirty_submodule, unsigned new_dirty_submodule)
 {
@@ -455,7 +453,7 @@ static int rev_compare_tree(struct rev_info *revs,
 
        tree_difference = REV_TREE_SAME;
        DIFF_OPT_CLR(&revs->pruning, HAS_CHANGES);
-       if (diff_tree_sha1(t1->object.oid.hash, t2->object.oid.hash, "",
+       if (diff_tree_oid(&t1->object.oid, &t2->object.oid, "",
                           &revs->pruning) < 0)
                return REV_TREE_DIFFERENT;
        return tree_difference;
@@ -471,7 +469,7 @@ static int rev_same_tree_as_empty(struct rev_info *revs, struct commit *commit)
 
        tree_difference = REV_TREE_SAME;
        DIFF_OPT_CLR(&revs->pruning, HAS_CHANGES);
-       retval = diff_tree_sha1(NULL, t1->object.oid.hash, "", &revs->pruning);
+       retval = diff_tree_oid(NULL, &t1->object.oid, "", &revs->pruning);
 
        return retval >= 0 && (tree_difference == REV_TREE_SAME);
 }
@@ -1142,7 +1140,7 @@ int ref_excluded(struct string_list *ref_excludes, const char *path)
        if (!ref_excludes)
                return 0;
        for_each_string_list_item(item, ref_excludes) {
-               if (!wildmatch(item->string, path, 0, NULL))
+               if (!wildmatch(item->string, path, 0))
                        return 1;
        }
        return 0;
@@ -1362,7 +1360,6 @@ void init_revisions(struct rev_info *revs, const char *prefix)
        init_grep_defaults();
        grep_init(&revs->grep_filter, prefix);
        revs->grep_filter.status_only = 1;
-       revs->grep_filter.regflags = REG_NEWLINE;
 
        diff_setup(&revs->diffopt);
        if (prefix && !revs->diffopt.prefix) {
@@ -1725,8 +1722,8 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
                revs->max_count = atoi(argv[1]);
                revs->no_walk = 0;
                return 2;
-       } else if (starts_with(arg, "-n")) {
-               revs->max_count = atoi(arg + 2);
+       } else if (skip_prefix(arg, "-n", &optarg)) {
+               revs->max_count = atoi(optarg);
                revs->no_walk = 0;
        } else if ((argcount = parse_long_opt("max-age", argv, &optarg))) {
                revs->max_age = atoi(optarg);
@@ -1785,16 +1782,13 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
        } else if (!strcmp(arg, "--author-date-order")) {
                revs->sort_order = REV_SORT_BY_AUTHOR_DATE;
                revs->topo_order = 1;
-       } else if (starts_with(arg, "--early-output")) {
-               int count = 100;
-               switch (arg[14]) {
-               case '=':
-                       count = atoi(arg+15);
-                       /* Fallthrough */
-               case 0:
-                       revs->topo_order = 1;
-                      revs->early_output = count;
-               }
+       } else if (!strcmp(arg, "--early-output")) {
+               revs->early_output = 100;
+               revs->topo_order = 1;
+       } else if (skip_prefix(arg, "--early-output=", &optarg)) {
+               if (strtoul_ui(optarg, 10, &revs->early_output) < 0)
+                       die("'%s': not a non-negative integer", optarg);
+               revs->topo_order = 1;
        } else if (!strcmp(arg, "--parents")) {
                revs->rewrite_parents = 1;
                revs->print_parents = 1;
@@ -1810,13 +1804,13 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
                revs->min_parents = 2;
        } else if (!strcmp(arg, "--no-merges")) {
                revs->max_parents = 1;
-       } else if (starts_with(arg, "--min-parents=")) {
-               revs->min_parents = atoi(arg+14);
-       } else if (starts_with(arg, "--no-min-parents")) {
+       } else if (skip_prefix(arg, "--min-parents=", &optarg)) {
+               revs->min_parents = atoi(optarg);
+       } else if (!strcmp(arg, "--no-min-parents")) {
                revs->min_parents = 0;
-       } else if (starts_with(arg, "--max-parents=")) {
-               revs->max_parents = atoi(arg+14);
-       } else if (starts_with(arg, "--no-max-parents")) {
+       } else if (skip_prefix(arg, "--max-parents=", &optarg)) {
+               revs->max_parents = atoi(optarg);
+       } else if (!strcmp(arg, "--no-max-parents")) {
                revs->max_parents = -1;
        } else if (!strcmp(arg, "--boundary")) {
                revs->boundary = 1;
@@ -1897,14 +1891,15 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
                revs->verbose_header = 1;
                revs->pretty_given = 1;
                get_commit_format(NULL, revs);
-       } else if (starts_with(arg, "--pretty=") || starts_with(arg, "--format=")) {
+       } else if (skip_prefix(arg, "--pretty=", &optarg) ||
+                  skip_prefix(arg, "--format=", &optarg)) {
                /*
                 * Detached form ("--pretty X" as opposed to "--pretty=X")
                 * not allowed, since the argument is optional.
                 */
                revs->verbose_header = 1;
                revs->pretty_given = 1;
-               get_commit_format(arg+9, revs);
+               get_commit_format(optarg, revs);
        } else if (!strcmp(arg, "--expand-tabs")) {
                revs->expand_tabs_in_log = 8;
        } else if (!strcmp(arg, "--no-expand-tabs")) {
@@ -1922,26 +1917,23 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
                revs->show_signature = 1;
        } else if (!strcmp(arg, "--no-show-signature")) {
                revs->show_signature = 0;
-       } else if (!strcmp(arg, "--show-linear-break") ||
-                  starts_with(arg, "--show-linear-break=")) {
-               if (starts_with(arg, "--show-linear-break="))
-                       revs->break_bar = xstrdup(arg + 20);
-               else
-                       revs->break_bar = "                    ..........";
+       } else if (!strcmp(arg, "--show-linear-break")) {
+               revs->break_bar = "                    ..........";
+               revs->track_linear = 1;
+               revs->track_first_time = 1;
+       } else if (skip_prefix(arg, "--show-linear-break=", &optarg)) {
+               revs->break_bar = xstrdup(optarg);
                revs->track_linear = 1;
                revs->track_first_time = 1;
-       } else if (starts_with(arg, "--show-notes=") ||
-                  starts_with(arg, "--notes=")) {
+       } else if (skip_prefix(arg, "--show-notes=", &optarg) ||
+                  skip_prefix(arg, "--notes=", &optarg)) {
                struct strbuf buf = STRBUF_INIT;
                revs->show_notes = 1;
                revs->show_notes_given = 1;
-               if (starts_with(arg, "--show-notes")) {
-                       if (revs->notes_opt.use_default_notes < 0)
-                               revs->notes_opt.use_default_notes = 1;
-                       strbuf_addstr(&buf, arg+13);
-               }
-               else
-                       strbuf_addstr(&buf, arg+8);
+               if (starts_with(arg, "--show-notes=") &&
+                   revs->notes_opt.use_default_notes < 0)
+                       revs->notes_opt.use_default_notes = 1;
+               strbuf_addstr(&buf, optarg);
                expand_notes_ref(&buf);
                string_list_append(&revs->notes_opt.extra_notes_refs,
                                   strbuf_detach(&buf, NULL));
@@ -1978,8 +1970,8 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
                revs->abbrev = 0;
        } else if (!strcmp(arg, "--abbrev")) {
                revs->abbrev = DEFAULT_ABBREV;
-       } else if (starts_with(arg, "--abbrev=")) {
-               revs->abbrev = strtoul(arg + 9, NULL, 10);
+       } else if (skip_prefix(arg, "--abbrev=", &optarg)) {
+               revs->abbrev = strtoul(optarg, NULL, 10);
                if (revs->abbrev < MINIMUM_ABBREV)
                        revs->abbrev = MINIMUM_ABBREV;
                else if (revs->abbrev > 40)
@@ -2027,11 +2019,10 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
                revs->grep_filter.pattern_type_option = GREP_PATTERN_TYPE_ERE;
        } else if (!strcmp(arg, "--regexp-ignore-case") || !strcmp(arg, "-i")) {
                revs->grep_filter.ignore_case = 1;
-               revs->grep_filter.regflags |= REG_ICASE;
                DIFF_OPT_SET(&revs->diffopt, PICKAXE_IGNORE_CASE);
        } else if (!strcmp(arg, "--fixed-strings") || !strcmp(arg, "-F")) {
                revs->grep_filter.pattern_type_option = GREP_PATTERN_TYPE_FIXED;
-       } else if (!strcmp(arg, "--perl-regexp")) {
+       } else if (!strcmp(arg, "--perl-regexp") || !strcmp(arg, "-P")) {
                revs->grep_filter.pattern_type_option = GREP_PATTERN_TYPE_PCRE;
        } else if (!strcmp(arg, "--all-match")) {
                revs->grep_filter.all_match = 1;
@@ -2080,7 +2071,7 @@ static int for_each_bisect_ref(const char *submodule, each_ref_fn fn, void *cb_d
        struct strbuf bisect_refs = STRBUF_INIT;
        int status;
        strbuf_addf(&bisect_refs, "refs/bisect/%s", term);
-       status = for_each_ref_in_submodule(submodule, bisect_refs.buf, fn, cb_data);
+       status = for_each_fullref_in_submodule(submodule, bisect_refs.buf, fn, cb_data, 0);
        strbuf_release(&bisect_refs);
        return status;
 }
@@ -2140,20 +2131,20 @@ static int handle_revision_pseudo_opt(const char *submodule,
        } else if ((argcount = parse_long_opt("exclude", argv, &optarg))) {
                add_ref_exclusion(&revs->ref_excludes, optarg);
                return argcount;
-       } else if (starts_with(arg, "--branches=")) {
+       } else if (skip_prefix(arg, "--branches=", &optarg)) {
                struct all_refs_cb cb;
                init_all_refs_cb(&cb, revs, *flags);
-               for_each_glob_ref_in(handle_one_ref, arg + 11, "refs/heads/", &cb);
+               for_each_glob_ref_in(handle_one_ref, optarg, "refs/heads/", &cb);
                clear_ref_exclusion(&revs->ref_excludes);
-       } else if (starts_with(arg, "--tags=")) {
+       } else if (skip_prefix(arg, "--tags=", &optarg)) {
                struct all_refs_cb cb;
                init_all_refs_cb(&cb, revs, *flags);
-               for_each_glob_ref_in(handle_one_ref, arg + 7, "refs/tags/", &cb);
+               for_each_glob_ref_in(handle_one_ref, optarg, "refs/tags/", &cb);
                clear_ref_exclusion(&revs->ref_excludes);
-       } else if (starts_with(arg, "--remotes=")) {
+       } else if (skip_prefix(arg, "--remotes=", &optarg)) {
                struct all_refs_cb cb;
                init_all_refs_cb(&cb, revs, *flags);
-               for_each_glob_ref_in(handle_one_ref, arg + 10, "refs/remotes/", &cb);
+               for_each_glob_ref_in(handle_one_ref, optarg, "refs/remotes/", &cb);
                clear_ref_exclusion(&revs->ref_excludes);
        } else if (!strcmp(arg, "--reflog")) {
                add_reflogs_to_pending(revs, *flags);
@@ -2163,14 +2154,14 @@ static int handle_revision_pseudo_opt(const char *submodule,
                *flags ^= UNINTERESTING | BOTTOM;
        } else if (!strcmp(arg, "--no-walk")) {
                revs->no_walk = REVISION_WALK_NO_WALK_SORTED;
-       } else if (starts_with(arg, "--no-walk=")) {
+       } else if (skip_prefix(arg, "--no-walk=", &optarg)) {
                /*
                 * Detached form ("--no-walk X" as opposed to "--no-walk=X")
                 * not allowed, since the argument is optional.
                 */
-               if (!strcmp(arg + 10, "sorted"))
+               if (!strcmp(optarg, "sorted"))
                        revs->no_walk = REVISION_WALK_NO_WALK_SORTED;
-               else if (!strcmp(arg + 10, "unsorted"))
+               else if (!strcmp(optarg, "unsorted"))
                        revs->no_walk = REVISION_WALK_NO_WALK_UNSORTED;
                else
                        return error("invalid argument to --no-walk");
@@ -2371,6 +2362,8 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
 
        if (revs->reverse && revs->reflog_info)
                die("cannot combine --reverse with --walk-reflogs");
+       if (revs->reflog_info && revs->limited)
+               die("cannot combine --walk-reflogs with history-limiting options");
        if (revs->rewrite_parents && revs->children.name)
                die("cannot combine --parents and --children");
 
@@ -2944,7 +2937,7 @@ static int commit_match(struct commit *commit, struct rev_info *opt)
        if (opt->show_notes) {
                if (!buf.len)
                        strbuf_addstr(&buf, message);
-               format_display_notes(commit->object.oid.hash, &buf, encoding, 1);
+               format_display_notes(&commit->object.oid, &buf, encoding, 1);
        }
 
        /*
@@ -2970,6 +2963,18 @@ static inline int want_ancestry(const struct rev_info *revs)
        return (revs->rewrite_parents || revs->children.name);
 }
 
+/*
+ * Return a timestamp to be used for --since/--until comparisons for this
+ * commit, based on the revision options.
+ */
+static timestamp_t comparison_date(const struct rev_info *revs,
+                                  struct commit *commit)
+{
+       return revs->reflog_info ?
+               get_reflog_timestamp(revs->reflog_info) :
+               commit->date;
+}
+
 enum commit_action get_commit_action(struct rev_info *revs, struct commit *commit)
 {
        if (commit->object.flags & SHOWN)
@@ -2980,8 +2985,9 @@ enum commit_action get_commit_action(struct rev_info *revs, struct commit *commi
                return commit_show;
        if (commit->object.flags & UNINTERESTING)
                return commit_ignore;
-       if (revs->min_age != -1 && (commit->date > revs->min_age))
-               return commit_ignore;
+       if (revs->min_age != -1 &&
+           comparison_date(revs, commit) > revs->min_age)
+                       return commit_ignore;
        if (revs->min_parents || (revs->max_parents >= 0)) {
                int n = commit_list_count(commit->parents);
                if ((n < revs->min_parents) ||
@@ -3114,17 +3120,19 @@ static void track_linear(struct rev_info *revs, struct commit *commit)
 
 static struct commit *get_revision_1(struct rev_info *revs)
 {
-       if (!revs->commits)
-               return NULL;
+       while (1) {
+               struct commit *commit;
 
-       do {
-               struct commit *commit = pop_commit(&revs->commits);
+               if (revs->reflog_info)
+                       commit = next_reflog_entry(revs->reflog_info);
+               else
+                       commit = pop_commit(&revs->commits);
 
-               if (revs->reflog_info) {
-                       save_parents(revs, commit);
-                       fake_reflog_parent(revs->reflog_info, commit);
+               if (!commit)
+                       return NULL;
+
+               if (revs->reflog_info)
                        commit->object.flags &= ~(ADDED | SEEN | SHOWN);
-               }
 
                /*
                 * If we haven't done the list limiting, we need to look at
@@ -3133,9 +3141,12 @@ static struct commit *get_revision_1(struct rev_info *revs)
                 */
                if (!revs->limited) {
                        if (revs->max_age != -1 &&
-                           (commit->date < revs->max_age))
+                           comparison_date(revs, commit) < revs->max_age)
                                continue;
-                       if (add_parents_to_list(revs, commit, &revs->commits, NULL) < 0) {
+
+                       if (revs->reflog_info)
+                               try_to_simplify_commit(revs, commit);
+                       else if (add_parents_to_list(revs, commit, &revs->commits, NULL) < 0) {
                                if (!revs->ignore_missing_links)
                                        die("Failed to traverse parents of commit %s",
                                                oid_to_hex(&commit->object.oid));
@@ -3153,8 +3164,7 @@ static struct commit *get_revision_1(struct rev_info *revs)
                                track_linear(revs, commit);
                        return commit;
                }
-       } while (revs->commits);
-       return NULL;
+       }
 }
 
 /*