From: Kevin Bracey <kevin@bracey.fi>
To: git@vger.kernel.org
Cc: Junio C Hamano <gitster@pobox.com>,
Linus Torvalds <torvalds@linux-foundation.org>,
Kevin Bracey <kevin@bracey.fi>
Subject: [PATCH v3 7/9] simplify-merges: never remove all TREESAME parents
Date: Sun, 5 May 2013 18:32:55 +0300 [thread overview]
Message-ID: <1367767977-14513-8-git-send-email-kevin@bracey.fi> (raw)
In-Reply-To: <1367767977-14513-1-git-send-email-kevin@bracey.fi>
When simplifying an odd merge, such as one that used "-s ours", we may
find ourselves TREESAME to apparently redundant parents. Prevent
simplify_merges() from removing every TREESAME parent; if this would
happen reinstate the first TREESAME parent - the one that the default
log would have followed.
This avoids producing a totally disjoint history from the default log
when the default log is a better explanation of the end result, and aids
visualisation of odd merges.
Signed-off-by: Kevin Bracey <kevin@bracey.fi>
---
Documentation/rev-list-options.txt | 3 +-
revision.c | 69 ++++++++++++++++++++++++++++++++++++++
t/t6111-rev-list-treesame.sh | 2 +-
3 files changed, 72 insertions(+), 2 deletions(-)
diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt
index 1dad341..e23bdb0 100644
--- a/Documentation/rev-list-options.txt
+++ b/Documentation/rev-list-options.txt
@@ -471,7 +471,8 @@ history according to the following rules:
+
* Replace each parent `P` of `C'` with its simplification `P'`. In
the process, drop parents that are ancestors of other parents, and
- remove duplicates.
+ remove duplicates, but take care to never drop all parents that
+ we are TREESAME to.
+
* If after this parent rewriting, `C'` is a root or merge commit (has
zero or >1 parents), a boundary commit, or !TREESAME, it remains.
diff --git a/revision.c b/revision.c
index c88ded8..7535757 100644
--- a/revision.c
+++ b/revision.c
@@ -2119,6 +2119,73 @@ static int mark_redundant_parents(struct rev_info *revs, struct commit *commit)
return marked;
}
+/*
+ * Awkward naming - this means one parent we are TREESAME to.
+ * cf mark_treesame_root_parents: root parents that are TREESAME (to an
+ * empty tree). Better name suggestions?
+ */
+static int leave_one_treesame_to_parent(struct rev_info *revs, struct commit *commit)
+{
+ struct treesame_state *ts = lookup_decoration(&revs->treesame, &commit->object);
+ struct commit *unmarked = NULL, *marked = NULL;
+ struct commit_list *p;
+ unsigned n;
+
+ for (p = commit->parents, n = 0; p; p = p->next, n++) {
+ if (ts->treesame[n]) {
+ if (p->item->object.flags & TMP_MARK) {
+ if (!marked)
+ marked = p->item;
+ } else {
+ if (!unmarked) {
+ unmarked = p->item;
+ break;
+ }
+ }
+ }
+ }
+
+ /*
+ * If we are TREESAME to a marked-for-deletion parent, but not to any
+ * unmarked parents, unmark the first TREESAME parent. This is the
+ * parent that the default simplify_history==1 scan would have followed,
+ * and it doesn't make sense to omit that path when asking for a
+ * simplified full history. Retaining it improves the chances of
+ * understanding odd missed merges that took an old version of a file.
+ *
+ * Example:
+ *
+ * I---------X A modified the file, but mainline merge X used
+ * \ / "-s ours", so took the version from I. X is
+ * `--A--' TREESAME to I and !TREESAME to A.
+ *
+ * Default log from X would produce "I". Without this check,
+ * --full-history --simplify-merges would produce "I-A-X", showing
+ * the merge commit X and that it changed A, but not making clear that
+ * it had just taken the I version. With this check, the topology above
+ * is retained.
+ *
+ * Note that it is possible that the simplification chooses a different
+ * TREESAME parent from the default, in which case this test doesn't
+ * activate, and we _do_ drop the default parent. Example:
+ *
+ * I------X A modified the file, but it was reverted in B,
+ * \ / meaning mainline merge X is TREESAME to both
+ * A--B parents.
+ *
+ * Default log would produce "I" by following the first parent;
+ * --full-history --simplify-merges will produce "I-A-B". But this is a
+ * reasonable result - it presents a logical full history leading from
+ * I to X, and X is not an important merge.
+ */
+ if (!unmarked && marked) {
+ marked->object.flags &= ~TMP_MARK;
+ return 1;
+ }
+
+ return 0;
+}
+
static int remove_marked_parents(struct rev_info *revs, struct commit *commit)
{
struct commit_list **pp, *p;
@@ -2222,6 +2289,8 @@ static struct commit_list **simplify_one(struct rev_info *revs, struct commit *c
if (1 < cnt) {
int marked = mark_redundant_parents(revs, commit);
if (marked)
+ marked -= leave_one_treesame_to_parent(revs, commit);
+ if (marked)
cnt = remove_marked_parents(revs, commit);
}
diff --git a/t/t6111-rev-list-treesame.sh b/t/t6111-rev-list-treesame.sh
index efc2442..5cc0c34 100755
--- a/t/t6111-rev-list-treesame.sh
+++ b/t/t6111-rev-list-treesame.sh
@@ -104,7 +104,7 @@ check_result 'M L H B A' -- file
check_result 'M L H B A' --parents -- file
check_result 'M L J I H G F D B A' --full-history -- file
check_result 'M L K J I H G F D B A' --full-history --parents -- file
-check_result 'M H L J I G F B A' --simplify-merges -- file
+check_result 'M H L J I G F B A' --simplify-merges -- file # should check that G has parent B
check_result 'M L K G F D B A' --first-parent
check_result 'M L G F B A' --first-parent -- file
--
1.8.3.rc0.28.g682c2d9
next prev parent reply other threads:[~2013-05-05 15:33 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-05-05 15:32 [PATCH v3 0/9] History traversal refinements Kevin Bracey
2013-05-05 15:32 ` [PATCH v3 1/9] decorate.c: compact table when growing Kevin Bracey
2013-05-05 15:32 ` [PATCH v3 2/9] t6019: test file dropped in -s ours merge Kevin Bracey
2013-05-05 15:32 ` [PATCH v3 3/9] t6111: new TREESAME test set Kevin Bracey
2013-05-06 19:37 ` Junio C Hamano
2013-05-06 20:36 ` Junio C Hamano
2013-05-07 15:19 ` Kevin Bracey
2013-05-07 16:28 ` Junio C Hamano
2013-05-05 15:32 ` [PATCH v3 4/9] rev-list-options.txt: correct TREESAME for P Kevin Bracey
2013-05-05 15:32 ` [PATCH v3 5/9] revision.c: Make --full-history consider more merges Kevin Bracey
2013-05-06 20:45 ` Junio C Hamano
2013-05-07 14:46 ` Kevin Bracey
2013-05-07 15:21 ` Junio C Hamano
2013-05-05 15:32 ` [PATCH v3 6/9] t6012: update test for tweaked full-history traversal Kevin Bracey
2013-05-05 15:32 ` Kevin Bracey [this message]
2013-05-05 15:32 ` [PATCH v3 8/9] simplify-merges: drop merge from irrelevant side branch Kevin Bracey
2013-05-05 15:32 ` [PATCH v3 9/9] revision.c: discount side branches when computing TREESAME Kevin Bracey
2013-05-06 16:51 ` [PATCH v3 10/9] revision.c: treat A...B merge bases as if manually specified Kevin Bracey
2013-05-06 21:24 ` Junio C Hamano
2013-05-07 15:52 ` Kevin Bracey
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=1367767977-14513-8-git-send-email-kevin@bracey.fi \
--to=kevin@bracey.fi \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=torvalds@linux-foundation.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).