Commit Diff


commit - f4d0e3fbae5165979285f3c67e9cdfceea1c7ad5
commit + 7aadece8bf43513dfa752120ab1255f7125b03ed
blob - 515477b2d9c25ebe5208ca3566e02cd34c00219d
blob + fa3eec221ff24961d74441b2e25a3a6186877ecd
--- lib/object_create.c
+++ lib/object_create.c
@@ -202,7 +202,7 @@ done:
 }
 
 static const struct got_error *
-te_mode2str(char *buf, size_t len, mode_t te_mode)
+te_mode2str(char *buf, size_t len, struct got_tree_entry *te)
 {
 	int ret;
 	mode_t mode;
@@ -210,13 +210,15 @@ te_mode2str(char *buf, size_t len, mode_t te_mode)
 	/*
 	 * Some Git implementations are picky about modes seen in tree entries.
 	 * For best compatibility we normalize the file/directory mode here.
-	 * Note that we do not support committing symlinks or submodules.
+	 * Note that we do not support committing symlinks.
 	 */
-	if (S_ISREG(te_mode)) {
+	if (S_ISREG(te->mode)) {
 		mode = GOT_DEFAULT_FILE_MODE;
-		if (te_mode & (S_IXUSR | S_IXGRP | S_IXOTH))
+		if (te->mode & (S_IXUSR | S_IXGRP | S_IXOTH))
 			mode |= S_IXUSR | S_IXGRP | S_IXOTH;
-	} else if (S_ISDIR(te_mode))
+	} else if (got_object_tree_entry_is_submodule(te))
+		mode = S_IFDIR | S_IFLNK;
+	else if (S_ISDIR(te->mode))
 		mode = S_IFDIR; /* Git leaves all the other bits unset. */
 	else
 		return got_error(GOT_ERR_BAD_FILETYPE);
@@ -281,7 +283,7 @@ got_object_tree_create(struct got_object_id **id,
 
 	for (i = 0; i < nentries; i++) {
 		te = sorted_entries[i];
-		err = te_mode2str(modebuf, sizeof(modebuf), te->mode);
+		err = te_mode2str(modebuf, sizeof(modebuf), te);
 		if (err)
 			goto done;
 		len += strlen(modebuf) + strlen(te->name) + 1 +
@@ -309,7 +311,7 @@ got_object_tree_create(struct got_object_id **id,
 
 	for (i = 0; i < nentries; i++) {
 		te = sorted_entries[i];
-		err = te_mode2str(modebuf, sizeof(modebuf), te->mode);
+		err = te_mode2str(modebuf, sizeof(modebuf), te);
 		if (err)
 			goto done;
 		len = strlen(modebuf);
blob - 3c8e833ec7ad8718957fd61f1be12dd5eceabd1f
blob + edfc2bb907f0c8a73be7bc0f249ea53a0df61732
--- regress/cmdline/commit.sh
+++ regress/cmdline/commit.sh
@@ -873,28 +873,31 @@ function test_commit_with_unrelated_submodule {
 	got checkout $testroot/repo $testroot/wt > /dev/null
 	ret="$?"
 	if [ "$ret" != "0" ]; then
+		echo "checkout failed unexpectedly" >&2
 		test_done "$testroot" "$ret"
 		return 1
 	fi
 
 	echo "modified alpha" > $testroot/wt/alpha
 
-	# Currently fails with "bad file type" error
-	(cd $testroot/wt && got commit -m 'modify alpha' \
-		> $testroot/stdout 2> $testroot/stderr)
+	echo "" > $testroot/stdout.expected
+
+	cd $testroot/wt && got commit -m 'modify alpha' > $testroot/stdout
 	ret="$?"
-	if [ "$ret" == "0" ]; then
-		echo "commit succeeded unexpectedly" >&2
-		test_done "$testroot" "1"
+	if [ "$ret" != "0" ]; then
+		echo "commit failed unexpectedly" >&2
+		test_done "$testroot" "$ret"
 		return 1
 	fi
-	echo "got: bad file type" > $testroot/stderr.expected
 
-	cmp -s $testroot/stderr.expected $testroot/stderr
+	local head_rev=`git_show_head $testroot/repo`
+	echo "M  alpha" > $testroot/stdout.expected
+	echo "Created commit $head_rev" >> $testroot/stdout.expected
+
+	cmp -s $testroot/stdout.expected $testroot/stdout
 	ret="$?"
 	if [ "$ret" != "0" ]; then
-		diff -u $testroot/stderr.expected $testroot/stderr
-		return 1
+		diff -u $testroot/stdout.expected $testroot/stdout
 	fi
 	test_done "$testroot" "$ret"
 }