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

[PATCH 2/2] Teach "git-read-tree -u" to check out submodules as a directory

From
Linus Torvalds <torvalds@linux-foundation.org>
Date
Apr 13, 2007, 04:08 UTC
Message-ID
<Pine.LNX.4.64.0704122104030.4061@woody.linux-foundation.org>
In-Reply-To
<Pine.LNX.4.64.0704122102320.4061@woody.linux-foundation.org>

This actually allows us to check out a supermodule after cloning, although the submodules will obviously not be checked out, and will just be an empty subdirectory.

[ Side note: this also shows that we currently don't correctly handle
  such subprojects that aren't checked out correctly yet.  They should
  always show up as not being modified, but failing to resolve the
  gitlink HEAD does not properly trigger the "not modified" logic in all 
  places it needs to..
  So more work to be done, but that's a separate issue, unrelated to
  the action of checking out the superproject. ]

The bulk of this patch is simply because we need to check the type of the index entry *before* we try to read the object it points to, and that meant that the code needed some re-organization. So I moved some of the code in common to both symlinks and files to be a trivial helper function.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
 entry.c |   42 +++++++++++++++++++++++++++++-------------
 1 files changed, 29 insertions(+), 13 deletions(-)
diff --git a/entry.c b/entry.c
index d72f811..9545e89 100644
--- a/entry.c
+++ b/entry.c
@@ -62,26 +62,33 @@ static int create_file(const char *path, unsigned int mode)
 	return open(path, O_WRONLY | O_CREAT | O_EXCL, mode);
 }
 
+static void *read_blob_entry(struct cache_entry *ce, const char *path, unsigned long *size)
+{
+	enum object_type type;
+	void *new = read_sha1_file(ce->sha1, &type, size);
+
+	if (new) {
+		if (type == OBJ_BLOB)
+			return new;
+		free(new);
+	}
+	return NULL;
+}
+
 static int write_entry(struct cache_entry *ce, char *path, struct checkout *state, int to_tempfile)
 {
 	int fd;
-	void *new;
-	unsigned long size;
 	long wrote;
-	enum object_type type;
 
-	new = read_sha1_file(ce->sha1, &type, &size);
-	if (!new || type != OBJ_BLOB) {
-		if (new)
-			free(new);
-		return error("git-checkout-index: unable to read sha1 file of %s (%s)",
-			path, sha1_to_hex(ce->sha1));
-	}
 	switch (ntohl(ce->ce_mode) & S_IFMT) {
-		char *buf;
-		unsigned long nsize;
+		char *buf, *new;
+		unsigned long size, nsize;
 
 	case S_IFREG:
+		new = read_blob_entry(ce, path, &size);
+		if (!new)
+			return error("git-checkout-index: unable to read sha1 file of %s (%s)",
+				path, sha1_to_hex(ce->sha1));
 		if (to_tempfile) {
 			strcpy(path, ".merge_file_XXXXXX");
 			fd = mkstemp(path);
@@ -111,6 +118,10 @@ static int write_entry(struct cache_entry *ce, char *path, struct checkout *stat
 			return error("git-checkout-index: unable to write file %s", path);
 		break;
 	case S_IFLNK:
+		new = read_blob_entry(ce, path, &size);
+		if (!new)
+			return error("git-checkout-index: unable to read sha1 file of %s (%s)",
+				path, sha1_to_hex(ce->sha1));
 		if (to_tempfile || !has_symlinks) {
 			if (to_tempfile) {
 				strcpy(path, ".merge_link_XXXXXX");
@@ -136,8 +147,13 @@ static int write_entry(struct cache_entry *ce, char *path, struct checkout *stat
 						 "symlink %s (%s)", path, strerror(errno));
 		}
 		break;
+	case S_IFDIRLNK:
+		if (to_tempfile)
+			return error("git-checkout-index: cannot create temporary subproject %s", path);
+		if (mkdir(path, 0777) < 0)
+			return error("git-checkout-index: cannot create subproject directory %s", path);
+		break;
 	default:
-		free(new);
 		return error("git-checkout-index: unknown file mode for %s", path);
 	}
 
Previous: Linus TorvaldsNext: Linus Torvalds
Message 2 of 5 in “Teach git list-objects logic not to follow gitlinks”
  1. 1/2 Teach git list-objects logic not to follow gitlinksLinus Torvalds, Apr 13, 2007
  2. 2/2 Teach "git-read-tree -u" to check out submodules as a directoryLinus Torvalds, Apr 13, 2007
  3. Linus TorvaldsApr 13, 2007
  4. Junio C HamanoApr 13, 2007
  5. Linus TorvaldsApr 13, 2007

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.