summaryrefslogtreecommitdiff
path: root/builtin/unpack-objects.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/unpack-objects.c')
-rw-r--r--builtin/unpack-objects.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c
index 99cde45879..7c3e79c48d 100644
--- a/builtin/unpack-objects.c
+++ b/builtin/unpack-objects.c
@@ -13,13 +13,14 @@
#include "fsck.h"
static int dry_run, quiet, recover, has_errors, strict;
-static const char unpack_usage[] = "git unpack-objects [-n] [-q] [-r] [--strict] < pack-file";
+static const char unpack_usage[] = "git unpack-objects [-n] [-q] [-r] [--strict]";
/* We always read in 4kB chunks. */
static unsigned char buffer[4096];
static unsigned int offset, len;
static off_t consumed_bytes;
static git_SHA_CTX ctx;
+static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
/*
* When running under --strict mode, objects whose reachability are
@@ -91,7 +92,7 @@ static void use(int bytes)
static void *get_data(unsigned long size)
{
git_zstream stream;
- void *buf = xmalloc(size);
+ void *buf = xmallocz(size);
memset(&stream, 0, sizeof(stream));
@@ -164,10 +165,10 @@ static unsigned nr_objects;
* Called only from check_object() after it verified this object
* is Ok.
*/
-static void write_cached_object(struct object *obj)
+static void write_cached_object(struct object *obj, struct obj_buffer *obj_buf)
{
unsigned char sha1[20];
- struct obj_buffer *obj_buf = lookup_object_buffer(obj);
+
if (write_sha1_file(obj_buf->buffer, obj_buf->size, typename(obj->type), sha1) < 0)
die("failed to write object %s", sha1_to_hex(obj->sha1));
obj->flags |= FLAG_WRITTEN;
@@ -178,8 +179,10 @@ static void write_cached_object(struct object *obj)
* that have reachability requirements and calls this function.
* Verify its reachability and validity recursively and write it out.
*/
-static int check_object(struct object *obj, int type, void *data)
+static int check_object(struct object *obj, int type, void *data, struct fsck_options *options)
{
+ struct obj_buffer *obj_buf;
+
if (!obj)
return 1;
@@ -198,11 +201,15 @@ static int check_object(struct object *obj, int type, void *data)
return 0;
}
- if (fsck_object(obj, 1, fsck_error_function))
+ obj_buf = lookup_object_buffer(obj);
+ if (!obj_buf)
+ die("Whoops! Cannot find object '%s'", sha1_to_hex(obj->sha1));
+ if (fsck_object(obj, obj_buf->buffer, obj_buf->size, &fsck_options))
die("Error in object");
- if (fsck_walk(obj, check_object, NULL))
+ fsck_options.walk = check_object;
+ if (fsck_walk(obj, NULL, &fsck_options))
die("Error on reachable objects of %s", sha1_to_hex(obj->sha1));
- write_cached_object(obj);
+ write_cached_object(obj, obj_buf);
return 0;
}
@@ -211,7 +218,7 @@ static void write_rest(void)
unsigned i;
for (i = 0; i < nr_objects; i++) {
if (obj_list[i].obj)
- check_object(obj_list[i].obj, OBJ_ANY, NULL);
+ check_object(obj_list[i].obj, OBJ_ANY, NULL, NULL);
}
}
@@ -523,6 +530,11 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix)
strict = 1;
continue;
}
+ if (skip_prefix(arg, "--strict=", &arg)) {
+ strict = 1;
+ fsck_set_msg_types(&fsck_options, arg);
+ continue;
+ }
if (starts_with(arg, "--pack_header=")) {
struct pack_header *hdr;
char *c;