|
|
|
@ -11,6 +11,7 @@
@@ -11,6 +11,7 @@
|
|
|
|
|
#include "parse-options.h" |
|
|
|
|
#include "diff.h" |
|
|
|
|
#include "userdiff.h" |
|
|
|
|
#include "streaming.h" |
|
|
|
|
|
|
|
|
|
#define BATCH 1 |
|
|
|
|
#define BATCH_CHECK 2 |
|
|
|
@ -127,6 +128,8 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name)
@@ -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); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (type == OBJ_BLOB) |
|
|
|
|
return stream_blob_to_fd(1, sha1, NULL, 0); |
|
|
|
|
buf = read_sha1_file(sha1, &type, &size); |
|
|
|
|
if (!buf) |
|
|
|
|
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)
@@ -149,6 +152,28 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name)
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
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); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|