Commit 5a9fc6c83c2fd12ce312d1042ec2c1e6abad4033

Carlos Martín Nieto 2015-05-04T16:22:56

submodule: make set_ignore() affect the configuration Instead of affecting a particular instance, make it change the configuration.

diff --git a/include/git2/submodule.h b/include/git2/submodule.h
index 48faf8a..e41dc49 100644
--- a/include/git2/submodule.h
+++ b/include/git2/submodule.h
@@ -452,9 +452,6 @@ GIT_EXTERN(const git_oid *) git_submodule_wd_id(git_submodule *submodule);
  *    The working directory will be consider clean so long as there is a
  *    checked out version present.
  *
- * plus the special **GIT_SUBMODULE_IGNORE_RESET** which can be used with
- * `git_submodule_set_ignore()` to revert to the on-disk setting.
- *
  * @param submodule The submodule to check
  * @return The current git_submodule_ignore_t valyue what will be used for
  *         this submodule.
@@ -463,23 +460,18 @@ GIT_EXTERN(git_submodule_ignore_t) git_submodule_ignore(
 	git_submodule *submodule);
 
 /**
- * Set the ignore rule for the submodule.
- *
- * This sets the in-memory ignore rule for the submodule which will
- * control the behavior of `git_submodule_status()`.
+ * Set the ignore rule for the submodule in the configuration
  *
- * To make changes persistent, call `git_submodule_save()` to write the
- * value to disk (in the ".gitmodules" and ".git/config" files).
+ * This does not affect any currently-loaded instances.
  *
- * Call with `GIT_SUBMODULE_IGNORE_RESET` or call `git_submodule_reload()`
- * to revert the in-memory rule to the value that is on disk.
- *
- * @param submodule The submodule to update
+ * @param repo the repository to affect
+ * @param name the name of the submdule
  * @param ignore The new value for the ignore rule
- * @return old value for ignore
+ * @return 0 or an error code
  */
