cat-file: handle streaming failures consistently

There are three ways to convince cat-file to stream a blob:

  - cat-file -p $blob

  - cat-file blob $blob

  - echo $batch | cat-file --batch

In the first two, we simply exit with the error code of
streaw_blob_to_fd(). That means that an error will cause us
to exit with "-1" (which we try to avoid) without printing
any kind of error message (which is confusing to the user).

Instead, let's match the third case, which calls die() on an
error. Unfortunately we cannot be more specific, as
stream_blob_to_fd() does not tell us whether the problem was
on reading (e.g., a corrupt object) or on writing (e.g.,
ENOSPC). That might be an opportunity for future work, but
for now we will at least exit with a sane message and exit
code.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Jeff King 2018-10-30 19:23:38 -04:00 коммит произвёл Junio C Hamano
Родитель ccdc4819d5
Коммит 98f425b453
1 изменённых файлов: 12 добавлений и 4 удалений

Просмотреть файл

@ -45,6 +45,13 @@ static int filter_object(const char *path, unsigned mode,
return 0; return 0;
} }
static int stream_blob(const struct object_id *oid)
{
if (stream_blob_to_fd(1, oid, NULL, 0))
die("unable to stream %s to stdout", oid_to_hex(oid));
return 0;
}
static int cat_one_file(int opt, const char *exp_type, const char *obj_name, static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
int unknown_type) int unknown_type)
{ {
@ -124,7 +131,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
} }
if (type == OBJ_BLOB) if (type == OBJ_BLOB)
return stream_blob_to_fd(1, &oid, NULL, 0); return stream_blob(&oid);
buf = read_sha1_file(oid.hash, &type, &size); buf = read_sha1_file(oid.hash, &type, &size);
if (!buf) if (!buf)
die("Cannot read object %s", obj_name); die("Cannot read object %s", obj_name);
@ -146,7 +153,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
oidcpy(&blob_oid, &oid); oidcpy(&blob_oid, &oid);
if (sha1_object_info(blob_oid.hash, NULL) == OBJ_BLOB) if (sha1_object_info(blob_oid.hash, NULL) == OBJ_BLOB)
return stream_blob_to_fd(1, &blob_oid, NULL, 0); return stream_blob(&blob_oid);
/* /*
* we attempted to dereference a tag to a blob * we attempted to dereference a tag to a blob
* and failed; there may be new dereference * and failed; there may be new dereference
@ -306,8 +313,9 @@ static void print_object_or_die(struct batch_options *opt, struct expand_data *d
die("BUG: invalid cmdmode: %c", opt->cmdmode); die("BUG: invalid cmdmode: %c", opt->cmdmode);
batch_write(opt, contents, size); batch_write(opt, contents, size);
free(contents); free(contents);
} else if (stream_blob_to_fd(1, oid, NULL, 0) < 0) } else {
die("unable to stream %s to stdout", oid_to_hex(oid)); stream_blob(oid);
}
} }
else { else {
enum object_type type; enum object_type type;