git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[WIP PATCH 21/22] commit parents prunning code

From
Bo Yang <struggleyb.nku@gmail.com>
Date
Jul 24, 2010, 15:13 UTC
Message-ID
<1279984434-28933-22-git-send-email-struggleyb.nku@gmail.com>
In-Reply-To
<1279984434-28933-1-git-send-email-struggleyb.nku@gmail.com>
Signed-off-by: Bo Yang <struggleyb.nku@gmail.com>
---
 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
Previous: Bo YangNext: Bo Yang
Message 23 of 24 in “Some updates since v3”
  1. 00/22 Some updates since v3Bo Yang, Jul 24, 2010
  2. 01/22 parse-options: enhance STOP_AT_NON_OPTIONBo Yang, Jul 24, 2010
  3. 02/22 parse-options: add two helper functionsBo Yang, Jul 24, 2010
  4. 03/22 Add the basic data structure for line level historyBo Yang, Jul 24, 2010
  5. 04/22 Refactor parse_locBo Yang, Jul 24, 2010
  6. 05/22 Parse the -L optionsBo Yang, Jul 24, 2010
  7. 06/22 Export three functions from diff.cBo Yang, Jul 24, 2010
  8. 07/22 Add range clone functionsBo Yang, Jul 24, 2010
  9. 08/22 map/take range to the parent of commitsBo Yang, Jul 24, 2010
  10. 09/22 Print the line logBo Yang, Jul 24, 2010
  11. 10/22 Hook line history into cmd_log, ensuring a topo-ordered walkBo Yang, Jul 24, 2010
  12. 11/22 Add --full-line-diff optionBo Yang, Jul 24, 2010
  13. 12/22 Add tests for line history browserBo Yang, Jul 24, 2010
  14. Thomas RastJul 24, 2010
  15. 13/22 Document line history browserBo Yang, Jul 24, 2010
  16. 14/22 Make rewrite_parents public to other part of gitBo Yang, Jul 24, 2010
  17. 15/22 Add parent rewriting to line history browserBo Yang, Jul 24, 2010
  18. 16/22 Add --graph prefix before line history outputBo Yang, Jul 24, 2010
  19. 17/22 Add test cases for '--graph' of line level logBo Yang, Jul 24, 2010
  20. 18/22 a fast fixBo Yang, Jul 24, 2010
  21. 19/22 Make graph_next_line external to other part of gitBo Yang, Jul 24, 2010
  22. 20/22 some changesBo Yang, Jul 24, 2010
  23. 21/22 commit parents prunning codeBo Yang, Jul 24, 2010
  24. 22/22 A merge should not be printed anywayBo Yang, Jul 24, 2010

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.