Commit 64bbd47a32e6aaed539bafd109eef624f24fbae7

Carlos Martín Nieto 2015-05-04T17:09:21

submodule: don't let status change an existing instance As submodules are becomes more like values, we should not let a status check to update its properties. Instead of taking a submodule, have status take a repo and submodule name.

diff --git a/include/git2/submodule.h b/include/git2/submodule.h
index e41dc49..7375708 100644
--- a/include/git2/submodule.h
+++ b/include/git2/submodule.h
@@ -626,16 +626,17 @@ GIT_EXTERN(int) git_submodule_reload_all(git_repository *repo, int force);
  * This looks at a submodule and tries to determine the status.  It
  * will return a combination of the `GIT_SUBMODULE_STATUS` values above.
  * How deeply it examines the working directory to do this will depend
- * on the `git_submodule_ignore_t` value for the submodule - which can be
- * set either temporarily or permanently with `git_submodule_set_ignore()`.
+ * on the `git_submodule_ignore_t` value for the submodule.
  *
  * @param status Combination of `GIT_SUBMODULE_STATUS` flags
- * @param submodule Submodule for which to get status
+ * @param repo the repository in which to look
+ * @param name name of the submodule
  * @return 0 on success, <0 on error
  */
 GIT_EXTERN(int) git_submodule_status(
 	unsigned int *status,
-	git_submodule *submodule);
+	git_repository *repo,
+	const char *name);
 
 /**
  * Get the locations of submodule information.
diff --git a/src/checkout.c b/src/checkout.c
index dab83c6..d95244a 100644
--- a/src/checkout.c
+++ b/src/checkout.c
@@ -180,7 +180,7 @@ static bool checkout_is_workdir_modified(
 			return true;
 		}
 
-		if (git_submodule_status(&sm_status, sm) < 0 ||
+		if (git_submodule_status(&sm_status, data->repo, wditem->path) < 0 ||
 			GIT_SUBMODULE_STATUS_IS_WD_DIRTY(sm_status))
 			rval = true;
 		else if ((sm_oid = git_submodule_wd_id(sm)) == NULL)
diff --git a/src/diff_file.c b/src/diff_file.c
index cef4bc1..4d9ecc8 100644
--- a/src/diff_file.c
+++ b/src/diff_file.c
@@ -186,7 +186,7 @@ static int diff_file_content_commit_to_str(
 			return error;
 		}
 
-		if ((error = git_submodule_status(&sm_status, sm)) < 0) {
+		if ((error = git_submodule_status(&sm_status, fc->repo, fc->file->path)) < 0) {
 			git_submodule_free(sm);
 			return error;
 		}
diff --git a/src/submodule.c b/src/submodule.c
index 78bf519..2faaa73 100644
--- a/src/submodule.c
+++ b/src/submodule.c
@@ -1067,7 +1067,7 @@ int git_submodule_update(git_submodule *sm, int init, git_submodule_update_optio
 	memcpy(&clone_options.fetch_opts, &update_options.fetch_opts, sizeof(git_fetch_options));
 
 	/* Get the status of the submodule to determine if it is already initialized  */
-	if ((error = git_submodule_status(&submodule_status, sm)) < 0)
+	if ((error = git_submodule_status(&submodule_status, sm->repo, sm->name)) < 0)
 		goto done;
 
 	/*
@@ -1511,11 +1511,20 @@ int git_submodule__status(
 	return 0;
 }
 
-int git_submodule_status(unsigned int *status, git_submodule *sm)
+int git_submodule_status(unsigned int *status, git_repository *repo, const char *name)
 {
-	assert(status && sm);
+	git_submodule *sm;
+	int error;
+
+	assert(status && repo && name);
+
+	if ((error = git_submodule_lookup(&sm, repo, name)) < 0)
+		return error;
+
+	error = git_submodule__status(status, NULL, NULL, NULL, sm, 0);
+	git_submodule_free(sm);
 
-	return git_submodule__status(status, NULL, NULL, NULL, sm, 0);
+	return error;
 }
 
 int git_submodule_location(unsigned int *location, git_submodule *sm)
diff --git a/tests/submodule/submodule_helpers.c b/tests/submodule/submodule_helpers.c
index 19bb04f..3683822 100644
--- a/tests/submodule/submodule_helpers.c
+++ b/tests/submodule/submodule_helpers.c
@@ -164,13 +164,11 @@ void refute__submodule_exists(
 
 unsigned int get_submodule_status(git_repository *repo, const char *name)
 {
-	git_submodule *sm = NULL;
 	unsigned int status = 0;
 
-	cl_git_pass(git_submodule_lookup(&sm, repo, name));
-	cl_assert(sm);
-	cl_git_pass(git_submodule_status(&status, sm));
-	git_submodule_free(sm);
+	assert(repo && name);
+
+	cl_git_pass(git_submodule_status(&status, repo, name));
 
 	return status;
 }
diff --git a/tests/submodule/update.c b/tests/submodule/update.c
index e7f1b76..8587043 100644
--- a/tests/submodule/update.c
+++ b/tests/submodule/update.c
@@ -103,7 +103,7 @@ void test_submodule_update__update_submodule(void)
 	cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
 
 	/* verify the initial state of the submodule */
