Merge branch 'jk/cat-file-regression-fix'

"git cat-file --batch=", an admittedly useless command, did not
behave very well.

* jk/cat-file-regression-fix:
  cat-file: handle --batch format with missing type/size
  cat-file: pass expand_data to print_object_or_die
This commit is contained in:
Junio C Hamano 2013-12-27 14:58:11 -08:00
commit 604ada435b
2 changed files with 42 additions and 10 deletions

View File

@ -193,25 +193,28 @@ static size_t expand_format(struct strbuf *sb, const char *start, void *data)
return end - start + 1; return end - start + 1;
} }
static void print_object_or_die(int fd, const unsigned char *sha1, static void print_object_or_die(int fd, struct expand_data *data)
enum object_type type, unsigned long size)
{ {
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) if (stream_blob_to_fd(fd, sha1, NULL, 0) < 0)
die("unable to stream %s to stdout", sha1_to_hex(sha1)); die("unable to stream %s to stdout", sha1_to_hex(sha1));
} }
else { else {
enum object_type rtype; enum object_type type;
unsigned long rsize; unsigned long size;
void *contents; void *contents;
contents = read_sha1_file(sha1, &rtype, &rsize); contents = read_sha1_file(sha1, &type, &size);
if (!contents) if (!contents)
die("object %s disappeared", sha1_to_hex(sha1)); die("object %s disappeared", sha1_to_hex(sha1));
if (rtype != type) if (type != data->type)
die("object %s changed type!?", sha1_to_hex(sha1)); die("object %s changed type!?", sha1_to_hex(sha1));
if (rsize != size) if (data->info.sizep && size != data->size)
die("object %s change size!?", sha1_to_hex(sha1)); die("object %s changed size!?", sha1_to_hex(sha1));
write_or_die(fd, contents, size); write_or_die(fd, contents, size);
free(contents); free(contents);
@ -250,7 +253,7 @@ static int batch_one_object(const char *obj_name, struct batch_options *opt,
strbuf_release(&buf); strbuf_release(&buf);
if (opt->print_contents) { 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); write_or_die(1, "\n", 1);
} }
return 0; return 0;
@ -274,6 +277,13 @@ static int batch_objects(struct batch_options *opt)
strbuf_expand(&buf, opt->format, expand_format, &data); strbuf_expand(&buf, opt->format, expand_format, &data);
data.mark_query = 0; 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 * 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 * objects. In most large cases, these will be actual object sha1s. The

View File

@ -85,6 +85,28 @@ $content"
git cat-file --batch-check="%(objecttype) %(rest)" >actual && git cat-file --batch-check="%(objecttype) %(rest)" >actual &&
test_cmp expect actual test_cmp expect actual
' '
test -z "$content" ||
test_expect_success "--batch without type ($type)" '
{
echo "$size" &&
maybe_remove_timestamp "$content" $no_ts
} >expect &&
echo $sha1 | git cat-file --batch="%(objectsize)" >actual.full &&
maybe_remove_timestamp "$(cat actual.full)" $no_ts >actual &&
test_cmp expect actual
'
test -z "$content" ||
test_expect_success "--batch without size ($type)" '
{
echo "$type" &&
maybe_remove_timestamp "$content" $no_ts
} >expect &&
echo $sha1 | git cat-file --batch="%(objecttype)" >actual.full &&
maybe_remove_timestamp "$(cat actual.full)" $no_ts >actual &&
test_cmp expect actual
'
} }
hello_content="Hello World" hello_content="Hello World"