All of lore.kernel.org
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: Clemens Buchacher <drizzd@aon.at>
Cc: Finn Arne Gangstad <finnag@pvv.org>,
	Tim Olsen <tim@brooklynpenguin.com>,
	git@vger.kernel.org
Subject: [PATCH v2] diff -c -p: do not die on submodules
Date: Wed, 29 Apr 2009 13:26:52 -0700	[thread overview]
Message-ID: <7vy6tj8aur.fsf_-_@gitster.siamese.dyndns.org> (raw)
In-Reply-To: <7v8wljcmvk.fsf_-_@gitster.siamese.dyndns.org> (Junio C. Hamano's message of "Wed, 29 Apr 2009 11:53:35 -0700")

The combine diff logic knew only about blobs (and their checked-out form
in the work tree, either regular files or symlinks), and barfed when fed
submodules.  This "externalizes" gitlinks in the same way as the normal
patch generation codepath does (i.e. "Subproject commit Xxx\n") to fix the
issue.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---

 This is a re-roll of the earlier "[PATCH] Teach gitlinks to combine-diff",
 meant to apply to maint-1.6.0 and later.

 combine-diff.c            |   38 ++++++++++++++++++++++++++------------
 t/t4027-diff-submodule.sh |   39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+), 12 deletions(-)

diff --git a/combine-diff.c b/combine-diff.c
index aa9d79e..f617e9d 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -6,6 +6,7 @@
 #include "quote.h"
 #include "xdiff-interface.h"
 #include "log-tree.h"
+#include "refs.h"
 
 static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr, int n, int num_parent)
 {
@@ -90,18 +91,24 @@ struct sline {
 	unsigned long *p_lno;
 };
 
-static char *grab_blob(const unsigned char *sha1, unsigned long *size)
+static char *grab_blob(const unsigned char *sha1, unsigned int mode, unsigned long *size)
 {
 	char *blob;
 	enum object_type type;
-	if (is_null_sha1(sha1)) {
+
+	if (S_ISGITLINK(mode)) {
+		blob = xmalloc(100);
+		*size = snprintf(blob, 100,
+				 "Subproject commit %s\n", sha1_to_hex(sha1));
+	} else if (is_null_sha1(sha1)) {
 		/* deleted blob */
 		*size = 0;
 		return xcalloc(1, 1);
+	} else {
+		blob = read_sha1_file(sha1, &type, size);
+		if (type != OBJ_BLOB)
+			die("object '%s' is not a blob!", sha1_to_hex(sha1));
 	}
-	blob = read_sha1_file(sha1, &type, size);
-	if (type != OBJ_BLOB)
-		die("object '%s' is not a blob!", sha1_to_hex(sha1));
 	return blob;
 }
 
@@ -197,7 +204,8 @@ static void consume_line(void *state_, char *line, unsigned long len)
 	}
 }
 
