@@ -217,7 +217,7 @@ static void batch_object_write(const char *obj_name,
struct expand_data *data)
{
int ret;
- struct ref_array_item item = { data->oid, data->rest };
+ struct ref_array_item item = { data->oid, data->rest, opt->cmdmode };
strbuf_reset(scratch);
strbuf_reset(err);
@@ -1,3 +1,4 @@
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "builtin.h"
#include "cache.h"
#include "parse-options.h"
@@ -1759,6 +1760,9 @@ static int get_object(struct ref_array_item *ref, int deref, struct object **obj
{
/* parse_object_buffer() will set eaten to 0 if free() will be needed */
int eaten = 1;
+ struct expand_data *actual_oi = oi;
+ struct expand_data act_oi = {0};
+
if (oi->info.contentp) {
/* We need to know that to use parse_object_buffer properly */
oi->info.sizep = &oi->size;
@@ -1772,19 +1776,47 @@ static int get_object(struct ref_array_item *ref, int deref, struct object **obj
BUG("Object size is less than zero.");
if (oi->info.contentp) {
- *obj = parse_object_buffer(the_repository, &oi->oid, oi->type, oi->size, oi->content, &eaten);
+ if ((ref->cat_file_cmdmode == 'c' || ref->cat_file_cmdmode == 'w') && !ref->rest)
+ return strbuf_addf_ret(err, -1, _("missing path for '%s'"),
+ oid_to_hex(&act_oi.oid));
+ if (oi->type == OBJ_BLOB) {
+ if (ref->cat_file_cmdmode == 'c') {
+ act_oi = *oi;
+ if (textconv_object(the_repository,
+ ref->rest, 0100644, &act_oi.oid,
+ 1, (char **)(&act_oi.content), &act_oi.size))
+ actual_oi = &act_oi;
+ } else if (ref->cat_file_cmdmode == 'w') {
+ struct strbuf strbuf = STRBUF_INIT;
+ struct checkout_metadata meta;
+ act_oi = *oi;
+
+ init_checkout_metadata(&meta, NULL, NULL, &act_oi.oid);
+ if (!convert_to_working_tree(&the_index, ref->rest, act_oi.content, act_oi.size, &strbuf, &meta))
+ die("could not convert '%s' %s",
+ oid_to_hex(&oi->oid), ref->rest);
+ act_oi.size = strbuf.len;
+ act_oi.content = strbuf_detach(&strbuf, NULL);
+ actual_oi = &act_oi;
+ }
+ }
+ *obj = parse_object_buffer(the_repository, &actual_oi->oid, actual_oi->type, actual_oi->size, actual_oi->content, &eaten);
if (!*obj) {
if (!eaten)
+ free(actual_oi->content);
+ if (actual_oi != oi)
free(oi->content);
return strbuf_addf_ret(err, -1, _("parse_object_buffer failed on %s for %s"),
oid_to_hex(&oi->oid), ref->refname);
}
- grab_values(ref->value, deref, *obj, oi);
+ grab_values(ref->value, deref, *obj, actual_oi);
}
grab_common_values(ref->value, deref, oi);
if (!eaten)
free(oi->content);
+ if (actual_oi != oi)
+ free(actual_oi->content);
return 0;
}
@@ -2193,6 +2225,7 @@ static struct ref_array_item *new_ref_array_item(const char *refname,
FLEX_ALLOC_STR(ref, refname, refname);
oidcpy(&ref->objectname, oid);
ref->rest = NULL;
+ ref->cat_file_cmdmode = 0;
return ref;
}
@@ -39,6 +39,7 @@ struct ref_sorting {
struct ref_array_item {
struct object_id objectname;
const char *rest;
+ int cat_file_cmdmode;
int flag;
unsigned int kind;
const char *symref;