Subject: [PATCH v2 15/16] config: add core.noshallow to prevent turning a repo into a shallow one

From: Nguyễn Thái Ngọc Duy <[email-masked]>
Date: Sat, 20 Jul 2013 16:58:09 +0700

Signed-off-by: Nguyễn Thái Ngọc Duy <[email-masked]>
---
 Documentation/config.txt | 5 +++++
 builtin/receive-pack.c   | 9 ++++++++-
 cache.h                  | 1 +
 config.c                 | 5 +++++
 environment.c            | 1 +
 fetch-pack.c             | 9 ++++++++-
 t/t5536-fetch-shallow.sh | 9 +++++++++
 t/t5537-push-shallow.sh  | 6 ++++++
 8 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 81856dd..e811180 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -655,6 +655,11 @@ core.abbrev::
 	for abbreviated object names to stay unique for sufficiently long
 	time.
 
+core.noshallow::
+	If true, reject any pushes or fetches that may turn the
+	repository into a shallow one. This setting is ignored if the
+	repository is already shallow.
+
 add.ignore-errors::
 add.ignoreErrors::
 	Tells 'git add' to continue adding files when some files cannot be
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 54bf6b2..95ea481 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -936,7 +936,14 @@ static const char *unpack(int err_fd)
 					&shallow,
 					WRITE_SHALLOW_NO_CUT |
 					WRITE_SHALLOW_REWRITE);
-		commit_lock_file(&shallow_lock);
+		if (*alternate_shallow_file == '\0') {
+			unlink_or_warn(git_path("shallow"));
+			rollback_lock_file(&shallow_lock);
+		} else {
+			if (!is_repository_shallow() && cannot_be_shallow)
+				die("not allowed to turn this repository into a shallow one");
+			commit_lock_file(&shallow_lock);
+		}
 	}
 	return NULL;
 }
diff --git a/cache.h b/cache.h
index 7f17228..3a52b08 100644
--- a/cache.h
+++ b/cache.h
@@ -592,6 +592,7 @@ extern int fsync_object_files;
 extern int core_preload_index;
 extern int core_apply_sparse_checkout;
 extern int precomposed_unicode;
+extern int cannot_be_shallow;
 
 /*
  * The character that begins a commented line in user-editable file
diff --git a/config.c b/config.c
index d04e815..31f5a57 100644
--- a/config.c
+++ b/config.c
@@ -784,6 +784,11 @@ static int git_default_core_config(const char *var, const char *value)
 		return 0;
 	}
 
+	if (!strcmp(var, "core.noshallow")) {
+		cannot_be_shallow = git_config_bool(var, value);
+		return 0;
+	}
+
 	/* Add other config variables here and to Documentation/config.txt. */
 	return 0;
 }
diff --git a/environment.c b/environment.c
index 0cb67b2..14c8005 100644
--- a/environment.c
+++ b/environment.c
@@ -61,6 +61,7 @@ int merge_log_config = -1;
 int precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */
 struct startup_info *startup_info;
 unsigned long pack_size_limit_cfg;
+int cannot_be_shallow;
 
 /*
  * The character that begins a commented line in user-editable file
diff --git a/fetch-pack.c b/fetch-pack.c
index f337526..40e7aa2 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -960,7 +960,14 @@ struct ref *fetch_pack(struct fetch_pack_args *args,
 							WRITE_SHALLOW_NO_CUT |
 							WRITE_SHALLOW_REWRITE);
 			}
-			commit_lock_file(&shallow_lock);
+			if (*alternate_shallow_file == '\0') {
+				unlink_or_warn(git_path("shallow"));
+				rollback_lock_file(&shallow_lock);
+			} else {
+				if (!is_repository_shallow() && cannot_be_shallow)
+					die("not allowed to turn this repository into a shallow one");
+				commit_lock_file(&shallow_lock);
+			}
 		}
 	}
 
diff --git a/t/t5536-fetch-shallow.sh b/t/t5536-fetch-shallow.sh
index 6ea6347..b7f89b1 100755
--- a/t/t5536-fetch-shallow.sh
+++ b/t/t5536-fetch-shallow.sh
@@ -102,6 +102,15 @@ EOF
 
 '
 
+test_expect_success 'core.noshallow' '
+	git init clean &&
+	(
+	cd clean &&
+	git config core.noshallow true &&
+	test_must_fail git fetch ../shallow/.git
+	)
+'
+
 if test -n "$NO_CURL" -o -z "$GIT_TEST_HTTPD"; then
 	say 'skipping remaining tests, git built without http support'
 	test_done
diff --git a/t/t5537-push-shallow.sh b/t/t5537-push-shallow.sh
index 8bea496..0edd51f 100755
--- a/t/t5537-push-shallow.sh
+++ b/t/t5537-push-shallow.sh
@@ -108,6 +108,12 @@ EOF
 	)
 '
 
+test_expect_success 'core.noshallow' '
+	git init clean &&
+	git --git-dir=clean/.git config core.noshallow true &&
+	test_must_fail git --git-dir=shallow/.git push clean master:refs/remotes/shallow/master
+'
+
 if test -n "$NO_CURL" -o -z "$GIT_TEST_HTTPD"; then
 	say 'skipping remaining tests, git built without http support'
 	test_done
-- 
1.8.2.83.gc99314b