tests: replace binary GPG keyrings with ASCII-armored keys
[gitweb.git] / builtin / cat-file.c
index 2e0af2e617e400a5c99465edd82f0dd1f8927680..f8d81291b9913a769f79405720210aa4eaf6daee 100644 (file)
@@ -82,8 +82,9 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name)
                                enum object_type type;
                                unsigned long size;
                                char *buffer = read_sha1_file(sha1, &type, &size);
-                               if (memcmp(buffer, "object ", 7) ||
-                                   get_sha1_hex(buffer + 7, blob_sha1))
+                               const char *target;
+                               if (!skip_prefix(buffer, "object ", &target) ||
+                                   get_sha1_hex(target, blob_sha1))
                                        die("%s not a valid tag", sha1_to_hex(sha1));
                                free(buffer);
                        } else
@@ -199,25 +200,28 @@ static size_t expand_format(struct strbuf *sb, const char *start, void *data)
        return end - start + 1;
 }
 
-static void print_object_or_die(int fd, const unsigned char *sha1,
-                               enum object_type type, unsigned long size)
+static void print_object_or_die(int fd, struct expand_data *data)
 {
-       if (type == OBJ_BLOB) {
+       const unsigned char *sha1 = data->sha1;
+
+       assert(data->info.typep);
+
+       if (data->type == OBJ_BLOB) {
                if (stream_blob_to_fd(fd, sha1, NULL, 0) < 0)
                        die("unable to stream %s to stdout", sha1_to_hex(sha1));
        }
        else {
-               enum object_type rtype;
-               unsigned long rsize;
+               enum object_type type;
+               unsigned long size;
                void *contents;
 
-               contents = read_sha1_file(sha1, &rtype, &rsize);
+               contents = read_sha1_file(sha1, &type, &size);
                if (!contents)
                        die("object %s disappeared", sha1_to_hex(sha1));
-               if (rtype != type)
+               if (type != data->type)
                        die("object %s changed type!?", sha1_to_hex(sha1));
-               if (rsize != size)
-                       die("object %s change size!?", sha1_to_hex(sha1));
+               if (data->info.sizep && size != data->size)
+                       die("object %s changed size!?", sha1_to_hex(sha1));
 
                write_or_die(fd, contents, size);
                free(contents);
@@ -244,7 +248,7 @@ static int batch_one_object(const char *obj_name, struct batch_options *opt,
                return 0;
        }
 
-       if (sha1_object_info_extended(data->sha1, &data->info) < 0) {
+       if (sha1_object_info_extended(data->sha1, &data->info, LOOKUP_REPLACE_OBJECT) < 0) {
                printf("%s missing\n", obj_name);
                fflush(stdout);
                return 0;
@@ -256,7 +260,7 @@ static int batch_one_object(const char *obj_name, struct batch_options *opt,
        strbuf_release(&buf);
 
        if (opt->print_contents) {
-               print_object_or_die(1, data->sha1, data->type, data->size);
+               print_object_or_die(1, data);
                write_or_die(1, "\n", 1);
        }
        return 0;
@@ -266,6 +270,8 @@ static int batch_objects(struct batch_options *opt)
 {
        struct strbuf buf = STRBUF_INIT;
        struct expand_data data;
+       int save_warning;
+       int retval = 0;
 
        if (!opt->format)
                opt->format = "%(objectname) %(objecttype) %(objectsize)";
@@ -280,6 +286,13 @@ static int batch_objects(struct batch_options *opt)
        strbuf_expand(&buf, opt->format, expand_format, &data);
        data.mark_query = 0;
 
+       /*
+        * If we are printing out the object, then always fill in the type,
+        * since we will want to decide whether or not to stream.
+        */
+       if (opt->print_contents)
+               data.info.typep = &data.type;
+
        /*
         * We are going to call get_sha1 on a potentially very large number of
         * objects. In most large cases, these will be actual object sha1s. The
@@ -287,11 +300,10 @@ static int batch_objects(struct batch_options *opt)
         * warn) ends up dwarfing the actual cost of the object lookups
         * themselves. We can work around it by just turning off the warning.
         */
+       save_warning = warn_on_object_refname_ambiguity;
        warn_on_object_refname_ambiguity = 0;
 
        while (strbuf_getline(&buf, stdin, '\n') != EOF) {
-               int error;
-
                if (data.split_on_whitespace) {
                        /*
                         * Split at first whitespace, tying off the beginning
@@ -306,12 +318,14 @@ static int batch_objects(struct batch_options *opt)
                        data.rest = p;
                }
 
-               error = batch_one_object(buf.buf, opt, &data);
-               if (error)
-                       return error;
+               retval = batch_one_object(buf.buf, opt, &data);
+               if (retval)
+                       break;
        }
 
-       return 0;
+       strbuf_release(&buf);
+       warn_on_object_refname_ambiguity = save_warning;
+       return retval;
 }
 
 static const char * const cat_file_usage[] = {