Commit 0d1b094b07d836a657ad9e458e04490d1e72d365

Russell Belfer 2013-02-26T13:15:06

Fix portability issues on Windows The new tests were not taking core.filemode into account when testing file modes after repo initialization. Fixed that and some other Windows warnings that have crept in.

diff --git a/src/refs.c b/src/refs.c
index cca3f3e..113cada 100644
--- a/src/refs.c
+++ b/src/refs.c
@@ -1599,7 +1599,8 @@ static int ensure_segment_validity(const char *name)
 {
 	const char *current = name;
 	char prev = '\0';
-	int lock_len = strlen(GIT_FILELOCK_EXTENSION);
+	const int lock_len = (int)strlen(GIT_FILELOCK_EXTENSION);
+	int segment_len;
 
 	if (*current == '.')
 		return -1; /* Refname starts with "." */
@@ -1620,12 +1621,14 @@ static int ensure_segment_validity(const char *name)
 		prev = *current;
 	}
 
+	segment_len = (int)(current - name);
+
 	/* A refname component can not end with ".lock" */
-	if (current - name >= lock_len &&
+	if (segment_len >= lock_len &&
 		!memcmp(current - lock_len, GIT_FILELOCK_EXTENSION, lock_len))
 			return -1;
 
-	return (int)(current - name);
+	return segment_len;
 }
 
 static bool is_all_caps_and_underscore(const char *name, size_t len)
@@ -1700,7 +1703,7 @@ int git_reference__normalize_name(
 		/* No empty segment is allowed when not normalizing */
 		if (segment_len == 0 && !normalize)
 			goto cleanup;
-		
+
 		if (current[segment_len] == '\0')
 			break;
 
diff --git a/src/repository.c b/src/repository.c
index 5279d8f..e120c58 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -1043,8 +1043,11 @@ static int repo_init_structure(
 
 static int mkdir_parent(git_buf *buf, uint32_t mode, bool skip2)
 {
+	/* When making parent directories during repository initialization
+	 * don't try to set gid or grant world write access
+	 */
 	return git_futils_mkdir(
-		buf->ptr, NULL, mode & ~(S_ISGID | S_IWOTH),
+		buf->ptr, NULL, mode & ~(S_ISGID | 0002),
 		GIT_MKDIR_PATH | GIT_MKDIR_VERIFY_DIR |
 		(skip2 ? GIT_MKDIR_SKIP_LAST2 : GIT_MKDIR_SKIP_LAST));
 }
diff --git a/tests-clar/refs/branches/remote.c b/tests-clar/refs/branches/remote.c
index 145c318..5272d12 100644
--- a/tests-clar/refs/branches/remote.c
+++ b/tests-clar/refs/branches/remote.c
@@ -11,7 +11,7 @@ void test_refs_branches_remote__initialize(void)
 {
 	g_repo = cl_git_sandbox_init("testrepo");
 
-	expected_remote_name_length = strlen(expected_remote_name) + 1;
+	expected_remote_name_length = (int)strlen(expected_remote_name) + 1;
 }
 
 void test_refs_branches_remote__cleanup(void)
diff --git a/tests-clar/repo/init.c b/tests-clar/repo/init.c
index c69ea76..085d65f 100644
--- a/tests-clar/repo/init.c
+++ b/tests-clar/repo/init.c
@@ -363,10 +363,23 @@ void test_repo_init__extended_1(void)
 	cl_fixture_cleanup("root");
 }
 
+static uint32_t normalize_filemode(uint32_t mode, bool core_filemode)
+{
+	/* if no filemode support, strip SETGID, exec, and low-order bits */
+
+	/* cannot use constants because on platform without SETGID, that
+	 * will have been defined to zero - must use hardcoded value to
+	 * clear it effectively from the expected value
+	 */
+
+	return core_filemode ? mode : (mode & ~02177);
+}
+
 static void assert_hooks_match(
 	const char *template_dir,
 	const char *repo_dir,
 	const char *hook_path,
+	bool core_filemode,
 	uint32_t expected_mode)
 {
 	git_buf expected = GIT_BUF_INIT;
@@ -384,6 +397,8 @@ static void assert_hooks_match(
 	if (!expected_mode)
 		expected_mode = (uint32_t)expected_st.st_mode;
 
+	expected_mode = normalize_filemode(expected_mode, core_filemode);
+
 	cl_assert_equal_i((int)expected_mode, (int)st.st_mode);
 
 	git_buf_free(&expected);
@@ -391,7 +406,7 @@ static void assert_hooks_match(
 }
 
 static void assert_has_mode(
-	const char *base, const char *path, uint32_t expected)
+	const char *base, const char *path, bool core_filemode, uint32_t expected)
 {
 	git_buf full = GIT_BUF_INIT;
 	struct stat st;
@@ -400,6 +415,8 @@ static void assert_has_mode(
 	cl_git_pass(git_path_lstat(full.ptr, &st));
 	git_buf_free(&full);
 
+	expected = normalize_filemode(expected, core_filemode);
+
 	cl_assert_equal_i((int)expected, (int)st.st_mode);
 }
 
@@ -433,11 +450,11 @@ void test_repo_init__extended_with_template(void)
 
 	assert_hooks_match(
 		cl_fixture("template"), git_repository_path(_repo),
-		"hooks/update.sample", 0);
+		"hooks/update.sample", true, 0);
 
 	assert_hooks_match(
 		cl_fixture("template"), git_repository_path(_repo),
-		"hooks/link.sample", 0);
+		"hooks/link.sample", true, 0);
 }
 
 void test_repo_init__extended_with_template_and_shared_mode(void)
