git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: "git\@vger.kernel.org" <git@vger.kernel.org>
Cc: Phil Hord <phil.hord@gmail.com>
Subject: [PATCH] simplify-merges: drop merge from irrelevant side branch
Date: Thu, 17 Jan 2013 14:23:03 -0800	[thread overview]
Message-ID: <7va9s7tpo8.fsf_-_@alter.siamese.dyndns.org> (raw)
In-Reply-To: <7vk3re0zyt.fsf@alter.siamese.dyndns.org> (Junio C. Hamano's message of "Tue, 15 Jan 2013 15:48:58 -0800")

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>
---

 * The old test vector had a history ending at I; the updates to it
   adds an unrelated side branch rooted at J, merge of I and J which
   is K, and then an extra commit L on top.

	A---(some merge mess)---I---K---L
                                   /
                                  J

 revision.c                   | 19 +++++++++++++++++++
 t/t6012-rev-list-simplify.sh | 26 +++++++++++++++++++++-----
 2 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/revision.c b/revision.c
index 33cb207..532611b 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,9 @@ static struct commit_list **simplify_one(struct rev_info *revs, struct commit *c
 		pst = locate_simplify_state(revs, p->item);
 		p->item = pst->simplified;
 	}
+
+	remove_treesame_parents(commit);
+
 	cnt = remove_duplicate_parents(commit);
 
 	/*
diff --git a/t/t6012-rev-list-simplify.sh b/t/t6012-rev-list-simplify.sh
index 510bb96..d6d79c4 100755
--- a/t/t6012-rev-list-simplify.sh
+++ b/t/t6012-rev-list-simplify.sh
@@ -59,7 +59,23 @@ test_expect_success setup '
 
 	echo "Final change" >file &&
 	test_tick && git commit -a -m "Final change" &&
-	note I
+	note I &&
+
+	git symbolic-ref HEAD refs/heads/unrelated &&
+	git rm -f "*" &&
+	echo "Unrelated branch" >side &&
+	git add side &&
+	test_tick && git commit -m "Side root" &&
+	note J &&
+
+	git checkout master &&
+	test_tick && git merge -m "Coolest" unrelated &&
+	note K &&
+
+	echo "Immaterial" >elif &&
+	git add elif &&
+	test_tick && git commit -m "Last" &&
+	note L
 '
 
 FMT='tformat:%P 	%H | %s'
@@ -82,10 +98,10 @@ check_result () {
 	'
 }
 
-check_result 'I H G F E D C B A' --full-history
-check_result 'I H E C B A' --full-history -- file
-check_result 'I H E C B A' --full-history --topo-order -- file
-check_result 'I H E C B A' --full-history --date-order -- file
+check_result 'L K J I H G F E D C B A' --full-history
+check_result 'K I H E C B A' --full-history -- file
+check_result 'K I H E C B A' --full-history --topo-order -- file
+check_result 'K I H E C B A' --full-history --date-order -- file
 check_result 'I E C B A' --simplify-merges -- file
 check_result 'I B A' -- file
 check_result 'I B A' --topo-order -- file
-- 
1.8.1.1.431.g469ab37

      reply	other threads:[~2013-01-17 22:23 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-01-15 23:12 --simplify-merges returns too many references Phil Hord
2013-01-15 23:48 ` Junio C Hamano
2013-01-17 22:23   ` Junio C Hamano [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7va9s7tpo8.fsf_-_@alter.siamese.dyndns.org \
    --to=gitster@pobox.com \
    --cc=git@vger.kernel.org \
    --cc=phil.hord@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).