revision.c: --full-history fix.
With history simplification, we still show merges that are required to make the history _complete_, i.e. say that you had: a | b / \ c d | | and neither "a" nor "b" actually changed the file, but both "c" and "d" did: in this case we have to leave "b" around just because otherwise there would be no way to show the _relationship_, even if "b" itself doesn't actually change the tree in any way what-so-ever. It would make sense to make that further simplification if the "--parents" flag wasn't present. In that case the user is literally asking for a list of commits and is not interested in the relationship between them. This patch also fixes a real bug. Without this patch, the "--parents --full-history" combination (which you'd get if you do something like gitk --full-history Makefile or similar) will actually _drop_ merges where all children are identical. That's wrong in the --full-history case, because it means that the graph ends up missing lots of entries. In the process, this also should make git-rev-list --full-history Makefile give just the _true_ list of all commits that changed Makefile (and properly ignore merges that were identical in one parent), because now we're not asking for "--parent", so we don't need the unnecessary merge commits to keep the history together. Signed-off-by: Linus Torvalds <torvalds@osdl.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
parent
ac3bc6c1d1
commit
6631c73685
16
revision.c
16
revision.c
@ -280,7 +280,7 @@ int rev_same_tree_as_empty(struct rev_info *revs, struct tree *t1)
|
|||||||
static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
|
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;
|
int tree_changed = 0, tree_same = 0;
|
||||||
|
|
||||||
if (!commit->tree)
|
if (!commit->tree)
|
||||||
return;
|
return;
|
||||||
@ -298,6 +298,7 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
|
|||||||
parse_commit(p);
|
parse_commit(p);
|
||||||
switch (rev_compare_tree(revs, p->tree, commit->tree)) {
|
switch (rev_compare_tree(revs, p->tree, commit->tree)) {
|
||||||
case REV_TREE_SAME:
|
case REV_TREE_SAME:
|
||||||
|
tree_same = 1;
|
||||||
if (!revs->simplify_history || (p->object.flags & UNINTERESTING)) {
|
if (!revs->simplify_history || (p->object.flags & UNINTERESTING)) {
|
||||||
/* Even if a merge with an uninteresting
|
/* Even if a merge with an uninteresting
|
||||||
* side branch brought the entire change
|
* side branch brought the entire change
|
||||||
@ -334,7 +335,7 @@ 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)
|
if (tree_changed && !tree_same)
|
||||||
commit->object.flags |= TREECHANGE;
|
commit->object.flags |= TREECHANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -896,6 +897,8 @@ static int rewrite_one(struct rev_info *revs, struct commit **pp)
|
|||||||
struct commit *p = *pp;
|
struct commit *p = *pp;
|
||||||
if (!revs->limited)
|
if (!revs->limited)
|
||||||
add_parents_to_list(revs, p, &revs->commits);
|
add_parents_to_list(revs, p, &revs->commits);
|
||||||
|
if (p->parents && p->parents->next)
|
||||||
|
return 0;
|
||||||
if (p->object.flags & (TREECHANGE | UNINTERESTING))
|
if (p->object.flags & (TREECHANGE | UNINTERESTING))
|
||||||
return 0;
|
return 0;
|
||||||
if (!p->parents)
|
if (!p->parents)
|
||||||
@ -988,8 +991,15 @@ struct commit *get_revision(struct rev_info *revs)
|
|||||||
commit->parents && commit->parents->next)
|
commit->parents && commit->parents->next)
|
||||||
continue;
|
continue;
|
||||||
if (revs->prune_fn && revs->dense) {
|
if (revs->prune_fn && revs->dense) {
|
||||||
if (!(commit->object.flags & TREECHANGE))
|
/* Commit without changes? */
|
||||||
|
if (!(commit->object.flags & TREECHANGE)) {
|
||||||
|
/* drop merges unless we want parenthood */
|
||||||
|
if (!revs->parents)
|
||||||
continue;
|
continue;
|
||||||
|
/* non-merge - always ignore it */
|
||||||
|
if (commit->parents && !commit->parents->next)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (revs->parents)
|
if (revs->parents)
|
||||||
rewrite_parents(revs, commit);
|
rewrite_parents(revs, commit);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user