提交 7dc0fe3b 编写于 作者: L Linus Torvalds 提交者: Junio C Hamano

Fix parent rewriting in --early-output

We cannot tell a node that has been checked and found not to be
interesting (which does not have the TREECHANGE flag) from a
node that hasn't been checked if it is interesting or not,
without relying on something else, such as object->parsed.

But an object can get the "parsed" flag for other reasons.
Which means that "TREECHANGE" has the wrong polarity.

This changes the way how the path pruning logic marks an
uninteresting commits.  From now on, we consider a commit
interesting by default, and explicitly mark the ones we decided
to prune.  The flag is renamed to "TREESAME".

Then, this fixes the logic to show the early output with
incomplete pruning.  It basically says "a commit that has
TREESAME set is kind-of-UNINTERESTING", but obviously in a
different way than an outright UNINTERESTING commit.  Until we
parse and examine enough parents to determine if a commit
becomes surely "kind-of-UNINTERESTING", we avoid rewriting
the ancestry so that later rounds can fix things up.
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: NJunio C Hamano <gitster@pobox.com>
上级 53b2c823
...@@ -176,7 +176,7 @@ static void shortlog(const char *name, unsigned char *sha1, ...@@ -176,7 +176,7 @@ static void shortlog(const char *name, unsigned char *sha1,
struct commit *commit; struct commit *commit;
struct object *branch; struct object *branch;
struct list subjects = { NULL, NULL, 0, 0 }; struct list subjects = { NULL, NULL, 0, 0 };
int flags = UNINTERESTING | TREECHANGE | SEEN | SHOWN | ADDED; int flags = UNINTERESTING | TREESAME | SEEN | SHOWN | ADDED;
branch = deref_tag(parse_object(sha1), sha1_to_hex(sha1), 40); branch = deref_tag(parse_object(sha1), sha1_to_hex(sha1), 40);
if (!branch || branch->type != OBJ_COMMIT) if (!branch || branch->type != OBJ_COMMIT)
......
...@@ -89,7 +89,7 @@ static int estimate_commit_count(struct rev_info *rev, struct commit_list *list) ...@@ -89,7 +89,7 @@ static int estimate_commit_count(struct rev_info *rev, struct commit_list *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 & TREECHANGE) && !(flags & UNINTERESTING)) if (!(flags & (TREESAME | UNINTERESTING)))
n++; n++;
} }
return n; return n;
......
...@@ -142,7 +142,7 @@ static int count_distance(struct commit_list *entry) ...@@ -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 (commit->object.flags & TREECHANGE) if (!(commit->object.flags & TREESAME))
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) ...@@ -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 (!(p->item->object.flags & TREECHANGE)) if (p->item->object.flags & TREESAME)
return 0; return 0;
if (DEBUG_BISECT) if (DEBUG_BISECT)
return 0; return 0;
...@@ -234,7 +234,7 @@ static void show_list(const char *debug, int counted, int nr, ...@@ -234,7 +234,7 @@ static void show_list(const char *debug, int counted, int nr,
char *ep, *sp; char *ep, *sp;
fprintf(stderr, "%c%c%c ", fprintf(stderr, "%c%c%c ",
(flags & TREECHANGE) ? 'T' : ' ', (flags & TREESAME) ? ' ' : 'T',
(flags & UNINTERESTING) ? 'U' : ' ', (flags & UNINTERESTING) ? 'U' : ' ',
(flags & COUNTED) ? 'C' : ' '); (flags & COUNTED) ? 'C' : ' ');
if (commit->util) if (commit->util)
...@@ -268,7 +268,7 @@ static struct commit_list *best_bisection(struct commit_list *list, int nr) ...@@ -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 (!(flags & TREECHANGE)) if (flags & TREESAME)
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 ...@@ -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 (!(flags & TREECHANGE)) if (flags & TREESAME)
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, ...@@ -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 (flags & TREECHANGE) { if (!(flags & TREESAME)) {
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, ...@@ -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 (flags & TREECHANGE) { if (!(flags & TREESAME)) {
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, ...@@ -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 (flags & TREECHANGE) if (!(flags & TREESAME))
nr++; nr++;
on_list++; on_list++;
} }
......
...@@ -311,17 +311,15 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit) ...@@ -311,17 +311,15 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
/* /*
* If we don't do pruning, everything is interesting * If we don't do pruning, everything is interesting
*/ */
if (!revs->prune) { if (!revs->prune)
commit->object.flags |= TREECHANGE;
return; return;
}
if (!commit->tree) if (!commit->tree)
return; return;
if (!commit->parents) { if (!commit->parents) {
if (!rev_same_tree_as_empty(revs, commit->tree)) if (rev_same_tree_as_empty(revs, commit->tree))
commit->object.flags |= TREECHANGE; commit->object.flags |= TREESAME;
return; return;
} }
...@@ -329,10 +327,8 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit) ...@@ -329,10 +327,8 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
* Normal non-merge commit? If we don't want to make the * Normal non-merge commit? If we don't want to make the
* history dense, we consider it always to be a change.. * history dense, we consider it always to be a change..
*/ */
if (!revs->dense && !commit->parents->next) { if (!revs->dense && !commit->parents->next)
commit->object.flags |= TREECHANGE;
return; return;
}
pp = &commit->parents; pp = &commit->parents;
while ((parent = *pp) != NULL) { while ((parent = *pp) != NULL) {
...@@ -357,6 +353,7 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit) ...@@ -357,6 +353,7 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
} }
parent->next = NULL; parent->next = NULL;
commit->parents = parent; commit->parents = parent;
commit->object.flags |= TREESAME;
return; return;
case REV_TREE_NEW: case REV_TREE_NEW:
...@@ -385,7 +382,8 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit) ...@@ -385,7 +382,8 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
die("bad tree compare for commit %s", sha1_to_hex(commit->object.sha1)); die("bad tree compare for commit %s", sha1_to_hex(commit->object.sha1));
} }
if (tree_changed && !tree_same) if (tree_changed && !tree_same)
commit->object.flags |= TREECHANGE; return;
commit->object.flags |= TREESAME;
} }
static int add_parents_to_list(struct rev_info *revs, struct commit *commit, struct commit_list **list) static int add_parents_to_list(struct rev_info *revs, struct commit *commit, struct commit_list **list)
...@@ -1354,7 +1352,9 @@ static enum rewrite_result rewrite_one(struct rev_info *revs, struct commit **pp ...@@ -1354,7 +1352,9 @@ static enum rewrite_result rewrite_one(struct rev_info *revs, struct commit **pp
return rewrite_one_error; return rewrite_one_error;
if (p->parents && p->parents->next) if (p->parents && p->parents->next)
return rewrite_one_ok; return rewrite_one_ok;
if (p->object.flags & (TREECHANGE | UNINTERESTING)) if (p->object.flags & UNINTERESTING)
return rewrite_one_ok;
if (!(p->object.flags & TREESAME))
return rewrite_one_ok; return rewrite_one_ok;
if (!p->parents) if (!p->parents)
return rewrite_one_noparents; return rewrite_one_noparents;
...@@ -1427,7 +1427,7 @@ enum commit_action simplify_commit(struct rev_info *revs, struct commit *commit) ...@@ -1427,7 +1427,7 @@ enum commit_action simplify_commit(struct rev_info *revs, struct commit *commit)
return commit_ignore; return commit_ignore;
if (revs->prune && revs->dense) { if (revs->prune && revs->dense) {
/* Commit without changes? */ /* Commit without changes? */
if (!(commit->object.flags & TREECHANGE)) { if (commit->object.flags & TREESAME) {
/* drop merges unless we want parenthood */ /* drop merges unless we want parenthood */
if (!revs->parents) if (!revs->parents)
return commit_ignore; return commit_ignore;
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#define SEEN (1u<<0) #define SEEN (1u<<0)
#define UNINTERESTING (1u<<1) #define UNINTERESTING (1u<<1)
#define TREECHANGE (1u<<2) #define TREESAME (1u<<2)
#define SHOWN (1u<<3) #define SHOWN (1u<<3)
#define TMP_MARK (1u<<4) /* for isolated cases; clean after use */ #define TMP_MARK (1u<<4) /* for isolated cases; clean after use */
#define BOUNDARY (1u<<5) #define BOUNDARY (1u<<5)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册