cat-file: use streaming API to print blobs

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Nguyễn Thái Ngọc Duy 2012-03-07 17:54:17 +07:00 committed by Junio C Hamano
parent d41489a642
commit 00c8fd493a
2 changed files with 27 additions and 2 deletions

View File

@ -11,6 +11,7 @@
#include "parse-options.h" #include "parse-options.h"
#include "diff.h" #include "diff.h"
#include "userdiff.h" #include "userdiff.h"
#include "streaming.h"
#define BATCH 1 #define BATCH 1
#define BATCH_CHECK 2 #define BATCH_CHECK 2
@ -127,6 +128,8 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name)
return cmd_ls_tree(2, ls_args, NULL); return cmd_ls_tree(2, ls_args, NULL);
} }
if (type == OBJ_BLOB)
return stream_blob_to_fd(1, sha1, NULL, 0);
buf = read_sha1_file(sha1, &type, &size); buf = read_sha1_file(sha1, &type, &size);
if (!buf) if (!buf)
die("Cannot read object %s", obj_name); die("Cannot read object %s", obj_name);
@ -149,6 +152,28 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name)
break; break;
case 0: case 0:
if (type_from_string(exp_type) == OBJ_BLOB) {
unsigned char blob_sha1[20];
if (sha1_object_info(sha1, NULL) == OBJ_TAG) {
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))
die("%s not a valid tag", sha1_to_hex(sha1));
free(buffer);
} else
hashcpy(blob_sha1, sha1);
if (sha1_object_info(blob_sha1, NULL) == OBJ_BLOB)
return stream_blob_to_fd(1, blob_sha1, NULL, 0);
/*
* we attempted to dereference a tag to a blob
* and failed; there may be new dereference
* mechanisms this code is not aware of.
* fall-back to the usual case.
*/
}
buf = read_object_with_reference(sha1, exp_type, &size, NULL); buf = read_object_with_reference(sha1, exp_type, &size, NULL);
break; break;

View File

@ -116,11 +116,11 @@ test_expect_success 'hash-object' '
git hash-object large1 git hash-object large1
' '
test_expect_failure 'cat-file a large file' ' test_expect_success 'cat-file a large file' '
git cat-file blob :large1 >/dev/null git cat-file blob :large1 >/dev/null
' '
test_expect_failure 'cat-file a large file from a tag' ' test_expect_success 'cat-file a large file from a tag' '
git tag -m largefile largefiletag :large1 && git tag -m largefile largefiletag :large1 &&
git cat-file blob largefiletag >/dev/null git cat-file blob largefiletag >/dev/null
' '