-	cl_git_pass(git_submodule_status(&submodule_status, sm));
+	cl_git_pass(git_submodule_status(&submodule_status, g_repo, "testrepo"));
 	cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD |
 		GIT_SUBMODULE_STATUS_IN_INDEX |
 		GIT_SUBMODULE_STATUS_IN_CONFIG |
@@ -114,7 +114,7 @@ void test_submodule_update__update_submodule(void)
 	cl_git_pass(git_submodule_update(sm, 0, &update_options));
 
 	/* verify state */
-	cl_git_pass(git_submodule_status(&submodule_status, sm));
+	cl_git_pass(git_submodule_status(&submodule_status, g_repo, "testrepo"));
 	cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD |
 		GIT_SUBMODULE_STATUS_IN_INDEX |
 		GIT_SUBMODULE_STATUS_IN_CONFIG |
@@ -142,7 +142,7 @@ void test_submodule_update__update_and_init_submodule(void)
 	/* get the submodule */
 	cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
 
-	cl_git_pass(git_submodule_status(&submodule_status, sm));
+	cl_git_pass(git_submodule_status(&submodule_status, g_repo, "testrepo"));
 	cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD |
 		GIT_SUBMODULE_STATUS_IN_INDEX |
 		GIT_SUBMODULE_STATUS_IN_CONFIG |
@@ -177,7 +177,7 @@ void test_submodule_update__update_already_checked_out_submodule(void)
 	/* Initialize and update the sub repository */
 	cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
 
-	cl_git_pass(git_submodule_status(&submodule_status, sm));
+	cl_git_pass(git_submodule_status(&submodule_status, g_repo, "testrepo"));
 	cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD |
 		GIT_SUBMODULE_STATUS_IN_INDEX |
 		GIT_SUBMODULE_STATUS_IN_CONFIG |
@@ -203,7 +203,11 @@ void test_submodule_update__update_already_checked_out_submodule(void)
 	 * HEAD commit and index should be updated, but not the workdir.
 	 */
 
-	cl_git_pass(git_submodule_status(&submodule_status, sm));
+	cl_git_pass(git_submodule_status(&submodule_status, g_repo, "testrepo"));
+
+	git_submodule_free(sm);
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
+
 	cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD |
 		GIT_SUBMODULE_STATUS_IN_INDEX |
 		GIT_SUBMODULE_STATUS_IN_CONFIG |
@@ -251,7 +255,7 @@ void test_submodule_update__update_blocks_on_dirty_wd(void)
 	/* Initialize and update the sub repository */
 	cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
 
-	cl_git_pass(git_submodule_status(&submodule_status, sm));
+	cl_git_pass(git_submodule_status(&submodule_status, g_repo, "testrepo"));
 	cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD |
 		GIT_SUBMODULE_STATUS_IN_INDEX |
 		GIT_SUBMODULE_STATUS_IN_CONFIG |
@@ -277,7 +281,11 @@ void test_submodule_update__update_blocks_on_dirty_wd(void)
 	 * HEAD commit and index should be updated, but not the workdir.
 	 */
 
-	cl_git_pass(git_submodule_status(&submodule_status, sm));
+	cl_git_pass(git_submodule_status(&submodule_status, g_repo, "testrepo"));
+
+	git_submodule_free(sm);
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
+
 	cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD |
 		GIT_SUBMODULE_STATUS_IN_INDEX |
 		GIT_SUBMODULE_STATUS_IN_CONFIG |
@@ -324,7 +332,7 @@ void test_submodule_update__can_force_update(void)
 	/* Initialize and update the sub repository */
 	cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
 
-	cl_git_pass(git_submodule_status(&submodule_status, sm));
+	cl_git_pass(git_submodule_status(&submodule_status, g_repo, "testrepo"));
 	cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD |
 		GIT_SUBMODULE_STATUS_IN_INDEX |
 		GIT_SUBMODULE_STATUS_IN_CONFIG |
@@ -349,7 +357,11 @@ void test_submodule_update__can_force_update(void)
 	 * Verify state after checkout of parent repository. The submodule ID in the
 	 * HEAD commit and index should be updated, but not the workdir.
 	 */
-	cl_git_pass(git_submodule_status(&submodule_status, sm));
+	cl_git_pass(git_submodule_status(&submodule_status, g_repo, "testrepo"));
+
+	git_submodule_free(sm);
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
+
 	cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD |
 		GIT_SUBMODULE_STATUS_IN_INDEX |
 		GIT_SUBMODULE_STATUS_IN_CONFIG |