Skip to content

Commit

Permalink
introduce "preciousObjects" repository extension
Browse files Browse the repository at this point in the history
If this extension is used in a repository, then no
operations should run which may drop objects from the object
storage. This can be useful if you are sharing that storage
with other repositories whose refs you cannot see.

For instance, if you do:

  $ git clone -s parent child
  $ git -C parent config extensions.preciousObjects true
  $ git -C parent config core.repositoryformatversion 1

you now have additional safety when running git in the
parent repository. Prunes and repacks will bail with an
error, and `git gc` will skip those operations (it will
continue to pack refs and do other non-object operations).
Older versions of git, when run in the repository, will
fail on every operation.

Note that we do not set the preciousObjects extension by
default when doing a "clone -s", as doing so breaks
backwards compatibility. It is a decision the user should
make explicitly.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Jeff King authored and Junio C Hamano committed Jun 25, 2015
1 parent 00a09d5 commit 067fbd4
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 9 deletions.
7 changes: 7 additions & 0 deletions Documentation/technical/repository-version.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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`).
20 changes: 11 additions & 9 deletions builtin/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
3 changes: 3 additions & 0 deletions builtin/prune.c
Original file line number Diff line number Diff line change
Expand Up @@ -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++;
Expand Down
3 changes: 3 additions & 0 deletions builtin/repack.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
1 change: 1 addition & 0 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions environment.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
22 changes: 22 additions & 0 deletions t/t1302-repo-version.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 067fbd4

Please sign in to comment.