Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2013-01-18 02:23:03 +0400
committerJunio C Hamano <gitster@pobox.com>2013-01-18 03:22:48 +0400
commit4b7f53da7618e94985c9d9d5081b4bc44c45de2f (patch)
tree909a630447fce8467cd286342bf38ee269794c61 /revision.c
parentfaf0156b278d1a760362cda1d294a88be7608de4 (diff)
simplify-merges: drop merge from irrelevant side branch
The merge simplification rule stated in 6546b59 (revision traversal: show full history with merge simplification, 2008-07-31) still treated merge commits too specially. Namely, in a history with this shape: ---o---o---M / x---x---x where three 'x' were on a history completely unrelated to the main history 'o' and do not touch any of the paths we are following, we still said that after simplifying all of the parents of M, 'x' (which is the leftmost 'x' that rightmost 'x simplifies down to) and 'o' (which would be the last commit on the main history that touches the paths we are following) are independent from each other, and both need to be kept. That is incorrect; when the side branch 'x' never touches the paths, it should be removed to allow M to simplify down to the last commit on the main history that touches the paths. Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'revision.c')
-rw-r--r--revision.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/revision.c b/revision.c
index 33cb207f28..3536635a88 100644
--- a/revision.c
+++ b/revision.c
@@ -1424,6 +1424,22 @@ static struct merge_simplify_state *locate_simplify_state(struct rev_info *revs,
return st;
}
+static void remove_treesame_parents(struct commit *commit)
+{
+ struct commit_list **pp, *p;
+
+ pp = &commit->parents;
+ while ((p = *pp) != NULL) {
+ struct commit *parent = p->item;
+ if (parent->object.flags & TREESAME) {
+ *pp = p->next;
+ free(p);
+ continue;
+ }
+ pp = &p->next;
+ }
+}
+
static struct commit_list **simplify_one(struct rev_info *revs, struct commit *commit, struct commit_list **tail)
{
struct commit_list *p;
@@ -1469,6 +1485,13 @@ static struct commit_list **simplify_one(struct rev_info *revs, struct commit *c
pst = locate_simplify_state(revs, p->item);
p->item = pst->simplified;
}
+
+ /*
+ * A merge with a tree-same parent is useless
+ */
+ if (commit->parents && commit->parents->next)
+ remove_treesame_parents(commit);
+
cnt = remove_duplicate_parents(commit);
/*