[WIP PATCH 20/22] some changes

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

 



1. if one parent is responsible for all ranges, then prune the
   parents list to only this one;
2. some other minor changes.

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

diff --git a/line.c b/line.c
index ca8980d..272f166 100644
--- a/line.c
+++ b/line.c
@@ -470,15 +470,15 @@ void add_line_range(struct rev_info *revs, struct commit *commit, struct diff_li
 {
 	struct diff_line_range *ret = NULL;
 
-	if (r != NULL) {
-		ret = lookup_decoration(&revs->line_range, &commit->object);
-		if (ret != NULL) {
-			diff_line_range_merge(ret, r);
-		} else {
-			add_decoration(&revs->line_range, &commit->object, r);
-		}
-		commit->object.flags |= RANGE_UPDATE;
+	ret = lookup_decoration(&revs->line_range, &commit->object);
+	if (ret != NULL && r != NULL) {
+		diff_line_range_merge(ret, r);
+	} else {
+		add_decoration(&revs->line_range, &commit->object, r);
 	}
+
+	if (r != NULL)
+		commit->object.flags |= RANGE_UPDATE;
 }
 
 struct diff_line_range *lookup_line_range(struct rev_info *revs, struct commit *commit)
@@ -544,8 +544,26 @@ void map_lines(long p_start, long p_end, long t_start, long t_end,
 		return;
 	}
 
-	if (start == t_start && end == t_end) {
+	if (start == t_start && end == t_end)
+	{
+		*o_start = p_start;
+		*o_end = p_end;
+		return;
+	}
+
+	if (start == t_start)
+	{
 		*o_start = p_start;
+		*o_end = p_start + (end - start);
+		if (*o_end > p_end)
+			*o_end = p_end;
+		return;
+	}
+
+	if (end == t_end) {
+		*o_start = p_end - (end - start);
+		if (*o_start < p_start)
+			*o_start = p_start;
 		*o_end = p_end;
 		return;
 	}
@@ -771,7 +789,7 @@ static void map_range_cb(void *data, long same, long p_next, long t_next)
 	d->tlno = t_next;
 }
 
-static void assign_range_to_parent(struct rev_info *rev, struct commit *c,
+static int assign_range_to_parent(struct rev_info *rev, struct commit *c,
 		struct commit *p, struct diff_line_range *r,
 		struct diff_options *opt, int map)
 {
@@ -917,20 +935,49 @@ static void assign_range_to_parent(struct rev_info *rev, struct commit *c,
 		}
 	}
 
+	if (!map)
+		goto out;
+
 	if (rr) {
 		assert(p);
 		add_line_range(rev, p, rr);
 	}
 
+	/* debug output */
+	/*
+	fprintf(stderr, "%8s..%8s:\n", sha1_to_hex(p->object.sha1), sha1_to_hex(c->object.sha1));
+	while (r) {
+		fprintf(stderr, "file: %s\n", r->spec->path);
+		int n = 0;
+		for (; n < r->nr; n++) {
+			fprintf(stderr, "%d-%d, ", r->ranges[n].start, r->ranges[n].end);
+		}
+		r = r->next;
+	}
+	fprintf(stderr, "\n");
+	while (rr) {
+		fprintf(stderr, "file: %s\n", rr->spec->path);
+		int n = 0;
+		for (; n < rr->nr; n++) {
+			fprintf(stderr, "%d-%d, ", rr->ranges[n].start, rr->ranges[n].end);
+		}
+		rr = rr->next;
+	}
+	fprintf(stderr, "\n");
+	*/
+
 	/* and the ranges of current commit c is updated */
 	c->object.flags &= ~RANGE_UPDATE;
 	if (diff)
 		c->object.flags |= NEED_PRINT;
 
+out:
 	if (tree1)
 		free(tree1);
 	if (tree2)
 		free(tree2);
+
+	return diff;
 }
 
 static void diff_update_parent_range(struct rev_info *rev, struct commit *commit)
@@ -967,16 +1014,46 @@ static void assign_parents_range(struct rev_info *rev, struct commit *commit)
 	 * be an evil merge.
 	 */
 	copy = diff_line_range_clone_deeply(r);
+	/* Never print out any diff for a merge commit */
+	commit->object.flags &= ~NEED_PRINT;
 	parents = commit->parents;
 	while (parents) {
 		struct commit *p = parents->item;
-		assign_range_to_parent(rev, commit, p, r, &rev->diffopt, 1);
+		int diff = 0;
+		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 */
+			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);
+				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;
+		}
 		assign_range_to_parent(rev, commit, p, copy, &rev->diffopt, 0);
 		parents = parents->next;
 	}
 
-	/* Never print out any diff for a merge commit */
-	commit->object.flags &= ~NEED_PRINT;
 	/*
 	 * yes, this must be an evil merge.
 	 */
@@ -1262,6 +1339,8 @@ static void line_log_flush(struct rev_info *rev, struct commit *c)
 							c->object.flags & NEED_PRINT))
 		return;
 
+	if (rev->graph)
+		graph_update(rev->graph, c);
 	log.commit = c;
 	log.parent = NULL;
 	rev->loginfo = &log;
@@ -1275,12 +1354,21 @@ static void line_log_flush(struct rev_info *rev, struct commit *c)
 	fprintf(rev->diffopt.file, "%s\n", line_prefix);
 
 	if (c->object.flags & EVIL_MERGE)
-		return flush_nontrivial_merge(rev, nontrivial);
+		flush_nontrivial_merge(rev, nontrivial);
+	else {
+		while (range) {
+			if (range->diff || (range->nr && rev->full_line_diff))
+				diff_flush_filepair(rev, range);
+			range = range->next;
+		}
+	}
 
-	while (range) {
-		if (range->diff || (range->nr && rev->full_line_diff))
-			diff_flush_filepair(rev, range);
-		range = range->next;
+	while (rev->graph && !graph_is_commit_finished(rev->graph))
+	{
+		struct strbuf sb;
+		strbuf_init(&sb, 0);
+		graph_next_line(rev->graph, &sb);
+		fputs(sb.buf, opt->file);
 	}
 }
 
@@ -1316,8 +1404,6 @@ int cmd_line_log_walk(struct rev_info *rev)
 		if (commit->object.flags & NEED_PRINT ||
 			commit->object.flags & EVIL_MERGE ||
 			rev->full_line_diff || rev->graph) {
-			if (rev->graph)
-				graph_update(rev->graph, commit);
 			line_log_flush(rev, commit);
 		}
 
@@ -1350,8 +1436,6 @@ static enum rewrite_result rewrite_one(struct rev_info *rev, struct commit **pp)
 		p = *pp;
 		if (p->object.flags & RANGE_UPDATE)
 			assign_parents_range(rev, p);
-		if (p->parents && p->parents->next)
-			return rewrite_one_ok;
 		if (p->object.flags & NEED_PRINT)
 			return rewrite_one_ok;
 		if (!p->parents)
-- 
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]