@@ -241,7 +241,7 @@ raw:size::
The raw data size of the object.
Note that `--format=%(raw)` can not be used with `--python`, `--shell`, `--tcl`,
-`--perl` because the host language may not support arbitrary binary data in the
+because the host language may not support arbitrary binary data in the
variables of its string type.
The message in a commit or a tag object is `contents`, from which
@@ -471,6 +471,23 @@ void perl_quote_buf(struct strbuf *sb, const char *src)
strbuf_addch(sb, sq);
}
+void perl_quote_buf_with_len(struct strbuf *sb, const char *src, size_t len)
+{
+ const char sq = '\'';
+ const char bq = '\\';
+ const char *c = src;
+ const char *end = src + len;
+
+ strbuf_addch(sb, sq);
+ while (c != end) {
+ if (*c == sq || *c == bq)
+ strbuf_addch(sb, bq);
+ strbuf_addch(sb, *c);
+ c++;
+ }
+ strbuf_addch(sb, sq);
+}
+
void python_quote_buf(struct strbuf *sb, const char *src)
{
const char sq = '\'';
@@ -94,6 +94,7 @@ char *quote_path(const char *in, const char *prefix, struct strbuf *out, unsigne
/* quoting as a string literal for other languages */
void perl_quote_buf(struct strbuf *sb, const char *src);
+void perl_quote_buf_with_len(struct strbuf *sb, const char *src, size_t len);
void python_quote_buf(struct strbuf *sb, const char *src);
void tcl_quote_buf(struct strbuf *sb, const char *src);
void basic_regex_quote_buf(struct strbuf *sb, const char *src);
@@ -742,7 +742,10 @@ static void quote_formatting(struct strbuf *s, const char *str, size_t len, int
sq_quote_buf(s, str);
break;
case QUOTE_PERL:
- perl_quote_buf(s, str);
+ if (len != ATOM_VALUE_S_SIZE_INIT)
+ perl_quote_buf_with_len(s, str, len);
+ else
+ perl_quote_buf(s, str);
break;
case QUOTE_PYTHON:
python_quote_buf(s, str);
@@ -1006,10 +1009,14 @@ int verify_ref_format(struct ref_format *format)
at = parse_ref_filter_atom(format, sp + 2, ep, &err);
if (at < 0)
die("%s", err.buf);
- if (format->quote_style && used_atom[at].atom_type == ATOM_RAW &&
- used_atom[at].u.raw_data.option == RAW_BARE)
+
+ if ((format->quote_style == QUOTE_PYTHON ||
+ format->quote_style == QUOTE_SHELL ||
+ format->quote_style == QUOTE_TCL) &&
+ used_atom[at].atom_type == ATOM_RAW &&
+ used_atom[at].u.raw_data.option == RAW_BARE)
die(_("--format=%.*s cannot be used with"
- "--python, --shell, --tcl, --perl"), (int)(ep - sp - 2), sp + 2);
+ "--python, --shell, --tcl"), (int)(ep - sp - 2), sp + 2);
cp = ep + 1;
if (skip_prefix(used_atom[at].name, "color:", &color))
@@ -915,8 +915,23 @@ test_expect_success '%(raw) with --tcl must fail' '
test_must_fail git for-each-ref --format="%(raw)" --tcl
'
-test_expect_success '%(raw) with --perl must fail' '
- test_must_fail git for-each-ref --format="%(raw)" --perl
+test_expect_success '%(raw) with --perl' '
+ git for-each-ref --format="\$name= %(raw);
+print \"\$name\"" refs/myblobs/blob1 --perl | perl > actual &&
+ cmp blob1 actual &&
+ git for-each-ref --format="\$name= %(raw);
+print \"\$name\"" refs/myblobs/blob3 --perl | perl > actual &&
+ cmp blob3 actual &&
+ git for-each-ref --format="\$name= %(raw);
+print \"\$name\"" refs/myblobs/blob8 --perl | perl > actual &&
+ cmp blob8 actual &&
+ git for-each-ref --format="\$name= %(raw);
+print \"\$name\"" refs/myblobs/first --perl | perl > actual &&
+ cmp one actual &&
+ git cat-file tree refs/mytrees/first > expected &&
+ git for-each-ref --format="\$name= %(raw);
+print \"\$name\"" refs/mytrees/first --perl | perl > actual &&
+ cmp expected actual
'
test_expect_success '%(raw) with --shell must fail' '