-static void combine_diff(const unsigned char *parent, mmfile_t *result_file,
+static void combine_diff(const unsigned char *parent, unsigned int mode,
+			 mmfile_t *result_file,
 			 struct sline *sline, unsigned int cnt, int n,
 			 int num_parent)
 {
@@ -213,7 +221,7 @@ static void combine_diff(const unsigned char *parent, mmfile_t *result_file,
 	if (!cnt)
 		return; /* result deleted */
 
-	parent_file.ptr = grab_blob(parent, &sz);
+	parent_file.ptr = grab_blob(parent, mode, &sz);
 	parent_file.size = sz;
 	xpp.flags = XDF_NEED_MINIMAL;
 	memset(&xecfg, 0, sizeof(xecfg));
@@ -692,7 +700,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
 	context = opt->context;
 	/* Read the result of merge first */
 	if (!working_tree_file)
-		result = grab_blob(elem->sha1, &result_size);
+		result = grab_blob(elem->sha1, elem->mode, &result_size);
 	else {
 		/* Used by diff-tree to read from the working tree */
 		struct stat st;
@@ -712,9 +720,13 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
 			}
 			result[len] = 0;
 			elem->mode = canon_mode(st.st_mode);
-		}
-		else if (0 <= (fd = open(elem->path, O_RDONLY)) &&
-			 !fstat(fd, &st)) {
+		} else if (S_ISDIR(st.st_mode)) {
+			unsigned char sha1[20];
+			if (resolve_gitlink_ref(elem->path, "HEAD", sha1) < 0)
+				result = grab_blob(elem->sha1, elem->mode, &result_size);
+			else
+				result = grab_blob(sha1, elem->mode, &result_size);
+		} else if (0 <= (fd = open(elem->path, O_RDONLY))) {
 			size_t len = xsize_t(st.st_size);
 			ssize_t done;
 			int is_file, i;
@@ -807,7 +819,9 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
 			}
 		}
 		if (i <= j)
-			combine_diff(elem->parent[i].sha1, &result_file, sline,
+			combine_diff(elem->parent[i].sha1,
+				     elem->parent[i].mode,
+				     &result_file, sline,
 				     cnt, i, num_parent);
 		if (elem->parent[i].mode != elem->mode)
 			mode_differs = 1;
diff --git a/t/t4027-diff-submodule.sh b/t/t4027-diff-submodule.sh
index ba6679c..718efe8 100755
--- a/t/t4027-diff-submodule.sh
+++ b/t/t4027-diff-submodule.sh
@@ -57,4 +57,43 @@ test_expect_success 'git diff (empty submodule dir)' '
 	test_cmp empty actual.empty
 '
 
+test_expect_success 'conflicted submodule setup' '
+
+	# 39 efs
+	c=fffffffffffffffffffffffffffffffffffffff
+	(
+		echo "000000 $_z40 0	sub"
+		echo "160000 1$c 1	sub"
+		echo "160000 2$c 2	sub"
+		echo "160000 3$c 3	sub"
+	) | git update-index --index-info &&
+	echo >expect.nosub '\''diff --cc sub
+index 2ffffff,3ffffff..0000000
+--- a/sub
++++ b/sub
+@@@ -1,1 -1,1 +1,1 @@@
+- Subproject commit 2fffffffffffffffffffffffffffffffffffffff
+ -Subproject commit 3fffffffffffffffffffffffffffffffffffffff
+++Subproject commit 0000000000000000000000000000000000000000'\'' &&
+
+	hh=$(git rev-parse HEAD) &&
+	sed -e "s/$_z40/$hh/" expect.nosub >expect.withsub
+
+'
+
+test_expect_success 'combined (empty submodule)' '
+	rm -fr sub && mkdir sub &&
+	git diff >actual &&
+	test_cmp expect.nosub actual
+'
+
+test_expect_success 'combined (with submodule)' '
+	rm -fr sub &&
+	git clone --no-checkout . sub &&
+	git diff >actual &&
+	test_cmp expect.withsub actual
+'
+
+
+
 test_done
-- 
1.6.3.rc3.16.gb37759

  reply	other threads:[~2009-04-29 20:27 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-04-28 17:36 different git-merge behavior with regard to submodules in 1.6.2.4 vs. 1.6.2.1 Tim Olsen
2009-04-28 18:29 ` Junio C Hamano
2009-04-28 21:12   ` Finn Arne Gangstad
2009-04-29  8:42     ` Clemens Buchacher
2009-04-29 12:15       ` Finn Arne Gangstad
2009-04-29 18:53       ` [PATCH] Teach gitlinks to combine-diff Junio C Hamano
2009-04-29 20:26         ` Junio C Hamano [this message]
2009-04-29 21:50           ` [PATCH v2] diff -c -p: do not die on submodules Alex Riesen
2009-04-29 22:13             ` Johannes Schindelin
2009-04-29 22:19               ` Alex Riesen
2009-04-29 22:39                 ` Johannes Schindelin
2009-04-30  5:47                   ` Alex Riesen
2009-04-30  6:07                     ` Finn Arne Gangstad
2009-04-29 23:09             ` Junio C Hamano
2009-04-29 18:54       ` different git-merge behavior with regard to submodules in 1.6.2.4 vs. 1.6.2.1 Junio C Hamano

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=7vy6tj8aur.fsf_-_@gitster.siamese.dyndns.org \
    --to=gitster@pobox.com \
    --cc=drizzd@aon.at \
    --cc=finnag@pvv.org \
    --cc=git@vger.kernel.org \
    --cc=tim@brooklynpenguin.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.