@@ -445,6 +462,8 @@ void test_repo_init__extended_with_template_and_shared_mode(void)
 	git_buf expected = GIT_BUF_INIT;
 	git_buf actual = GIT_BUF_INIT;
 	git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
+	git_config *config;
+	int filemode = true;
 
 	cl_set_cleanup(&cleanup_repository, "init_shared_from_tpl");
 
@@ -458,6 +477,10 @@ void test_repo_init__extended_with_template_and_shared_mode(void)
 	cl_assert(!git_repository_is_bare(_repo));
 	cl_assert(!git__suffixcmp(git_repository_path(_repo), "/init_shared_from_tpl/.git/"));
 
+	cl_git_pass(git_repository_config(&config, _repo));
+	cl_git_pass(git_config_get_bool(&filemode, config, "core.filemode"));
+	git_config_free(config);
+
 	cl_git_pass(git_futils_readbuffer(
 		&expected, cl_fixture("template/description")));
 	cl_git_pass(git_futils_readbuffer(
@@ -468,17 +491,17 @@ void test_repo_init__extended_with_template_and_shared_mode(void)
 	git_buf_free(&expected);
 	git_buf_free(&actual);
 
-	assert_has_mode(git_repository_path(_repo), "hooks",
+	assert_has_mode(git_repository_path(_repo), "hooks", filemode,
 		GIT_REPOSITORY_INIT_SHARED_GROUP | S_IFDIR);
-	assert_has_mode(git_repository_path(_repo), "info",
+	assert_has_mode(git_repository_path(_repo), "info", filemode,
 		GIT_REPOSITORY_INIT_SHARED_GROUP | S_IFDIR);
-	assert_has_mode(git_repository_path(_repo), "description",
+	assert_has_mode(git_repository_path(_repo), "description", filemode,
 		(GIT_REPOSITORY_INIT_SHARED_GROUP | S_IFREG) & ~(S_ISGID | 0111));
 
 	/* for a non-symlinked hook, it should have shared permissions now */
 	assert_hooks_match(
 		cl_fixture("template"), git_repository_path(_repo),
-		"hooks/update.sample",
+		"hooks/update.sample", filemode,
 		(GIT_REPOSITORY_INIT_SHARED_GROUP | S_IFREG) & ~S_ISGID);
 
 	/* for a symlinked hook, the permissions still should match the
@@ -486,7 +509,7 @@ void test_repo_init__extended_with_template_and_shared_mode(void)
 	 */
 	assert_hooks_match(
 		cl_fixture("template"), git_repository_path(_repo),
-		"hooks/link.sample", 0);
+		"hooks/link.sample", filemode, 0);
 }
 
 void test_repo_init__can_reinit_an_initialized_repository(void)