Commit Diff


commit - e67867107a97eae4801a85636493efb4239a61cd
commit + 9188bd7879dac13c9b727f55056edaa8ffd81b25
blob - 4852f9d736dbac0c5937db2d764f79b66a7a4abf
blob + 1290b7007bf14c58dc88fc618969d59fe988b94a
--- gotadmin/gotadmin.1
+++ gotadmin/gotadmin.1
@@ -237,6 +237,12 @@ and
 will only purge corresponding objects once such references have been
 deleted with
 .Cm got ref -d .
+.Pp
+The
+.Dq preciousObjects
+Git extension is intended to prevent the removal of objects from a repository.
+.Cm gotadmin cleanup 
+will refuse to operate on repositories where this extension is active.
 .Pp
 The options for
 .Cm gotadmin cleanup
blob - 22ab038974a7575228d4b2fc26a06d6feb886e0f
blob + 3a8fe2211096a986460483094705912532891e8e
--- gotadmin/gotadmin.c
+++ gotadmin/gotadmin.c
@@ -971,6 +971,8 @@ cmd_cleanup(int argc, char *argv[])
 	char scaled_before[FMT_SCALED_STRSIZE];
 	char scaled_after[FMT_SCALED_STRSIZE];
 	char scaled_diff[FMT_SCALED_STRSIZE];
+	char **extensions;
+	int nextensions, i;
 
 	while ((ch = getopt(argc, argv, "r:nq")) != -1) {
 		switch (ch) {
@@ -1015,6 +1017,17 @@ cmd_cleanup(int argc, char *argv[])
 	if (error)
 		goto done;
 
+	got_repo_get_gitconfig_extensions(&extensions, &nextensions,
+	    repo);
+	for (i = 0; i < nextensions; i++) {
+		if (strcasecmp(extensions[i], "preciousObjects") == 0) {
+			error = got_error_msg(GOT_ERR_GIT_REPO_EXT,
+			    "the preciousObjects Git extension is enabled; "
+			    "this implies that objects must not be deleted");
+			goto done;
+		}
+	}
+
 	memset(&cpa, 0, sizeof(cpa));
 	cpa.last_ncommits = -1;
 	cpa.last_npurged = -1;
blob - 2584e7cad8d98fb4009517d5add53e9b00f9d55b
blob + daa3c3755d6b05b2eb1cfa3014d128ff50539685
--- include/got_repository.h
+++ include/got_repository.h
@@ -50,6 +50,10 @@ const char *got_repo_get_global_gitconfig_author_email
 /* Obtain repository owner name if parsed from gitconfig, else NULL. */
 const char *got_repo_get_gitconfig_owner(struct got_repository *);
 
+/* Obtain the list of enabled Git extensions parsed from gitconfig. */
+void got_repo_get_gitconfig_extensions(char ***, int *,
+    struct got_repository *);
+
 /* Information about one remote repository. */
 struct got_remote_repo {
 	char *name;
blob - a8727af0dda8619fc955177c35f9183919571c0c
blob + 11cc9cb8955d06a769b92d1cd8e3f6bc2a588640
--- lib/repository.c
+++ lib/repository.c
@@ -110,6 +110,14 @@ const char *
 got_repo_get_gitconfig_owner(struct got_repository *repo)
 {
 	return repo->gitconfig_owner;
+}
+
+void
+got_repo_get_gitconfig_extensions(char ***extensions, int *nextensions,
+    struct got_repository *repo)
+{
+	*extensions = repo->extensions;
+	*nextensions = repo->nextensions;
 }
 
 int
blob - c3bf21f542eafcad208d6df25cf8fbad74a2304d
blob + b55cfe1aebef1d3a2fc7fc8cc6f5858e4ffa124b
--- regress/cmdline/cleanup.sh
+++ regress/cmdline/cleanup.sh
@@ -233,6 +233,35 @@ test_cleanup_redundant_loose_objects() {
 	test_done "$testroot" "$ret"
 }
 
+test_cleanup_precious_objects() {
+	local testroot=`test_init cleanup_precious_objects`
+
+	# enable Git's preciousObjects extension
+	(cd $testroot/repo && git config extensions.preciousObjects true)
+
+	# cleanup should now refuse to purge objects
+	gotadmin cleanup -q -r $testroot/repo > $testroot/stdout \
+		2> $testroot/stderr
+	ret="$?"
+	if [ "$ret" == "0" ]; then
+		echo "gotadmin cleanup succeeded unexpectedly" >&2
+		test_done "$testroot" "1"
+		return 1
+	fi
+
+	echo -n "gotadmin: the preciousObjects Git extension is enabled; " \
+		> $testroot/stderr.expected
+	echo "this implies that objects must not be deleted" \
+		>> $testroot/stderr.expected
+	cmp -s $testroot/stderr.expected $testroot/stderr
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		diff -u $testroot/stderr.expected $testroot/stderr
+	fi
+	test_done "$testroot" "$ret"
+}
+
 test_parseargs "$@"
 run_test test_cleanup_unreferenced_loose_objects
 run_test test_cleanup_redundant_loose_objects
+run_test test_cleanup_precious_objects