summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2005-11-10 23:47:58 (GMT)
committerJunio C Hamano <junkio@cox.net>2005-11-11 18:52:38 (GMT)
commit6b209d473378cc25708ab9839d0edd493afc1e8f (patch)
tree96fa9b56b09dbc9bc29f013c1c2df134f13b89a4
parent9ce7028531fd7ce1ca8d75a5c4f9a941ef79c9d4 (diff)
downloadgit-6b209d473378cc25708ab9839d0edd493afc1e8f.zip
git-6b209d473378cc25708ab9839d0edd493afc1e8f.tar.gz
git-6b209d473378cc25708ab9839d0edd493afc1e8f.tar.bz2
Fully detect uninteresting commits.
With the change in the previous round, we are guaranteed to come up with the list of all relevant merge bases, but sometimes we do not fully mark unintersting ones due to a horizon effect. Add a phase to postprocess, so that we mark all ancestor of "interesting" commit. This also changes the default ordering of shown commits back to chronological order, and adds --topo-order flag to show them in topological order. Signed-off-by: Junio C Hamano <junkio@cox.net>
-rw-r--r--show-branch.c64
1 files changed, 53 insertions, 11 deletions
diff --git a/show-branch.c b/show-branch.c
index 714e7f8..631336c 100644
--- a/show-branch.c
+++ b/show-branch.c
@@ -199,18 +199,58 @@ static void join_revs(struct commit_list **list_p,
parents = parents->next;
if ((this_flag & flags) == flags)
continue;
- parse_commit(p);
+ if (!p->object.parsed)
+ parse_commit(p);
if (mark_seen(p, seen_p) && !still_interesting)
extra--;
p->object.flags |= flags;
insert_by_date(p, list_p);
}
}
+
+ /*
+ * Postprocess to complete well-poisoning.
+ *
+ * At this point we have all the commits we have seen in
+ * seen_p list (which happens to be sorted chronologically but
+ * it does not really matter). Mark anything that can be
+ * reached from uninteresting commits not interesting.
+ */
+ for (;;) {
+ int changed = 0;
+ struct commit_list *s;
+ for (s = *seen_p; s; s = s->next) {
+ struct commit *c = s->item;
+ struct commit_list *parents;
+
+ if (((c->object.flags & all_revs) != all_revs) &&
+ !(c->object.flags & UNINTERESTING))
+ continue;
+
+ /* The current commit is either a merge base or
+ * already uninteresting one. Mark its parents
+ * as uninteresting commits _only_ if they are
+ * already parsed. No reason to find new ones
+ * here.
+ */
+ parents = c->parents;
+ while (parents) {
+ struct commit *p = parents->item;
+ parents = parents->next;
+ if (!(p->object.flags & UNINTERESTING)) {
+ p->object.flags |= UNINTERESTING;
+ changed = 1;
+ }
+ }
+ }
+ if (!changed)
+ break;
+ }
}
static void show_one_commit(struct commit *commit, int no_name)
{
- char pretty[128], *cp;
+ char pretty[256], *cp;
struct commit_name *name = commit->object.util;
if (commit->object.parsed)
pretty_print_commit(CMIT_FMT_ONELINE, commit->buffer, ~0,
@@ -360,7 +400,7 @@ int main(int ac, char **av)
unsigned int rev_mask[MAX_REVS];
int num_rev, i, extra = 0;
int all_heads = 0, all_tags = 0;
- int all_mask, all_revs, shown_merge_point;
+ int all_mask, all_revs;
char head_path[128];
const char *head_path_p;
int head_path_len;
@@ -369,6 +409,8 @@ int main(int ac, char **av)
int independent = 0;
int no_name = 0;
int sha1_name = 0;
+ int shown_merge_point = 0;
+ int topo_order = 0;
setup_git_directory();
@@ -394,6 +436,8 @@ int main(int ac, char **av)
merge_base = 1;
else if (!strcmp(arg, "--independent"))
independent = 1;
+ else if (!strcmp(arg, "--topo-order"))
+ topo_order = 1;
else
usage(show_branch_usage);
ac--; av++;
@@ -496,7 +540,8 @@ int main(int ac, char **av)
exit(0);
/* Sort topologically */
- sort_in_topological_order(&seen);
+ if (topo_order)
+ sort_in_topological_order(&seen);
/* Give names to commits */
if (!sha1_name && !no_name)
@@ -504,15 +549,12 @@ int main(int ac, char **av)
all_mask = ((1u << (REV_SHIFT + num_rev)) - 1);
all_revs = all_mask & ~((1u << REV_SHIFT) - 1);
- shown_merge_point = 0;
while (seen) {
struct commit *commit = pop_one_commit(&seen);
int this_flag = commit->object.flags;
- int is_merge_point = (this_flag & all_revs) == all_revs;
- if (is_merge_point)
- shown_merge_point = 1;
+ shown_merge_point |= ((this_flag & all_revs) == all_revs);
if (1 < num_rev) {
for (i = 0; i < num_rev; i++)
@@ -521,9 +563,9 @@ int main(int ac, char **av)
putchar(' ');
}
show_one_commit(commit, no_name);
- if (shown_merge_point && is_merge_point)
- if (--extra < 0)
- break;
+
+ if (shown_merge_point && --extra < 0)
+ break;
}
return 0;
}