@@ -260,7 +260,15 @@ contents:signature::
contents:lines=N::
The first `N` lines of the message of the commit or tag message.
-Note: blob and tree objects only support `%(contents)` and `%(contents:size)`.
+contents:raw::
+ The raw data of the object. For blob and tree, it priont all object data,
+ its output is equivalent to `%(contents)`; For commit and tag, it not only
+ print objects’ messages (as `%(contents)` does), but also print objects
+ headers, like the "tree XXX", "parent YYY", etc lines in commits, and the
+ "object OOO", "type TTT", etc lines in tags.
+
+Note: blob and tree objects only support `%(contents)`, `%(contents:raw)` and
+`%(contents:size)`.
Additionally, the trailers as interpreted by linkgit:git-interpret-trailers[1]
are obtained as `trailers[:options]` (or by using the historical alias
@@ -134,7 +134,7 @@ static struct used_atom {
} remote_ref;
struct {
enum { C_BARE, C_BODY, C_BODY_DEP, C_LENGTH, C_LINES,
- C_SIG, C_SUB, C_SUB_SANITIZE, C_TRAILERS } option;
+ C_RAW, C_SIG, C_SUB, C_SUB_SANITIZE, C_TRAILERS } option;
struct process_trailer_options trailer_opts;
unsigned int nlines;
} contents;
@@ -347,6 +347,8 @@ static int contents_atom_parser(const struct ref_format *format, struct used_ato
{
if (!arg)
atom->u.contents.option = C_BARE;
+ else if (!strcmp(arg,"raw"))
+ atom->u.contents.option = C_RAW;
else if (!strcmp(arg, "body"))
atom->u.contents.option = C_BODY;
else if (!strcmp(arg, "size"))
@@ -1387,11 +1389,16 @@ static void grab_contents(struct atom_value *val, int deref, void *buf,
v->s = strbuf_detach(&s, NULL);
} else if (atom->u.contents.option == C_BARE)
v->s = xstrdup(subpos);
+ else if (atom->u.contents.option == C_RAW) {
+ v->s_size = buf_size;
+ v->s = xmemdupz(buf, buf_size);
+ }
break;
}
case OBJ_BLOB:
case OBJ_TREE: {
- if (atom->u.contents.option == C_BARE) {
+ if (atom->u.contents.option == C_BARE ||
+ atom->u.contents.option == C_RAW) {
v->s_size = buf_size;
v->s = xmemdupz(buf, buf_size);
} else if (atom->u.contents.option == C_LENGTH)
@@ -159,6 +159,8 @@ test_atom head subject 'Initial'
test_atom head subject:sanitize 'Initial'
test_atom head contents:subject 'Initial'
test_atom head body ''
+test_atom head contents:raw "$(git cat-file commit refs/heads/main)
+"
test_atom head contents:body ''
test_atom head contents:signature ''
test_atom head contents 'Initial
@@ -688,6 +690,18 @@ test_atom refs/tags/signed-empty contents:body ''
test_atom refs/tags/signed-empty contents:signature "$sig"
test_atom refs/tags/signed-empty contents "$sig"
+test_expect_success 'basic atom: refs/tags/signed-empty contents:raw' '
+ git cat-file tag refs/tags/signed-empty >expected &&
+ git for-each-ref --format="%(contents:raw)" refs/tags/signed-empty >actual &&
+ sanitize_pgp <expected >expected.clean &&
+ sanitize_pgp <actual >actual.clean &&
+ echo "" >>expected.clean &&
+ test_cmp expected.clean actual.clean
+'
+
+test_atom refs/tags/signed-empty '*contents:raw' "$(git cat-file commit HEAD)
+"
+
test_atom refs/tags/signed-short subject 'subject line'
test_atom refs/tags/signed-short subject:sanitize 'subject-line'
test_atom refs/tags/signed-short contents:subject 'subject line'
@@ -697,6 +711,15 @@ test_atom refs/tags/signed-short contents:signature "$sig"
test_atom refs/tags/signed-short contents "subject line
$sig"
+test_expect_success 'basic atom: refs/tags/signed-short contents:raw' '
+ git cat-file tag refs/tags/signed-short >expected &&
+ git for-each-ref --format="%(contents:raw)" refs/tags/signed-short >actual &&
+ sanitize_pgp <expected >expected.clean &&
+ sanitize_pgp <actual >actual.clean &&
+ echo "" >>expected.clean &&
+ test_cmp expected.clean actual.clean
+'
+
test_atom refs/tags/signed-long subject 'subject line'
test_atom refs/tags/signed-long subject:sanitize 'subject-line'
test_atom refs/tags/signed-long contents:subject 'subject line'
@@ -710,6 +733,15 @@ test_atom refs/tags/signed-long contents "subject line
body contents
$sig"
+test_expect_success 'basic atom: refs/tags/signed-long contents:raw' '
+ git cat-file tag refs/tags/signed-long >expected &&
+ git for-each-ref --format="%(contents:raw)" refs/tags/signed-long >actual &&
+ sanitize_pgp <expected >expected.clean &&
+ sanitize_pgp <actual >actual.clean &&
+ echo "" >>expected.clean &&
+ test_cmp expected.clean actual.clean
+'
+
test_expect_success 'set up refs pointing to tree and blob' '
git update-ref refs/mytrees/first refs/heads/main^{tree} &&
git update-ref refs/myblobs/first refs/heads/main:one
@@ -731,6 +763,14 @@ test_expect_success 'basic atom: refs/mytrees/first contents' '
test_cmp size_expected actual
'
+test_expect_success 'basic atom: refs/mytrees/first contents:raw' '
+ git cat-file tree refs/mytrees/first >expected &&
+ cat expected | wc -c >size_expected &&
+ echo "" >>expected &&
+ git for-each-ref --format="%(contents:raw)" refs/mytrees/first >actual &&
+ test_cmp expected actual
+'
+
test_expect_success 'basic atom: refs/mytrees/first contents with --python' '
cat >expected <<-\EOF &&
0000000 030447 030060 032066 020064 067157 000145 157155 153143
@@ -803,6 +843,14 @@ test_expect_success 'basic atom: refs/myblobs/first contents' '
test_cmp size_expected actual
'
+test_expect_success 'basic atom: refs/myblobs/first contents:raw' '
+ git cat-file blob refs/myblobs/first >expected &&
+ cat expected | wc -c >size_expected &&
+ echo "" >>expected &&
+ git for-each-ref --format="%(contents:raw)" refs/myblobs/first >actual &&
+ test_cmp expected actual
+'
+
test_expect_success 'set up refs pointing to binary blob' '
printf "%b" "a\0b\0c" >blob1 &&
printf "%b" "a\0c\0b" >blob2 &&