aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--builtin/index-pack.c21
-rw-r--r--fsck.c6
-rw-r--r--fsck.h7
-rwxr-xr-xt/t5302-pack-index.sh16
4 files changed, 47 insertions, 3 deletions
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 2b78ba7fe4..699fe678cd 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -1640,7 +1640,7 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
rename_tmp_packfile(&final_index_name, curr_index_name, &index_name,
hash, "idx", 1);
- if (do_fsck_object)
+ if (do_fsck_object && startup_info->have_repository)
packfile_store_load_pack(the_repository->objects->packfiles,
final_index_name, 0);
@@ -2110,8 +2110,23 @@ int cmd_index_pack(int argc,
else
close(input_fd);
- if (do_fsck_object && fsck_finish(&fsck_options))
- die(_("fsck error in pack objects"));
+ if (do_fsck_object) {
+ /*
+ * We cannot perform queued consistency checks when running
+ * outside of a repository because those require us to read
+ * from the object database, which is uninitialized.
+ *
+ * TODO: we may eventually set up an in-memory object database,
+ * which would allow us to perform these queued checks.
+ */
+ if (!startup_info->have_repository &&
+ fsck_has_queued_checks(&fsck_options))
+ die(_("cannot perform queued object checks outside "
+ "of a repository"));
+
+ if (fsck_finish(&fsck_options))
+ die(_("fsck error in pack objects"));
+ }
free(opts.anomaly);
free(objects);
diff --git a/fsck.c b/fsck.c
index 341e100d24..8e1565fe6d 100644
--- a/fsck.c
+++ b/fsck.c
@@ -1350,6 +1350,12 @@ int fsck_finish(struct fsck_options *options)
return ret;
}
+bool fsck_has_queued_checks(struct fsck_options *options)
+{
+ return !oidset_equal(&options->gitmodules_found, &options->gitmodules_done) ||
+ !oidset_equal(&options->gitattributes_found, &options->gitattributes_done);
+}
+
void fsck_options_clear(struct fsck_options *options)
{
free(options->msg_type);
diff --git a/fsck.h b/fsck.h
index cb6ef32f4f..336917c045 100644
--- a/fsck.h
+++ b/fsck.h
@@ -249,6 +249,13 @@ int fsck_tag_standalone(const struct object_id *oid, const char *buffer,
int fsck_finish(struct fsck_options *options);
/*
+ * Check whether there are any checks that have been queued up and that still
+ * need to be run. Returns `false` iff `fsck_finish()` wouldn't perform any
+ * actions, `true` otherwise.
+ */
+bool fsck_has_queued_checks(struct fsck_options *options);
+
+/*
* Clear the fsck_options struct, freeing any allocated memory.
*/
void fsck_options_clear(struct fsck_options *options);
diff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh
index 413c99274c..9697448cb2 100755
--- a/t/t5302-pack-index.sh
+++ b/t/t5302-pack-index.sh
@@ -293,4 +293,20 @@ test_expect_success 'too-large packs report the breach' '
grep "maximum allowed size (20 bytes)" err
'
+# git-index-pack(1) uses the default hash algorithm outside of the repository,
+# and it has no way to tell it otherwise. So we can only run this test with the
+# default hash algorithm, as it would otherwise fail to parse the tree.
+test_expect_success DEFAULT_HASH_ALGORITHM 'index-pack --fsck-objects outside of a repo' '
+ test_when_finished "rm -rf repo" &&
+ git init repo &&
+ (
+ cd repo &&
+ printf "100644 blob $(test_oid 001)\t.gitattributes\n" >tree &&
+ git mktree --missing <tree >tree-oid &&
+ git pack-objects <tree-oid pack &&
+ test_must_fail nongit git index-pack --fsck-objects "$(pwd)"/pack-*.pack 2>err &&
+ test_grep "cannot perform queued object checks outside of a repository" err
+ )
+'
+
test_done