rev-list: disable object/refname ambiguity check with --stdin
[gitweb.git] / builtin / cat-file.c
index 425346048bbba66874eb857985bed9937c44e1d6..cc863ff78c1b7f4029f8c3a2011c5bd0054a3b84 100644 (file)
@@ -45,6 +45,14 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name)
        case 'e':
                return !has_sha1_file(sha1);
 
+       case 'c':
+               if (!obj_context.path[0])
+                       die("git cat-file --textconv %s: <object> must be <sha1:path>",
+                           obj_name);
+
+               if (textconv_object(obj_context.path, obj_context.mode, sha1, 1, &buf, &size))
+                       break;
+
        case 'p':
                type = sha1_object_info(sha1, NULL);
                if (type < 0)
@@ -67,16 +75,6 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name)
                /* otherwise just spit out the data */
                break;
 
-       case 'c':
-               if (!obj_context.path[0])
-                       die("git cat-file --textconv %s: <object> must be <sha1:path>",
-                           obj_name);
-
-               if (!textconv_object(obj_context.path, obj_context.mode, sha1, 1, &buf, &size))
-                       die("git cat-file --textconv: unable to run textconv on %s",
-                           obj_name);
-               break;
-
        case 0:
                if (type_from_string(exp_type) == OBJ_BLOB) {
                        unsigned char blob_sha1[20];
@@ -119,6 +117,7 @@ struct expand_data {
        enum object_type type;
        unsigned long size;
        unsigned long disk_size;
+       const char *rest;
 
        /*
         * If mark_query is true, we do not expand anything, but rather
@@ -126,6 +125,13 @@ struct expand_data {
         */
        int mark_query;
 
+       /*
+        * Whether to split the input on whitespace before feeding it to
+        * get_sha1; this is decided during the mark_query phase based on
+        * whether we have a %(rest) token in our format.
+        */
+       int split_on_whitespace;
+
        /*
         * After a mark_query run, this object_info is set up to be
         * passed to sha1_object_info_extended. It will point to the data
@@ -163,6 +169,11 @@ static void expand_atom(struct strbuf *sb, const char *atom, int len,
                        data->info.disk_sizep = &data->disk_size;
                else
                        strbuf_addf(sb, "%lu", data->disk_size);
+       } else if (is_atom("rest", atom, len)) {
+               if (data->mark_query)
+                       data->split_on_whitespace = 1;
+               else if (data->rest)
+                       strbuf_addstr(sb, data->rest);
        } else
                die("unknown format element: %.*s", len, atom);
 }
@@ -249,6 +260,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)";
@@ -270,15 +283,32 @@ 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 = batch_one_object(buf.buf, opt, &data);
-               if (error)
-                       return error;
+               if (data.split_on_whitespace) {
+                       /*
+                        * Split at first whitespace, tying off the beginning
+                        * of the string and saving the remainder (or NULL) in
+                        * data.rest.
+                        */
+                       char *p = strpbrk(buf.buf, " \t");
+                       if (p) {
+                               while (*p && strchr(" \t", *p))
+                                       *p++ = '\0';
+                       }
+                       data.rest = p;
+               }
+
+               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[] = {