-GIT_EXTERN(git_submodule_ignore_t) git_submodule_set_ignore(
-	git_submodule *submodule,
+GIT_EXTERN(int) git_submodule_set_ignore(
+	git_repository *repo,
+	const char *name,
 	git_submodule_ignore_t ignore);
 
 /**
diff --git a/src/submodule.c b/src/submodule.c
index 9a14854..78bf519 100644
--- a/src/submodule.c
+++ b/src/submodule.c
@@ -754,12 +754,6 @@ int git_submodule_save(git_submodule *submodule)
 	if (error < 0)
 		goto cleanup;
 
-	if (!(error = submodule_config_key_trunc_puts(&key, "ignore")) &&
-		(val = git_submodule_ignore_to_str(submodule->ignore)) != NULL)
-		error = git_config_file_set_string(mods, key.ptr, val);
-	if (error < 0)
-		goto cleanup;
-
 	if (!(error = submodule_config_key_trunc_puts(&key, "fetchRecurseSubmodules")) &&
 		(val = git_submodule_recurse_to_str(submodule->fetch_recurse)) != NULL)
 		error = git_config_file_set_string(mods, key.ptr, val);
@@ -906,19 +900,32 @@ git_submodule_ignore_t git_submodule_ignore(git_submodule *submodule)
 		GIT_SUBMODULE_IGNORE_NONE : submodule->ignore;
 }
 
-git_submodule_ignore_t git_submodule_set_ignore(
-	git_submodule *submodule, git_submodule_ignore_t ignore)
+int git_submodule_set_ignore(git_repository *repo, const char *name, git_submodule_ignore_t ignore)
 {
-	git_submodule_ignore_t old;
+	git_buf key = GIT_BUF_INIT;
+	git_config_backend *mods;
+	const char *val;
+	int error;
 
-	assert(submodule);
+	val = git_submodule_ignore_to_str(ignore);
+	if (!val) {
+		giterr_set(GITERR_SUBMODULE, "invalid ignore value");
+		return -1;
+	}
 
-	if (ignore == GIT_SUBMODULE_IGNORE_RESET)
-		ignore = submodule->ignore_default;
+	mods = open_gitmodules(repo, GITMODULES_CREATE);
+	if (!mods)
+		return -1;
 
-	old = submodule->ignore;
-	submodule->ignore = ignore;
-	return old;
+	if ((error = git_buf_printf(&key, "submodule.%s.ignore", name)) < 0)
+		goto cleanup;
+
+	error = git_config_file_set_string(mods, key.ptr, val);
+	git_buf_free(&key);
+
+cleanup:
+	git_config_file_free(mods);
+	return error;
 }
 
 git_submodule_update_t git_submodule_update_strategy(git_submodule *submodule)
diff --git a/tests/diff/submodules.c b/tests/diff/submodules.c
index e216958..08682cd 100644
--- a/tests/diff/submodules.c
+++ b/tests/diff/submodules.c
@@ -273,13 +273,13 @@ void test_diff_submodules__invalid_cache(void)
 
 	/* create untracked file in submodule working directory */
 	cl_git_mkfile("submod2/sm_changed_head/new_around_here", "hello");
-	git_submodule_set_ignore(sm, GIT_SUBMODULE_IGNORE_NONE);
+	git_submodule_set_ignore(g_repo, git_submodule_name(sm), GIT_SUBMODULE_IGNORE_NONE);
 
 	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
 	check_diff_patches(diff, expected_dirty);
 	git_diff_free(diff);
 
-	git_submodule_set_ignore(sm, GIT_SUBMODULE_IGNORE_UNTRACKED);
+	git_submodule_set_ignore(g_repo, git_submodule_name(sm), GIT_SUBMODULE_IGNORE_UNTRACKED);
 
 	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
 	check_diff_patches(diff, expected_unchanged);
@@ -301,7 +301,7 @@ void test_diff_submodules__invalid_cache(void)
 	check_diff_patches(diff, expected_dirty);
 	git_diff_free(diff);
 
-	git_submodule_set_ignore(sm, GIT_SUBMODULE_IGNORE_DIRTY);
+	git_submodule_set_ignore(g_repo, git_submodule_name(sm), GIT_SUBMODULE_IGNORE_DIRTY);
 
 	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
 	check_diff_patches(diff, expected_unchanged);
@@ -312,13 +312,13 @@ void test_diff_submodules__invalid_cache(void)
 	cl_git_pass(git_repository_index(&smindex, smrepo));
 	cl_git_pass(git_index_add_bypath(smindex, "file_to_modify"));
 
-	git_submodule_set_ignore(sm, GIT_SUBMODULE_IGNORE_UNTRACKED);
+	git_submodule_set_ignore(g_repo, git_submodule_name(sm), GIT_SUBMODULE_IGNORE_UNTRACKED);
 
 	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
 	check_diff_patches(diff, expected_dirty);
 	git_diff_free(diff);
 
-	git_submodule_set_ignore(sm, GIT_SUBMODULE_IGNORE_DIRTY);
+	git_submodule_set_ignore(g_repo, git_submodule_name(sm), GIT_SUBMODULE_IGNORE_DIRTY);
 
 	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
 	check_diff_patches(diff, expected_unchanged);
@@ -327,19 +327,19 @@ void test_diff_submodules__invalid_cache(void)
 	/* commit changed index of submodule */
 	cl_repo_commit_from_index(NULL, smrepo, NULL, 1372350000, "Move it");
 
-	git_submodule_set_ignore(sm, GIT_SUBMODULE_IGNORE_DIRTY);
+	git_submodule_set_ignore(g_repo, git_submodule_name(sm), GIT_SUBMODULE_IGNORE_DIRTY);
 
 	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
 	check_diff_patches(diff, expected_moved);
 	git_diff_free(diff);
 
-	git_submodule_set_ignore(sm, GIT_SUBMODULE_IGNORE_ALL);
+	git_submodule_set_ignore(g_repo, git_submodule_name(sm), GIT_SUBMODULE_IGNORE_ALL);
 
 	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
 	check_diff_patches(diff, expected_unchanged);
 	git_diff_free(diff);
 
-	git_submodule_set_ignore(sm, GIT_SUBMODULE_IGNORE_NONE);
+	git_submodule_set_ignore(g_repo, git_submodule_name(sm), GIT_SUBMODULE_IGNORE_NONE);
 
 	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
 	check_diff_patches(diff, expected_moved_dirty);
diff --git a/tests/submodule/modify.c b/tests/submodule/modify.c
index 8f24d9b..65f656e 100644
--- a/tests/submodule/modify.c
+++ b/tests/submodule/modify.c
@@ -128,11 +128,21 @@ void test_submodule_modify__sync(void)
 	git_submodule_free(sm3);
 }
 
