diff options
Diffstat (limited to 'revision.c')
-rw-r--r-- | revision.c | 124 |
1 files changed, 105 insertions, 19 deletions
@@ -33,6 +33,7 @@ #include "bloom.h" #include "json-writer.h" #include "list-objects-filter-options.h" +#include "resolve-undo.h" volatile show_early_output_fn_t show_early_output; @@ -606,6 +607,10 @@ static struct commit *one_relevant_parent(const struct rev_info *revs, * * 2. We saw anything except REV_TREE_NEW. */ +#define REV_TREE_SAME 0 +#define REV_TREE_NEW 1 /* Only new files */ +#define REV_TREE_OLD 2 /* Only files removed */ +#define REV_TREE_DIFFERENT 3 /* Mixed changes */ static int tree_difference = REV_TREE_SAME; static void file_add_remove(struct diff_options *options, @@ -1440,6 +1445,9 @@ static int limit_list(struct rev_info *revs) if (revs->min_age != -1 && (commit->date > revs->min_age) && !revs->line_level_traverse) continue; + if (revs->max_age_as_filter != -1 && + (commit->date < revs->max_age_as_filter) && !revs->line_level_traverse) + continue; date = commit->date; p = &commit_list_insert(commit, p)->next; @@ -1456,10 +1464,9 @@ static int limit_list(struct rev_info *revs) if (revs->left_only || revs->right_only) limit_left_right(newlist, revs); - if (bottom) { + if (bottom) limit_to_ancestry(bottom, newlist); - free_commit_list(bottom); - } + free_commit_list(bottom); /* * Check if any commits have become TREESAME by some of their parents @@ -1690,6 +1697,39 @@ static void add_cache_tree(struct cache_tree *it, struct rev_info *revs, } +static void add_resolve_undo_to_pending(struct index_state *istate, struct rev_info *revs) +{ + struct string_list_item *item; + struct string_list *resolve_undo = istate->resolve_undo; + + if (!resolve_undo) + return; + + for_each_string_list_item(item, resolve_undo) { + const char *path = item->string; + struct resolve_undo_info *ru = item->util; + int i; + + if (!ru) + continue; + for (i = 0; i < 3; i++) { + struct blob *blob; + + if (!ru->mode[i] || !S_ISREG(ru->mode[i])) + continue; + + blob = lookup_blob(revs->repo, &ru->oid[i]); + if (!blob) { + warning(_("resolve-undo records `%s` which is missing"), + oid_to_hex(&ru->oid[i])); + continue; + } + add_pending_object_with_path(revs, &blob->object, "", + ru->mode[i], path); + } + } +} + static void do_add_index_objects_to_pending(struct rev_info *revs, struct index_state *istate, unsigned int flags) @@ -1718,6 +1758,8 @@ static void do_add_index_objects_to_pending(struct rev_info *revs, add_cache_tree(istate->cache_tree, revs, &path, flags); strbuf_release(&path); } + + add_resolve_undo_to_pending(istate, revs); } void add_index_objects_to_pending(struct rev_info *revs, unsigned int flags) @@ -1838,6 +1880,7 @@ void repo_init_revisions(struct repository *r, revs->dense = 1; revs->prefix = prefix; revs->max_age = -1; + revs->max_age_as_filter = -1; revs->min_age = -1; revs->skip_count = -1; revs->max_count = -1; @@ -2218,6 +2261,9 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg } else if ((argcount = parse_long_opt("since", argv, &optarg))) { revs->max_age = approxidate(optarg); return argcount; + } else if ((argcount = parse_long_opt("since-as-filter", argv, &optarg))) { + revs->max_age_as_filter = approxidate(optarg); + return argcount; } else if ((argcount = parse_long_opt("after", argv, &optarg))) { revs->max_age = approxidate(optarg); return argcount; @@ -2691,9 +2737,9 @@ static int handle_revision_pseudo_opt(struct rev_info *revs, revs->no_walk = 0; } else if (!strcmp(arg, "--single-worktree")) { revs->single_worktree = 1; - } else if (skip_prefix(arg, ("--" CL_ARG__FILTER "="), &arg)) { + } else if (skip_prefix(arg, ("--filter="), &arg)) { parse_list_objects_filter(&revs->filter, arg); - } else if (!strcmp(arg, ("--no-" CL_ARG__FILTER))) { + } else if (!strcmp(arg, ("--no-filter"))) { list_objects_filter_set_no_filter(&revs->filter); } else { return 0; @@ -2833,7 +2879,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s } strvec_clear(&prune_data); - if (revs->def == NULL) + if (!revs->def) revs->def = opt ? opt->def : NULL; if (opt && opt->tweak) opt->tweak(revs, opt); @@ -2923,6 +2969,42 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s return left; } +static void release_revisions_cmdline(struct rev_cmdline_info *cmdline) +{ + unsigned int i; + + for (i = 0; i < cmdline->nr; i++) + free((char *)cmdline->rev[i].name); + free(cmdline->rev); +} + +static void release_revisions_mailmap(struct string_list *mailmap) +{ + if (!mailmap) + return; + clear_mailmap(mailmap); + free(mailmap); +} + +static void release_revisions_topo_walk_info(struct topo_walk_info *info); + +void release_revisions(struct rev_info *revs) +{ + free_commit_list(revs->commits); + object_array_clear(&revs->pending); + object_array_clear(&revs->boundary_commits); + release_revisions_cmdline(&revs->cmdline); + list_objects_filter_release(&revs->filter); + clear_pathspec(&revs->prune_data); + date_mode_release(&revs->date_mode); + release_revisions_mailmap(revs->mailmap); + free_grep_patterns(&revs->grep_filter); + /* TODO (need to handle "no_free"): diff_free(&revs->diffopt) */ + diff_free(&revs->pruning); + reflog_walk_info_release(revs->reflog_info); + release_revisions_topo_walk_info(revs->topo_walk_info); +} + static void add_child(struct rev_info *revs, struct commit *parent, struct commit *child) { struct commit_list *l = xcalloc(1, sizeof(*l)); @@ -3433,17 +3515,22 @@ static void compute_indegrees_to_depth(struct rev_info *revs, indegree_walk_step(revs); } -static void reset_topo_walk(struct rev_info *revs) +static void release_revisions_topo_walk_info(struct topo_walk_info *info) { - struct topo_walk_info *info = revs->topo_walk_info; - + if (!info) + return; clear_prio_queue(&info->explore_queue); clear_prio_queue(&info->indegree_queue); clear_prio_queue(&info->topo_queue); clear_indegree_slab(&info->indegree); clear_author_date_slab(&info->author_date); + free(info); +} - FREE_AND_NULL(revs->topo_walk_info); +static void reset_topo_walk(struct rev_info *revs) +{ + release_revisions_topo_walk_info(revs->topo_walk_info); + revs->topo_walk_info = NULL; } static void init_topo_walk(struct rev_info *revs) @@ -3652,7 +3739,7 @@ static enum rewrite_result rewrite_one_1(struct rev_info *revs, return rewrite_one_ok; if (!p->parents) return rewrite_one_noparents; - if ((p = one_relevant_parent(revs, p->parents)) == NULL) + if (!(p = one_relevant_parent(revs, p->parents))) return rewrite_one_ok; *pp = p; } @@ -3862,6 +3949,9 @@ enum commit_action get_commit_action(struct rev_info *revs, struct commit *commi if (revs->min_age != -1 && comparison_date(revs, commit) > revs->min_age) return commit_ignore; + if (revs->max_age_as_filter != -1 && + comparison_date(revs, commit) < revs->max_age_as_filter) + return commit_ignore; if (revs->min_parents || (revs->max_parents >= 0)) { int n = commit_list_count(commit->parents); if ((n < revs->min_parents) || @@ -4080,10 +4170,8 @@ static void create_boundary_commit_list(struct rev_info *revs) * boundary commits anyway. (This is what the code has always * done.) */ - if (revs->commits) { - free_commit_list(revs->commits); - revs->commits = NULL; - } + free_commit_list(revs->commits); + revs->commits = NULL; /* * Put all of the actual boundary commits from revs->boundary_commits @@ -4220,10 +4308,8 @@ struct commit *get_revision(struct rev_info *revs) graph_update(revs->graph, c); if (!c) { free_saved_parents(revs); - if (revs->previous_parents) { - free_commit_list(revs->previous_parents); - revs->previous_parents = NULL; - } + free_commit_list(revs->previous_parents); + revs->previous_parents = NULL; } return c; } |