From: Junio C Hamano <junkio@cox.net>
To: Linus Torvalds <torvalds@osdl.org>
Cc: git@vger.kernel.org
Subject: merge-base: fully contaminate the well.
Date: Thu, 10 Nov 2005 18:58:07 -0800 [thread overview]
Message-ID: <7vzmobuc00.fsf@assigned-by-dhcp.cox.net> (raw)
In-Reply-To: Pine.LNX.4.64.0511091348530.4627@g5.osdl.org
The discussion on the list demonstrated a pathological case where
an ancestor of a merge-base can be left interesting. This commit
introduces a postprocessing phase to fix it.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
Linus Torvalds <torvalds@osdl.org> writes:
> On Wed, 9 Nov 2005, Junio C Hamano wrote:
>
>> But the point of well-poisoning you did in merge-base was to
>> detect that E is an ancestor of B and exclude it in the first
>> place.
>
> Ahh, you're right, and I'm wrong. That "E" is not a real merge-base, since
> there _is_ a valid merge-base that is a direct descendant of it and thus
> objectively better.
>
> Which means that sometimes it can stop with too _many_ merge heads, just
> because it hasn't realized that they are reachable through a chain that is
> otherwise provably uninteresting.
I am not particularly proud of this change, but here is an
attempt to fully contaminate the well without going all the
way down to root. It adds a postprocessing phase which does
not parse any new commits.
> The thing is, I don't see what guarantees that the show-branch brhaviour
> is safe or conservative.
You are right about this; I have a separate patch to fix it.
merge-base.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 77 insertions(+), 1 deletions(-)
applies-to: 8eacf17303188e55375f76bea8051555ba1baf02
a2fd94f707128f3f390362725c8d8b0802940111
diff --git a/merge-base.c b/merge-base.c
index 286bf0e..43a6818 100644
--- a/merge-base.c
+++ b/merge-base.c
@@ -80,6 +80,45 @@ static struct commit *interesting(struct
* Now, list does not have any interesting commit. So we find the newest
* commit from the result list that is not marked uninteresting. Which is
* commit B.
+ *
+ *
+ * Another pathological example how this thing can fail to mark an ancestor
+ * of a merge base as UNINTERESTING without the postprocessing phase.
+ *
+ * 2
+ * H
+ * 1 / \
+ * G A \
+ * |\ / \
+ * | B \
+ * | \ \
+ * \ C F
+ * \ \ /
+ * \ D /
+ * \ | /
+ * \| /
+ * E
+ *
+ * list A B C D E F G H
+ * G1 H2 - - - - - - 1 2
+ * H2 E1 B1 - 1 - - 1 - 1 2
+ * F2 E1 B1 A2 2 1 - - 1 2 1 2
+ * E3 B1 A2 2 1 - - 3 2 1 2
+ * B1 A2 2 1 - - 3 2 1 2
+ * C1 A2 2 1 1 - 3 2 1 2
+ * D1 A2 2 1 1 1 3 2 1 2
+ * A2 2 1 1 1 3 2 1 2
+ * B3 2 3 1 1 3 2 1 2
+ * C7 2 3 7 1 3 2 1 2
+ *
+ * At this point, unfortunately, everybody in the list is
+ * uninteresting, so we fail to complete the following two
+ * steps to fully marking uninteresting commits.
+ *
+ * D7 2 3 7 7 3 2 1 2
+ * E7 2 3 7 7 7 2 1 2
+ *
+ * and we end up showing E as an interesting merge base.
*/
static int show_all = 0;
@@ -88,6 +127,7 @@ static int merge_base(struct commit *rev
{
struct commit_list *list = NULL;
struct commit_list *result = NULL;
+ struct commit_list *tmp = NULL;
if (rev1 == rev2) {
printf("%s\n", sha1_to_hex(rev1->object.sha1));
@@ -104,9 +144,10 @@ static int merge_base(struct commit *rev
while (interesting(list)) {
struct commit *commit = list->item;
- struct commit_list *tmp = list, *parents;
+ struct commit_list *parents;
int flags = commit->object.flags & 7;
+ tmp = list;
list = list->next;
free(tmp);
if (flags == 3) {
@@ -130,6 +171,41 @@ static int merge_base(struct commit *rev
if (!result)
return 1;
+ /*
+ * Postprocess to fully contaminate the well.
+ */
+ for (tmp = result; tmp; tmp = tmp->next) {
+ struct commit *c = tmp->item;
+ /* Reinject uninteresting ones to list,
+ * so we can scan their parents.
+ */
+ if (c->object.flags & UNINTERESTING)
+ commit_list_insert(c, &list);
+ }
+ while (list) {
+ struct commit *c = list->item;
+ struct commit_list *parents;
+
+ tmp = list;
+ list = list->next;
+ free(tmp);
+
+ /* Anything taken out of the list is uninteresting, so
+ * mark all its parents uninteresting. We do not
+ * parse new ones (we already parsed all the relevant
+ * ones).
+ */
+ parents = c->parents;
+ while (parents) {
+ struct commit *p = parents->item;
+ parents = parents->next;
+ if (!(p->object.flags & UNINTERESTING)) {
+ p->object.flags |= UNINTERESTING;
+ commit_list_insert(p, &list);
+ }
+ }
+ }
+
while (result) {
struct commit *commit = result->item;
result = result->next;
---
0.99.9.GIT
next prev parent reply other threads:[~2005-11-11 2:58 UTC|newest]
Thread overview: 58+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-11-07 16:48 Comments on recursive merge Linus Torvalds
2005-11-07 16:56 ` Linus Torvalds
2005-11-07 23:19 ` [PATCH] merge-recursive: Only print relevant rename messages Fredrik Kuivinen
2005-11-07 23:54 ` Junio C Hamano
2005-11-09 10:36 ` Fredrik Kuivinen
2005-11-07 22:58 ` Comments on recursive merge Fredrik Kuivinen
2005-11-08 0:13 ` Junio C Hamano
2005-11-08 0:33 ` Linus Torvalds
2005-11-08 0:59 ` Junio C Hamano
2005-11-08 11:58 ` Johannes Schindelin
2005-11-08 21:02 ` Fredrik Kuivinen
2005-11-08 21:47 ` Junio C Hamano
2005-11-08 21:52 ` Linus Torvalds
2005-11-08 22:36 ` Fredrik Kuivinen
2005-11-08 23:05 ` Linus Torvalds
2005-11-08 23:18 ` Johannes Schindelin
2005-11-09 0:18 ` Linus Torvalds
2005-11-09 6:10 ` Junio C Hamano
2005-11-09 0:32 ` Petr Baudis
2005-11-09 0:51 ` Linus Torvalds
2005-11-09 0:59 ` Junio C Hamano
2005-11-09 1:22 ` Linus Torvalds
2005-11-09 1:42 ` Junio C Hamano
2005-11-09 10:20 ` Junio C Hamano
2005-11-09 14:59 ` Petr Baudis
2005-11-09 16:30 ` Linus Torvalds
2005-11-09 20:13 ` Junio C Hamano
2005-11-09 21:58 ` Linus Torvalds
2005-11-09 22:56 ` Junio C Hamano
2005-11-09 23:34 ` Linus Torvalds
2005-11-11 2:58 ` Junio C Hamano [this message]
2005-11-11 5:36 ` merge-base: fully contaminate the well Linus Torvalds
2005-11-11 6:04 ` Junio C Hamano
2005-11-11 16:18 ` Linus Torvalds
2005-11-11 8:28 ` Junio C Hamano
2005-11-08 23:04 ` Comments on recursive merge Johannes Schindelin
2005-11-08 16:21 ` [RFC/PATCH] Make git-recursive the default strategy for git-pull Junio C Hamano
2005-11-11 22:25 ` Comments on recursive merge Junio C Hamano
2005-11-11 22:53 ` Linus Torvalds
2005-11-12 0:42 ` Junio C Hamano
2005-11-12 6:35 ` Ryan Anderson
2005-11-12 7:44 ` [PATCH] GIT commit statistics Junio C Hamano
2005-11-12 12:19 ` Martin Langhoff
2005-11-12 12:53 ` Petr Baudis
2005-11-15 10:04 ` Catalin Marinas
2005-11-15 15:29 ` Chuck Lever
2005-11-12 19:04 ` Johannes Schindelin
2005-11-13 10:59 ` Junio C Hamano
2005-11-13 20:42 ` Martin Langhoff
2005-11-14 3:33 ` Junio C Hamano
2005-11-14 4:01 ` Martin Langhoff
2005-11-14 6:06 ` Junio C Hamano
2005-11-14 8:51 ` Martin Langhoff
2005-11-14 9:25 ` Petr Baudis
2005-11-14 21:25 ` Martin Langhoff
2005-11-14 9:27 ` Junio C Hamano
2005-11-15 3:00 ` Junio C Hamano
2005-11-13 11:11 ` Petr Baudis
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
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=7vzmobuc00.fsf@assigned-by-dhcp.cox.net \
--to=junkio@cox.net \
--cc=git@vger.kernel.org \
--cc=torvalds@osdl.org \
/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.
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 NNTP newsgroup(s).