+void test_submodule_modify__set_ignore(void)
+{
+	git_submodule *sm;
+
+	cl_git_pass(git_submodule_set_ignore(g_repo, "sm_changed_head", GIT_SUBMODULE_IGNORE_UNTRACKED));
+
+	cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_changed_head"));
+	cl_assert_equal_i(GIT_SUBMODULE_IGNORE_UNTRACKED, git_submodule_ignore(sm));
+	git_submodule_free(sm);
+}
+
 void test_submodule_modify__edit_and_save(void)
 {
 	git_submodule *sm1, *sm2;
 	char *old_url, *old_branch;
-	git_submodule_ignore_t old_ignore;
 	git_submodule_update_t old_update;
 	git_repository *r2;
 	git_submodule_recurse_t old_fetchrecurse;
@@ -145,7 +155,6 @@ void test_submodule_modify__edit_and_save(void)
 	/* modify properties of submodule */
 	cl_git_pass(git_submodule_set_url(sm1, SM_LIBGIT2_URL));
 	cl_git_pass(git_submodule_set_branch(sm1, SM_LIBGIT2_BRANCH));
-	old_ignore = git_submodule_set_ignore(sm1, GIT_SUBMODULE_IGNORE_UNTRACKED);
 	old_update = git_submodule_set_update(sm1, GIT_SUBMODULE_UPDATE_REBASE);
 	old_fetchrecurse = git_submodule_set_fetch_recurse_submodules(
 		sm1, GIT_SUBMODULE_RECURSE_YES);
@@ -153,8 +162,6 @@ void test_submodule_modify__edit_and_save(void)
 	cl_assert_equal_s(SM_LIBGIT2_URL, git_submodule_url(sm1));
 	cl_assert_equal_s(SM_LIBGIT2_BRANCH, git_submodule_branch(sm1));
 	cl_assert_equal_i(
-		GIT_SUBMODULE_IGNORE_UNTRACKED, git_submodule_ignore(sm1));
-	cl_assert_equal_i(
 		GIT_SUBMODULE_UPDATE_REBASE, git_submodule_update_strategy(sm1));
 	cl_assert_equal_i(
 		GIT_SUBMODULE_RECURSE_YES, git_submodule_fetch_recurse_submodules(sm1));
@@ -163,9 +170,6 @@ void test_submodule_modify__edit_and_save(void)
 	cl_git_pass(git_submodule_set_url(sm1, old_url));
 	cl_git_pass(git_submodule_set_branch(sm1, old_branch));
 	cl_assert_equal_i(
-		GIT_SUBMODULE_IGNORE_UNTRACKED,
-		git_submodule_set_ignore(sm1, GIT_SUBMODULE_IGNORE_RESET));
-	cl_assert_equal_i(
 		GIT_SUBMODULE_UPDATE_REBASE,
 		git_submodule_set_update(sm1, GIT_SUBMODULE_UPDATE_RESET));
 	cl_assert_equal_i(
@@ -175,7 +179,6 @@ void test_submodule_modify__edit_and_save(void)
 	/* check that revert was successful */
 	cl_assert_equal_s(old_url, git_submodule_url(sm1));
 	cl_assert_equal_s(old_branch, git_submodule_branch(sm1));
-	cl_assert_equal_i((int)old_ignore, (int)git_submodule_ignore(sm1));
 	cl_assert_equal_i((int)old_update, (int)git_submodule_update_strategy(sm1));
 	cl_assert_equal_i(
 		old_fetchrecurse, git_submodule_fetch_recurse_submodules(sm1));
@@ -183,7 +186,6 @@ void test_submodule_modify__edit_and_save(void)
 	/* modify properties of submodule (again) */
 	cl_git_pass(git_submodule_set_url(sm1, SM_LIBGIT2_URL));
 	cl_git_pass(git_submodule_set_branch(sm1, SM_LIBGIT2_BRANCH));
-	git_submodule_set_ignore(sm1, GIT_SUBMODULE_IGNORE_UNTRACKED);
 	git_submodule_set_update(sm1, GIT_SUBMODULE_UPDATE_REBASE);
 	git_submodule_set_fetch_recurse_submodules(sm1, GIT_SUBMODULE_RECURSE_YES);
 
@@ -191,15 +193,12 @@ void test_submodule_modify__edit_and_save(void)
 	cl_git_pass(git_submodule_save(sm1));
 
 	/* attempt to "revert" values */
-	git_submodule_set_ignore(sm1, GIT_SUBMODULE_IGNORE_RESET);
 	git_submodule_set_update(sm1, GIT_SUBMODULE_UPDATE_RESET);
 
 	/* but ignore and update should NOT revert because the RESET
 	 * should now be the newly saved value...
 	 */
 	cl_assert_equal_i(
-		(int)GIT_SUBMODULE_IGNORE_UNTRACKED, (int)git_submodule_ignore(sm1));
-	cl_assert_equal_i(
 		(int)GIT_SUBMODULE_UPDATE_REBASE, (int)git_submodule_update_strategy(sm1));
 	cl_assert_equal_i(GIT_SUBMODULE_RECURSE_YES, git_submodule_fetch_recurse_submodules(sm1));
 
@@ -209,8 +208,6 @@ void test_submodule_modify__edit_and_save(void)
 	cl_assert_equal_s(SM_LIBGIT2_URL, git_submodule_url(sm1));
 	cl_assert_equal_s(SM_LIBGIT2_BRANCH, git_submodule_branch(sm1));
 	cl_assert_equal_i(
-		(int)GIT_SUBMODULE_IGNORE_UNTRACKED, (int)git_submodule_ignore(sm1));
-	cl_assert_equal_i(
 		(int)GIT_SUBMODULE_UPDATE_REBASE, (int)git_submodule_update_strategy(sm1));
 	cl_assert_equal_i(GIT_SUBMODULE_RECURSE_YES, git_submodule_fetch_recurse_submodules(sm1));
 
@@ -226,8 +223,6 @@ void test_submodule_modify__edit_and_save(void)
 
 	cl_assert_equal_s(SM_LIBGIT2_URL, git_submodule_url(sm2));
 	cl_assert_equal_i(
-		GIT_SUBMODULE_IGNORE_UNTRACKED, git_submodule_ignore(sm2));
-	cl_assert_equal_i(
 		GIT_SUBMODULE_UPDATE_REBASE, git_submodule_update_strategy(sm2));
 	cl_assert_equal_i(
 		GIT_SUBMODULE_RECURSE_NO, git_submodule_fetch_recurse_submodules(sm2));
diff --git a/tests/submodule/status.c b/tests/submodule/status.c
index 6efae35..4d51d8d 100644
--- a/tests/submodule/status.c
+++ b/tests/submodule/status.c
@@ -111,7 +111,7 @@ static int set_sm_ignore(git_submodule *sm, const char *name, void *payload)
 {
 	git_submodule_ignore_t ignore = *(git_submodule_ignore_t *)payload;
 	GIT_UNUSED(name);
-	git_submodule_set_ignore(sm, ignore);
+	git_submodule_set_ignore(g_repo, git_submodule_name(sm), ignore);
 	return 0;
 }