Skip to content

Commit 7121c4d

Browse files
adlternativegitster
authored andcommitted
ref-filter: --format=%(raw) support --perl
Because the perl language can handle binary data correctly, add the function perl_quote_buf_with_len(), which can specify the length of the data and prevent the data from being truncated at '\0' to help `--format="%(raw)"` support `--perl`. Reviewed-by: Jacob Keller <[email protected]> Helped-by: Ævar Arnfjörð Bjarmason <[email protected]> Signed-off-by: ZheNing Hu <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent bd0708c commit 7121c4d

File tree

5 files changed

+48
-8
lines changed

5 files changed

+48
-8
lines changed

Documentation/git-for-each-ref.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,8 @@ raw:size::
241241
The raw data size of the object.
242242

243243
Note that `--format=%(raw)` can not be used with `--python`, `--shell`, `--tcl`,
244-
`--perl` because such language may not support arbitrary binary data in their
245-
string variable type.
244+
because such language may not support arbitrary binary data in their string
245+
variable type.
246246

247247
The message in a commit or a tag object is `contents`, from which
248248
`contents:<part>` can be used to extract various parts out of:

quote.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,23 @@ void perl_quote_buf(struct strbuf *sb, const char *src)
471471
strbuf_addch(sb, sq);
472472
}
473473

474+
void perl_quote_buf_with_len(struct strbuf *sb, const char *src, size_t len)
475+
{
476+
const char sq = '\'';
477+
const char bq = '\\';
478+
const char *c = src;
479+
const char *end = src + len;
480+
481+
strbuf_addch(sb, sq);
482+
while (c != end) {
483+
if (*c == sq || *c == bq)
484+
strbuf_addch(sb, bq);
485+
strbuf_addch(sb, *c);
486+
c++;
487+
}
488+
strbuf_addch(sb, sq);
489+
}
490+
474491
void python_quote_buf(struct strbuf *sb, const char *src)
475492
{
476493
const char sq = '\'';

quote.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ char *quote_path(const char *in, const char *prefix, struct strbuf *out, unsigne
9494

9595
/* quoting as a string literal for other languages */
9696
void perl_quote_buf(struct strbuf *sb, const char *src);
97+
void perl_quote_buf_with_len(struct strbuf *sb, const char *src, size_t len);
9798
void python_quote_buf(struct strbuf *sb, const char *src);
9899
void tcl_quote_buf(struct strbuf *sb, const char *src);
99100
void basic_regex_quote_buf(struct strbuf *sb, const char *src);

ref-filter.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -746,7 +746,10 @@ static void quote_formatting(struct strbuf *s, const char *str, ssize_t len, int
746746
sq_quote_buf(s, str);
747747
break;
748748
case QUOTE_PERL:
749-
perl_quote_buf(s, str);
749+
if (len < 0)
750+
perl_quote_buf(s, str);
751+
else
752+
perl_quote_buf_with_len(s, str, len);
750753
break;
751754
case QUOTE_PYTHON:
752755
python_quote_buf(s, str);
@@ -1009,10 +1012,14 @@ int verify_ref_format(struct ref_format *format)
10091012
at = parse_ref_filter_atom(format, sp + 2, ep, &err);
10101013
if (at < 0)
10111014
die("%s", err.buf);
1012-
if (format->quote_style && used_atom[at].atom_type == ATOM_RAW &&
1013-
used_atom[at].u.raw_data.option == RAW_BARE)
1015+
1016+
if ((format->quote_style == QUOTE_PYTHON ||
1017+
format->quote_style == QUOTE_SHELL ||
1018+
format->quote_style == QUOTE_TCL) &&
1019+
used_atom[at].atom_type == ATOM_RAW &&
1020+
used_atom[at].u.raw_data.option == RAW_BARE)
10141021
die(_("--format=%.*s cannot be used with"
1015-
"--python, --shell, --tcl, --perl"), (int)(ep - sp - 2), sp + 2);
1022+
"--python, --shell, --tcl"), (int)(ep - sp - 2), sp + 2);
10161023
cp = ep + 1;
10171024

10181025
if (skip_prefix(used_atom[at].name, "color:", &color))

t/t6300-for-each-ref.sh

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -915,8 +915,23 @@ test_expect_success '%(raw) with --tcl must fail' '
915915
test_must_fail git for-each-ref --format="%(raw)" --tcl
916916
'
917917

918-
test_expect_success '%(raw) with --perl must fail' '
919-
test_must_fail git for-each-ref --format="%(raw)" --perl
918+
test_expect_success '%(raw) with --perl' '
919+
git for-each-ref --format="\$name= %(raw);
920+
print \"\$name\"" refs/myblobs/blob1 --perl | perl >actual &&
921+
cmp blob1 actual &&
922+
git for-each-ref --format="\$name= %(raw);
923+
print \"\$name\"" refs/myblobs/blob3 --perl | perl >actual &&
924+
cmp blob3 actual &&
925+
git for-each-ref --format="\$name= %(raw);
926+
print \"\$name\"" refs/myblobs/blob8 --perl | perl >actual &&
927+
cmp blob8 actual &&
928+
git for-each-ref --format="\$name= %(raw);
929+
print \"\$name\"" refs/myblobs/first --perl | perl >actual &&
930+
cmp one actual &&
931+
git cat-file tree refs/mytrees/first > expected &&
932+
git for-each-ref --format="\$name= %(raw);
933+
print \"\$name\"" refs/mytrees/first --perl | perl >actual &&
934+
cmp expected actual
920935
'
921936

922937
test_expect_success '%(raw) with --shell must fail' '

0 commit comments

Comments
 (0)