revision walker: mini clean-up

This removes the unnecessary indirection of "revs->prune_fn",
since that function is always the same one (or NULL), and there
is in fact not even an abstraction reason to make it a function
(i.e. its not called from some other file and doesn't allow us
to keep the function itself static or anything like that).

It then just replaces it with a bit that says "prune or not",
and if not pruning, every commit gets TREECHANGE.

That in turn means that

 - if (!revs->prune_fn || (flags & TREECHANGE))
 - if (revs->prune_fn && !(flags & TREECHANGE))

just become

 - if (flags & TREECHANGE)
 - if (!(flags & TREECHANGE))

respectively.

Together with adding the "single_parent()" helper function, the "complex"
conditional now becomes

	if (!(flags & TREECHANGE) && rev->dense && single_parent(commit))
		continue;

Also indirection of "revs->dense" checking is thrown away the
same way, because TREECHANGE bit is set appropriately now.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Linus Torvalds 2007-11-05 13:22:34 -08:00 committed by Junio C Hamano
parent 252a7c0235
commit 53b2c823f6
5 changed files with 35 additions and 26 deletions

View File

@ -88,14 +88,8 @@ static int estimate_commit_count(struct rev_info *rev, struct commit_list *list)
while (list) { while (list) {
struct commit *commit = list->item; struct commit *commit = list->item;
unsigned int flags = commit->object.flags; unsigned int flags = commit->object.flags;
list = list->next; list = list->next;
if (flags & UNINTERESTING) if ((flags & TREECHANGE) && !(flags & UNINTERESTING))
continue;
if (rev->prune_fn && rev->dense && !(flags & TREECHANGE)) {
if (commit->parents && !commit->parents->next)
continue;
}
n++; n++;
} }
return n; return n;

View File

