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

Re: [PATCH v4 1/2] push: Don't push a repository with unpushed submodules

From
Junio C Hamano <gitster@pobox.com>
Date
Aug 20, 2011, 06:32 UTC
Message-ID
<7vippszj70.fsf@alter.siamese.dyndns.org>
In-Reply-To
<7vwre9yodc.fsf@alter.siamese.dyndns.org>
Junio C Hamano <gitster@pobox.com> writes:
Show 5 quoted lines
> What I meant was more along the lines of the following, but I think we
> would need a new kind of callback that can take N-way parents (which is
> not depicted here).
>
> Let me cook up something and get back to you later tonight.
And here is a two-patch series to do just that.

The first one is meant for you to use, and the second one is a sample application of the new machinery.

-- >8 --
Subject: [PATCH 1/2] combine-diff: support format_callback

This teaches combine-diff machinery to feed a combined merge to a callback function when DIFF_FORMAT_CALLBACK is specified.

So far, format callback functions are not used for anything but 2-way diffs. A callback is given a diff_queue_struct, which is an array of diff_filepair. As its name suggests, a diff_filepair is a _pair_ of diff_filespec that represents a single preimage and a single postimage.

Since "diff -c" is to compare N parents with a single merge result and filter out any paths whose result match one (or more) of the parent(s), its output has to be able to represent N preimages and 1 postimage. For this reason, a callback function that inspects a diff_filepair that results from this new infrastructure can and is expected to view the preimage side (i.e. pair->one) as an array of diff_filespec. Each element in the array, except for the last one, is marked with "has_more_entries" bit, so that the same callback function can be used for 2-way diffs and combined diffs.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 combine-diff.c |   69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 diffcore.h     |    2 +-
 2 files changed, 70 insertions(+), 1 deletions(-)
diff --git a/combine-diff.c b/combine-diff.c
index 655fa89..de88186 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -970,6 +970,72 @@ void show_combined_diff(struct combine_diff_path *p,
 		show_patch_diff(p, num_parent, dense, rev);
 }
 
+static void free_combined_pair(struct diff_filepair *pair)
+{
+	free(pair->two);
+	free(pair);
+}
+
+/*
+ * A combine_diff_path expresses N parents on the LHS against 1 merge
+ * result. Synthesize a diff_filepair that has N entries on the "one"
+ * side and 1 entry on the "two" side.
+ *
+ * In the future, we might want to add more data to combine_diff_path
+ * so that we can fill fields we are ignoring (most notably, size) here,
+ * but currently nobody uses it, so this should suffice for now.
+ */
+static struct diff_filepair *combined_pair(struct combine_diff_path *p,
+					   int num_parent)
+{
+	int i;
+	struct diff_filepair *pair;
+	struct diff_filespec *pool;
+
+	pair = xmalloc(sizeof(*pair));
+	pool = xcalloc(num_parent + 1, sizeof(struct diff_filespec));
+	pair->one = pool + 1;
+	pair->two = pool;
+
+	for (i = 0; i < num_parent; i++) {
+		pair->one[i].path = p->path;
+		pair->one[i].mode = p->parent[i].mode;
+		hashcpy(pair->one[i].sha1, p->parent[i].sha1);
+		pair->one[i].sha1_valid = !is_null_sha1(p->parent[i].sha1);
+		pair->one[i].has_more_entries = 1;
+	}
+	pair->one[num_parent - 1].has_more_entries = 0;
+
+	pair->two->path = p->path;
+	pair->two->mode = p->mode;
+	hashcpy(pair->two->sha1, p->sha1);
+	pair->two->sha1_valid = !is_null_sha1(p->sha1);
+	return pair;
+}
+
+static void handle_combined_callback(struct diff_options *opt,
+				     struct combine_diff_path *paths,
+				     int num_parent,
+				     int num_paths)
+{
+	struct combine_diff_path *p;
+	struct diff_queue_struct q;
+	int i;
+
+	q.queue = xcalloc(num_paths, sizeof(struct diff_filepair *));
+	q.alloc = num_paths;
+	q.nr = num_paths;
+	for (i = 0, p = paths; p; p = p->next) {
+		if (!p->len)
+			continue;
+		q.queue[i++] = combined_pair(p, num_parent);
+	}
+	opt->format_callback(&q, opt, opt->format_callback_data);
+	for (i = 0; i < num_paths; i++)
+		free_combined_pair(q.queue[i]);
+	free(q.queue);
+}
+
 void diff_tree_combined(const unsigned char *sha1,
 			const unsigned char parent[][20],
 			int num_parent,
@@ -1029,6 +1095,9 @@ void diff_tree_combined(const unsigned char *sha1,
 		else if (opt->output_format &
 			 (DIFF_FORMAT_NUMSTAT|DIFF_FORMAT_DIFFSTAT))
 			needsep = 1;
+		else if (opt->output_format & DIFF_FORMAT_CALLBACK)
+			handle_combined_callback(opt, paths, num_parent, num_paths);
+
 		if (opt->output_format & DIFF_FORMAT_PATCH) {
 			if (needsep)
 				putchar(opt->line_termination);
diff --git a/diffcore.h b/diffcore.h
index b8f1fde..8f32b82 100644
--- a/diffcore.h
+++ b/diffcore.h
@@ -45,7 +45,7 @@ struct diff_filespec {
 	unsigned dirty_submodule : 2;  /* For submodules: its work tree is dirty */
 #define DIRTY_SUBMODULE_UNTRACKED 1
 #define DIRTY_SUBMODULE_MODIFIED  2
-
+	unsigned has_more_entries : 1; /* only appear in combined diff */
 	struct userdiff_driver *driver;
 	/* data should be considered "binary"; -1 means "don't know yet" */
 	int is_binary;
-- 
1.7.6.557.gcee42

 
Previous: Junio C HamanoNext: Junio C Hamano
Message 4 of 20 in “push: submodule support”
  1. 0/2 push: submodule supportFredrik Gustafsson, Aug 19, 2011
  2. 1/2 push: Don't push a repository with unpushed submodulesFredrik Gustafsson, Aug 19, 2011
  3. Junio C HamanoAug 19, 2011
  4. Junio C HamanoAug 20, 2011
  5. Junio C HamanoAug 21, 2011
  6. Heiko VoigtAug 22, 2011
  7. Junio C HamanoAug 22, 2011
  8. Heiko VoigtAug 23, 2011
  9. revision-walking: allow iterating revisions multiple timesHeiko Voigt, Aug 24, 2011
  10. Junio C HamanoAug 24, 2011
  11. 2/2 demonstrate format-callback used in combined diffJunio C Hamano, Aug 20, 2011
  12. Fredrik GustafssonAug 21, 2011
  13. 2/2 push: teach --recurse-submodules the on-demand optionFredrik Gustafsson, Aug 19, 2011
  14. Junio C HamanoSep 2, 2011
  15. Junio C HamanoOct 17, 2011
  16. Jens LehmannOct 18, 2011
  17. Phil HordDec 12, 2011
  18. Jens LehmannDec 12, 2011
  19. Phil HordDec 12, 2011
  20. Jens LehmannDec 13, 2011

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.