[WIP PATCH 21/22] commit parents prunning code

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Bo Yang <struggleyb.nku@xxxxxxxxx>
---
 line.c |   48 ++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/line.c b/line.c
index 272f166..bc9fc76 100644
--- a/line.c
+++ b/line.c
@@ -390,6 +390,7 @@ struct diff_line_range *diff_line_range_clone(struct diff_line_range *r)
 	struct diff_line_range *ret = xmalloc(sizeof(*ret));
 	int i = 0;
 
+	assert(r);
 	DIFF_LINE_RANGE_INIT(ret);
 	ret->ranges = xcalloc(r->nr, sizeof(struct range));
 	memcpy(ret->ranges, r->ranges, sizeof(struct range) * r->nr);
@@ -993,13 +994,21 @@ static void diff_update_parent_range(struct rev_info *rev, struct commit *commit
 	assign_range_to_parent(rev, commit, c, r, &rev->diffopt, 1);
 }
 
+struct commit_state {
+	struct diff_line_range *range;
+	struct object obj;
+};
+
 static void assign_parents_range(struct rev_info *rev, struct commit *commit)
 {
 	struct commit_list *parents = commit->parents;
 	struct diff_line_range *r = lookup_line_range(rev, commit);
 	struct diff_line_range *copy = NULL, *range = NULL;
+	struct decoration parents_state;
+	struct commit_state *state = NULL;
 	int nontrivial = 0;
 
+	memset(&parents_state, 0, sizeof(parents_state));
 	/*
 	 * If we are in linear history, update range and flush the patch if
 	 * necessary
@@ -1020,36 +1029,44 @@ static void assign_parents_range(struct rev_info *rev, struct commit *commit)
 	while (parents) {
 		struct commit *p = parents->item;
 		int diff = 0;
+		struct diff_line_range *origin_range = lookup_line_range(rev, p);
+		if (origin_range)
+			origin_range = diff_line_range_clone_deeply(origin_range);
+
+		state = xmalloc(sizeof(*state));
+		state->range = origin_range;
+		state->obj = p->object;
+		add_decoration(&parents_state, &p->object, state);
 		diff = assign_range_to_parent(rev, commit, p, r, &rev->diffopt, 1);
 		/* Since all the ranges comes from this parent, we can ignore others */
 		if (diff == 0) {
-			/* parent rewriting code */
+			/* restore the state of parents before this one */
 			parents = commit->parents;
 			while (parents->item != p) {
 				struct commit_list *list = parents;
 				struct diff_line_range *line_range = NULL;
 				parents = parents->next;
 				line_range = lookup_line_range(rev, list->item);
-				add_line_range(rev, list->item, NULL);
-				free(line_range);
-				list->item->object.flags &= ~(RANGE_UPDATE | NEED_PRINT | EVIL_MERGE);
+				cleanup(line_range);
+				state = lookup_decoration(&parents_state, &list->item->object);
+				add_decoration(&parents_state, &list->item->object, NULL);
+				add_line_range(rev, list->item, state->range);
+				list->item->object = state->obj;
+				free(state);
 				free(list);
 			}
+
 			commit->parents = parents;
 			parents = parents->next;
 			commit->parents->next = NULL;
 			while (parents) {
 				struct commit_list *list = parents;
-				struct diff_line_range *line_range = NULL;
 				parents = parents->next;
-				line_range = lookup_line_range(rev, list->item);
-				add_line_range(rev, list->item, NULL);
-				free(line_range);
-				list->item->object.flags &= ~(RANGE_UPDATE | NEED_PRINT | EVIL_MERGE);
 				free(list);
 			}
-			return;
+			goto out;
 		}
+		/* take the ranges from 'commit', try to detect nontrivial merge */
 		assign_range_to_parent(rev, commit, p, copy, &rev->diffopt, 0);
 		parents = parents->next;
 	}
@@ -1066,6 +1083,17 @@ static void assign_parents_range(struct rev_info *rev, struct commit *commit)
 		range = range->next;
 	}
 
+out:
+	parents = commit->parents;
+	while (parents) {
+		state = lookup_decoration(&parents_state, &parents->item->object);
+		if (state) {
+			cleanup(state->range);
+			free(state);
+		}
+		parents = parents->next;
+	}
+
 	if (nontrivial) {
 		add_decoration(&rev->nontrivial_merge, &commit->object, copy);
 	} else {
-- 
1.7.0.2.273.gc2413.dirty

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]