@ -142,7 +142,7 @@ static int count_distance(struct commit_list *entry)
if (commit->object.flags & (UNINTERESTING | COUNTED)) if (commit->object.flags & (UNINTERESTING | COUNTED))
break; break;
if (!revs.prune_fn || (commit->object.flags & TREECHANGE)) if (commit->object.flags & TREECHANGE)
nr++; nr++;
commit->object.flags |= COUNTED; commit->object.flags |= COUNTED;
p = commit->parents; p = commit->parents;
@ -198,7 +198,7 @@ static inline int halfway(struct commit_list *p, int nr)
/* /*
* Don't short-cut something we are not going to return! * Don't short-cut something we are not going to return!
*/ */
if (revs.prune_fn && !(p->item->object.flags & TREECHANGE)) if (!(p->item->object.flags & TREECHANGE))
return 0; return 0;
if (DEBUG_BISECT) if (DEBUG_BISECT)
return 0; return 0;
@ -268,7 +268,7 @@ static struct commit_list *best_bisection(struct commit_list *list, int nr)
int distance; int distance;
unsigned flags = p->item->object.flags; unsigned flags = p->item->object.flags;
if (revs.prune_fn && !(flags & TREECHANGE)) if (!(flags & TREECHANGE))
continue; continue;
distance = weight(p); distance = weight(p);
if (nr - distance < distance) if (nr - distance < distance)
@ -308,7 +308,7 @@ static struct commit_list *best_bisection_sorted(struct commit_list *list, int n
int distance; int distance;
unsigned flags = p->item->object.flags; unsigned flags = p->item->object.flags;
if (revs.prune_fn && !(flags & TREECHANGE)) if (!(flags & TREECHANGE))
continue; continue;
distance = weight(p); distance = weight(p);
if (nr - distance < distance) if (nr - distance < distance)
@ -362,7 +362,7 @@ static struct commit_list *do_find_bisection(struct commit_list *list,
p->item->util = &weights[n++]; p->item->util = &weights[n++];
switch (count_interesting_parents(commit)) { switch (count_interesting_parents(commit)) {
case 0: case 0:
if (!revs.prune_fn || (flags & TREECHANGE)) { if (flags & TREECHANGE) {
weight_set(p, 1); weight_set(p, 1);
counted++; counted++;
show_list("bisection 2 count one", show_list("bisection 2 count one",
@ -435,7 +435,7 @@ static struct commit_list *do_find_bisection(struct commit_list *list,
* add one for p itself if p is to be counted, * add one for p itself if p is to be counted,
* otherwise inherit it from q directly. * otherwise inherit it from q directly.
*/ */
if (!revs.prune_fn || (flags & TREECHANGE)) { if (flags & TREECHANGE) {
weight_set(p, weight(q)+1); weight_set(p, weight(q)+1);
counted++; counted++;
show_list("bisection 2 count one", show_list("bisection 2 count one",
@ -482,7 +482,7 @@ static struct commit_list *find_bisection(struct commit_list *list,
continue; continue;
p->next = last; p->next = last;
last = p; last = p;
if (!revs.prune_fn || (flags & TREECHANGE)) if (flags & TREECHANGE)
nr++; nr++;
on_list++; on_list++;
} }

View File

@ -117,4 +117,9 @@ extern int interactive_add(void);
extern void add_files_to_cache(int verbose, const char *prefix, const char **files); extern void add_files_to_cache(int verbose, const char *prefix, const char **files);
extern int rerere(void); extern int rerere(void);
static inline int single_parent(struct commit *commit)
{
return commit->parents && !commit->parents->next;
}
#endif /* COMMIT_H */ #endif /* COMMIT_H */

View File

@ -308,6 +308,14 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
struct commit_list **pp, *parent; struct commit_list **pp, *parent;
int tree_changed = 0, tree_same = 0; int tree_changed = 0, tree_same = 0;
/*
* If we don't do pruning, everything is interesting
*/
if (!revs->prune) {
commit->object.flags |= TREECHANGE;
return;
}
if (!commit->tree) if (!commit->tree)
return; return;
@ -317,6 +325,15 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
return; return;
} }
/*
* Normal non-merge commit? If we don't want to make the
* history dense, we consider it always to be a change..
*/
if (!revs->dense && !commit->parents->next) {
commit->object.flags |= TREECHANGE;
return;
}
pp = &commit->parents; pp = &commit->parents;
while ((parent = *pp) != NULL) { while ((parent = *pp) != NULL) {
struct commit *p = parent->item; struct commit *p = parent->item;
@ -415,8 +432,7 @@ static int add_parents_to_list(struct rev_info *revs, struct commit *commit, str
* simplify the commit history and find the parent * simplify the commit history and find the parent
* that has no differences in the path set if one exists. * that has no differences in the path set if one exists.
*/ */
if (revs->prune_fn) try_to_simplify_commit(revs, commit);
revs->prune_fn(revs, commit);
if (revs->no_walk) if (revs->no_walk)
return 0; return 0;
@ -684,9 +700,6 @@ void init_revisions(struct rev_info *revs, const char *prefix)
revs->skip_count = -1; revs->skip_count = -1;
revs->max_count = -1; revs->max_count = -1;
revs->prune_fn = NULL;
revs->prune_data = NULL;
revs->commit_format = CMIT_FMT_DEFAULT; revs->commit_format = CMIT_FMT_DEFAULT;
diff_setup(&revs->diffopt); diff_setup(&revs->diffopt);
@ -1271,7 +1284,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
diff_tree_setup_paths(revs->prune_data, &revs->pruning); diff_tree_setup_paths(revs->prune_data, &revs->pruning);
/* Can't prune commits with rename following: the paths change.. */ /* Can't prune commits with rename following: the paths change.. */
if (!revs->diffopt.follow_renames) if (!revs->diffopt.follow_renames)
revs->prune_fn = try_to_simplify_commit; revs->prune = 1;
if (!revs->full_diff) if (!revs->full_diff)
diff_tree_setup_paths(revs->prune_data, &revs->diffopt); diff_tree_setup_paths(revs->prune_data, &revs->diffopt);
} }
@ -1412,7 +1425,7 @@ enum commit_action simplify_commit(struct rev_info *revs, struct commit *commit)
return commit_ignore; return commit_ignore;
if (!commit_match(commit, revs)) if (!commit_match(commit, revs))
return commit_ignore; return commit_ignore;
if (revs->prune_fn && revs->dense) { if (revs->prune && revs->dense) {
/* Commit without changes? */ /* Commit without changes? */
if (!(commit->object.flags & TREECHANGE)) { if (!(commit->object.flags & TREECHANGE)) {
/* drop merges unless we want parenthood */ /* drop merges unless we want parenthood */

View File

@ -15,8 +15,6 @@
struct rev_info; struct rev_info;
struct log_info; struct log_info;
typedef void (prune_fn_t)(struct rev_info *revs, struct commit *commit);
struct rev_info { struct rev_info {
/* Starting list */ /* Starting list */
struct commit_list *commits; struct commit_list *commits;
@ -28,12 +26,11 @@ struct rev_info {
/* Basic information */ /* Basic information */
const char *prefix; const char *prefix;
void *prune_data; void *prune_data;
prune_fn_t *prune_fn;
unsigned int early_output; unsigned int early_output;
/* Traversal flags */ /* Traversal flags */
unsigned int dense:1, unsigned int dense:1,
prune:1,
no_merges:1, no_merges:1,
no_walk:1, no_walk:1,
remove_empty_trees:1, remove_empty_trees:1,