summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/technical/repository-version.txt7
-rw-r--r--builtin/gc.c20
-rw-r--r--builtin/prune.c3
-rw-r--r--builtin/repack.c3
-rw-r--r--cache.h1
-rw-r--r--environment.c1
-rw-r--r--setup.c2
-rwxr-xr-xt/t1302-repo-version.sh22
8 files changed, 50 insertions, 9 deletions
diff --git a/Documentation/technical/repository-version.txt b/Documentation/technical/repository-version.txt
index 3d7106d93d..00ad37986e 100644
--- a/Documentation/technical/repository-version.txt
+++ b/Documentation/technical/repository-version.txt
@@ -79,3 +79,10 @@ The defined extensions are:
This extension does not change git's behavior at all. It is useful only
for testing format-1 compatibility.
+
+`preciousObjects`
+~~~~~~~~~~~~~~~~~
+
+When the config key `extensions.preciousObjects` is set to `true`,
+objects in the repository MUST NOT be deleted (e.g., by `git-prune` or
+`git repack -d`).
diff --git a/builtin/gc.c b/builtin/gc.c
index 36fe33300f..8b8dc6b610 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -352,15 +352,17 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
if (gc_before_repack())
return -1;
- if (run_command_v_opt(repack.argv, RUN_GIT_CMD))
- return error(FAILED_RUN, repack.argv[0]);
-
- if (prune_expire) {
- argv_array_push(&prune, prune_expire);
- if (quiet)
- argv_array_push(&prune, "--no-progress");
- if (run_command_v_opt(prune.argv, RUN_GIT_CMD))
- return error(FAILED_RUN, prune.argv[0]);
+ if (!repository_format_precious_objects) {
+ if (run_command_v_opt(repack.argv, RUN_GIT_CMD))
+ return error(FAILED_RUN, repack.argv[0]);
+
+ if (prune_expire) {
+ argv_array_push(&prune, prune_expire);
+ if (quiet)
+ argv_array_push(&prune, "--no-progress");
+ if (run_command_v_opt(prune.argv, RUN_GIT_CMD))
+ return error(FAILED_RUN, prune.argv[0]);
+ }
}
if (prune_worktrees_expire) {
diff --git a/builtin/prune.c b/builtin/prune.c
index 0c73246c72..6a58e75108 100644
--- a/builtin/prune.c
+++ b/builtin/prune.c
@@ -218,6 +218,9 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
return 0;
}
+ if (repository_format_precious_objects)
+ die(_("cannot prune in a precious-objects repo"));
+
while (argc--) {
unsigned char sha1[20];
const char *name = *argv++;
diff --git a/builtin/repack.c b/builtin/repack.c
index af7340c7ba..3beda2c65a 100644
--- a/builtin/repack.c
+++ b/builtin/repack.c
@@ -193,6 +193,9 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix, builtin_repack_options,
git_repack_usage, 0);
+ if (delete_redundant && repository_format_precious_objects)
+ die(_("cannot delete packs in a precious-objects repo"));
+
if (pack_kept_objects < 0)
pack_kept_objects = write_bitmaps;
diff --git a/cache.h b/cache.h
index 996584c1ce..b1bc401055 100644
--- a/cache.h
+++ b/cache.h
@@ -694,6 +694,7 @@ extern int grafts_replace_parents;
#define GIT_REPO_VERSION 0
#define GIT_REPO_VERSION_READ 1
extern int repository_format_version;
+extern int repository_format_precious_objects;
extern int check_repository_format(void);
#define MTIME_CHANGED 0x0001
diff --git a/environment.c b/environment.c
index 61c685b8d9..da66e829d1 100644
--- a/environment.c
+++ b/environment.c
@@ -26,6 +26,7 @@ int warn_ambiguous_refs = 1;
int warn_on_object_refname_ambiguity = 1;
int ref_paranoia = -1;
int repository_format_version;
+int repository_format_precious_objects;
const char *git_commit_encoding;
const char *git_log_output_encoding;
int shared_repository = PERM_UMASK;
diff --git a/setup.c b/setup.c
index 0d5384683c..8b8dca9fd2 100644
--- a/setup.c
+++ b/setup.c
@@ -367,6 +367,8 @@ static int check_repo_format(const char *var, const char *value, void *cb)
*/
if (!strcmp(ext, "noop"))
;
+ else if (!strcmp(ext, "preciousobjects"))
+ repository_format_precious_objects = git_config_bool(var, value);
else
string_list_append(&unknown_extensions, ext);
}
diff --git a/t/t1302-repo-version.sh b/t/t1302-repo-version.sh
index 8dd6fd7baa..9bcd34969f 100755
--- a/t/t1302-repo-version.sh
+++ b/t/t1302-repo-version.sh
@@ -105,4 +105,26 @@ abort 1 no-such-extension
allow 0 no-such-extension
EOF
+test_expect_success 'precious-objects allowed' '
+ mkconfig 1 preciousObjects >.git/config &&
+ check_allow
+'
+
+test_expect_success 'precious-objects blocks destructive repack' '
+ test_must_fail git repack -ad
+'
+
+test_expect_success 'other repacks are OK' '
+ test_commit foo &&
+ git repack
+'
+
+test_expect_success 'precious-objects blocks prune' '
+ test_must_fail git prune
+'
+
+test_expect_success 'gc runs without complaint' '
+ git gc
+'
+
test_done