2008-04-23 21:17:43 +02:00
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
test_description='git cat-file'
|
|
|
|
|
|
|
|
. ./test-lib.sh
|
|
|
|
|
|
|
|
echo_without_newline () {
|
|
|
|
printf '%s' "$*"
|
|
|
|
}
|
|
|
|
|
|
|
|
strlen () {
|
|
|
|
echo_without_newline "$1" | wc -c | sed -e 's/^ *//'
|
|
|
|
}
|
|
|
|
|
|
|
|
maybe_remove_timestamp () {
|
|
|
|
if test -z "$2"; then
|
|
|
|
echo_without_newline "$1"
|
|
|
|
else
|
|
|
|
echo_without_newline "$(printf '%s\n' "$1" | sed -e 's/ [0-9][0-9]* [-+][0-9][0-9][0-9][0-9]$//')"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
run_tests () {
|
|
|
|
type=$1
|
|
|
|
sha1=$2
|
|
|
|
size=$3
|
|
|
|
content=$4
|
|
|
|
pretty_content=$5
|
|
|
|
no_ts=$6
|
|
|
|
|
2008-04-23 21:17:47 +02:00
|
|
|
batch_output="$sha1 $type $size
|
|
|
|
$content"
|
|
|
|
|
2008-04-23 21:17:43 +02:00
|
|
|
test_expect_success "$type exists" '
|
|
|
|
git cat-file -e $sha1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success "Type of $type is correct" '
|
2013-07-10 13:36:43 +02:00
|
|
|
echo $type >expect &&
|
|
|
|
git cat-file -t $sha1 >actual &&
|
|
|
|
test_cmp expect actual
|
2008-04-23 21:17:43 +02:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success "Size of $type is correct" '
|
2013-07-10 13:36:43 +02:00
|
|
|
echo $size >expect &&
|
|
|
|
git cat-file -s $sha1 >actual &&
|
|
|
|
test_cmp expect actual
|
2008-04-23 21:17:43 +02:00
|
|
|
'
|
|
|
|
|
|
|
|
test -z "$content" ||
|
|
|
|
test_expect_success "Content of $type is correct" '
|
2013-07-10 13:36:43 +02:00
|
|
|
maybe_remove_timestamp "$content" $no_ts >expect &&
|
|
|
|
maybe_remove_timestamp "$(git cat-file $type $sha1)" $no_ts >actual &&
|
|
|
|
test_cmp expect actual
|
2008-04-23 21:17:43 +02:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success "Pretty content of $type is correct" '
|
2013-07-10 13:36:43 +02:00
|
|
|
maybe_remove_timestamp "$pretty_content" $no_ts >expect &&
|
|
|
|
maybe_remove_timestamp "$(git cat-file -p $sha1)" $no_ts >actual &&
|
|
|
|
test_cmp expect actual
|
2008-04-23 21:17:43 +02:00
|
|
|
'
|
2008-04-23 21:17:46 +02:00
|
|
|
|
2008-04-23 21:17:47 +02:00
|
|
|
test -z "$content" ||
|
|
|
|
test_expect_success "--batch output of $type is correct" '
|
2013-07-10 13:36:43 +02:00
|
|
|
maybe_remove_timestamp "$batch_output" $no_ts >expect &&
|
|
|
|
maybe_remove_timestamp "$(echo $sha1 | git cat-file --batch)" $no_ts >actual &&
|
|
|
|
test_cmp expect actual
|
2008-04-23 21:17:47 +02:00
|
|
|
'
|
|
|
|
|
2008-04-23 21:17:46 +02:00
|
|
|
test_expect_success "--batch-check output of $type is correct" '
|
2013-07-10 13:36:43 +02:00
|
|
|
echo "$sha1 $type $size" >expect &&
|
|
|
|
echo_without_newline $sha1 | git cat-file --batch-check >actual &&
|
|
|
|
test_cmp expect actual
|
2008-04-23 21:17:46 +02:00
|
|
|
'
|
2013-07-10 13:45:47 +02:00
|
|
|
|
|
|
|
test_expect_success "custom --batch-check format" '
|
|
|
|
echo "$type $sha1" >expect &&
|
|
|
|
echo $sha1 | git cat-file --batch-check="%(objecttype) %(objectname)" >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
cat-file: only split on whitespace when %(rest) is used
Commit c334b87b (cat-file: split --batch input lines on whitespace,
2013-07-11) taught `cat-file --batch-check` to split input lines on
the first whitespace, and stash everything after the first token
into the %(rest) output format element. It claimed:
Object names cannot contain spaces, so any input with
spaces would have resulted in a "missing" line.
But that is not correct. Refs, object sha1s, and various peeling
suffixes cannot contain spaces, but some object names can. In
particular:
1. Tree paths like "[<tree>]:path with whitespace"
2. Reflog specifications like "@{2 days ago}"
3. Commit searches like "rev^{/grep me}" or ":/grep me"
To remain backwards compatible, we cannot split on whitespace by
default, hence we will ship 1.8.4 with the commit reverted.
Resurrect its attempt but in a weaker form; only do the splitting
when "%(rest)" is used in the output format. Since that element did
not exist at all before c334b87, old scripts cannot be affected.
The existence of object names with spaces does mean that you
cannot reliably do:
echo ":path with space and other data" |
git cat-file --batch-check="%(objectname) %(rest)"
as it would split the path and feed only ":path" to get_sha1. But
that command is nonsensical. If you wanted to see "and other data"
in "%(rest)", git cannot possibly know where the filename ends and
the "rest" begins.
It might be more robust to have something like "-z" to separate the
input elements. But this patch is still a reasonable step before
having that. It makes the easy cases easy; people who do not care
about %(rest) do not have to consider it, and the %(rest) code
handles the spaces and newlines of "rev-list --objects" correctly.
Hard cases remain hard but possible (if you might get whitespace in
your input, you do not get to use %(rest) and must split and join
the output yourself using more flexible tools). And most
importantly, it does not preclude us from having different splitting
rules later if a "-z" (or similar) option is added. So we can make
the hard cases easier later, if we choose to.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-08-02 13:59:07 +02:00
|
|
|
|
|
|
|
test_expect_success '--batch-check with %(rest)' '
|
|
|
|
echo "$type this is some extra content" >expect &&
|
|
|
|
echo "$sha1 this is some extra content" |
|
|
|
|
git cat-file --batch-check="%(objecttype) %(rest)" >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
cat-file: handle --batch format with missing type/size
Commit 98e2092 taught cat-file to stream blobs with --batch,
which requires that we look up the object type before
loading it into memory. As a result, we now print the
object header from information in sha1_object_info, and the
actual contents from the read_sha1_file. We double-check
that the information we printed in the header matches the
content we are about to show.
Later, commit 93d2a60 allowed custom header lines for
--batch, and commit 5b08640 made type lookups optional. As a
result, specifying a header line without the type or size
means that we will not look up those items at all.
This causes our double-checking to erroneously die with an
error; we think the type or size has changed, when in fact
it was simply left at "0".
For the size, we can fix this by only doing the consistency
double-check when we have retrieved the size via
sha1_object_info. In the case that we have not retrieved the
value, that means we also did not print it, so there is
nothing for us to check that we are consistent with.
We could do the same for the type. However, besides our
consistency check, we also care about the type in deciding
whether to stream or not. So instead of handling the case
where we do not know the type, this patch instead makes sure
that we always trigger a type lookup when we are printing,
so that even a format without the type will stream as we
would in the normal case.
Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-12-12 00:15:50 +01:00
|
|
|
|
|
|
|
test -z "$content" ||
|
|
|
|
test_expect_success "--batch without type ($type)" '
|
|
|
|
{
|
|
|
|
echo "$size" &&
|
|
|
|
maybe_remove_timestamp "$content" $no_ts
|
|
|
|
} >expect &&
|
|
|
|
echo $sha1 | git cat-file --batch="%(objectsize)" >actual.full &&
|
|
|
|
maybe_remove_timestamp "$(cat actual.full)" $no_ts >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test -z "$content" ||
|
|
|
|
test_expect_success "--batch without size ($type)" '
|
|
|
|
{
|
|
|
|
echo "$type" &&
|
|
|
|
maybe_remove_timestamp "$content" $no_ts
|
|
|
|
} >expect &&
|
|
|
|
echo $sha1 | git cat-file --batch="%(objecttype)" >actual.full &&
|
|
|
|
maybe_remove_timestamp "$(cat actual.full)" $no_ts >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
2008-04-23 21:17:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
hello_content="Hello World"
|
|
|
|
hello_size=$(strlen "$hello_content")
|
|
|
|
hello_sha1=$(echo_without_newline "$hello_content" | git hash-object --stdin)
|
|
|
|
|
|
|
|
test_expect_success "setup" '
|
|
|
|
echo_without_newline "$hello_content" > hello &&
|
|
|
|
git update-index --add hello
|
|
|
|
'
|
|
|
|
|
|
|
|
run_tests 'blob' $hello_sha1 $hello_size "$hello_content" "$hello_content"
|
|
|
|
|
cat-file: only split on whitespace when %(rest) is used
Commit c334b87b (cat-file: split --batch input lines on whitespace,
2013-07-11) taught `cat-file --batch-check` to split input lines on
the first whitespace, and stash everything after the first token
into the %(rest) output format element. It claimed:
Object names cannot contain spaces, so any input with
spaces would have resulted in a "missing" line.
But that is not correct. Refs, object sha1s, and various peeling
suffixes cannot contain spaces, but some object names can. In
particular:
1. Tree paths like "[<tree>]:path with whitespace"
2. Reflog specifications like "@{2 days ago}"
3. Commit searches like "rev^{/grep me}" or ":/grep me"
To remain backwards compatible, we cannot split on whitespace by
default, hence we will ship 1.8.4 with the commit reverted.
Resurrect its attempt but in a weaker form; only do the splitting
when "%(rest)" is used in the output format. Since that element did
not exist at all before c334b87, old scripts cannot be affected.
The existence of object names with spaces does mean that you
cannot reliably do:
echo ":path with space and other data" |
git cat-file --batch-check="%(objectname) %(rest)"
as it would split the path and feed only ":path" to get_sha1. But
that command is nonsensical. If you wanted to see "and other data"
in "%(rest)", git cannot possibly know where the filename ends and
the "rest" begins.
It might be more robust to have something like "-z" to separate the
input elements. But this patch is still a reasonable step before
having that. It makes the easy cases easy; people who do not care
about %(rest) do not have to consider it, and the %(rest) code
handles the spaces and newlines of "rev-list --objects" correctly.
Hard cases remain hard but possible (if you might get whitespace in
your input, you do not get to use %(rest) and must split and join
the output yourself using more flexible tools). And most
importantly, it does not preclude us from having different splitting
rules later if a "-z" (or similar) option is added. So we can make
the hard cases easier later, if we choose to.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-08-02 13:59:07 +02:00
|
|
|
test_expect_success '--batch-check without %(rest) considers whole line' '
|
|
|
|
echo "$hello_sha1 blob $hello_size" >expect &&
|
|
|
|
git update-index --add --cacheinfo 100644 $hello_sha1 "white space" &&
|
|
|
|
test_when_finished "git update-index --remove \"white space\"" &&
|
|
|
|
echo ":white space" | git cat-file --batch-check >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2008-04-23 21:17:43 +02:00
|
|
|
tree_sha1=$(git write-tree)
|
|
|
|
tree_size=33
|
|
|
|
tree_pretty_content="100644 blob $hello_sha1 hello"
|
|
|
|
|
|
|
|
run_tests 'tree' $tree_sha1 $tree_size "" "$tree_pretty_content"
|
|
|
|
|
2013-04-12 00:36:10 +02:00
|
|
|
commit_message="Initial commit"
|
2008-04-23 21:17:43 +02:00
|
|
|
commit_sha1=$(echo_without_newline "$commit_message" | git commit-tree $tree_sha1)
|
2013-04-12 00:36:10 +02:00
|
|
|
commit_size=177
|
2008-04-23 21:17:43 +02:00
|
|
|
commit_content="tree $tree_sha1
|
|
|
|
author $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> 0000000000 +0000
|
|
|
|
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 0000000000 +0000
|
|
|
|
|
|
|
|
$commit_message"
|
|
|
|
|
|
|
|
run_tests 'commit' $commit_sha1 $commit_size "$commit_content" "$commit_content" 1
|
|
|
|
|
|
|
|
tag_header_without_timestamp="object $hello_sha1
|
|
|
|
type blob
|
|
|
|
tag hellotag
|
|
|
|
tagger $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
|
|
|
|
tag_description="This is a tag"
|
|
|
|
tag_content="$tag_header_without_timestamp 0000000000 +0000
|
|
|
|
|
|
|
|
$tag_description"
|
|
|
|
|
|
|
|
tag_sha1=$(echo_without_newline "$tag_content" | git mktag)
|
|
|
|
tag_size=$(strlen "$tag_content")
|
|
|
|
|
cat-file: print tags raw for "cat-file -p"
When "cat-file -p" prints commits, it shows them in their
raw format, since git's format is already human-readable.
For tags, however, we print the whole thing raw except for
one thing: we convert the timestamp on the tagger line into a
human-readable date.
This dates all the way back to a0f15fa (Pretty-print tagger
dates, 2006-03-01). At that time there was no other way to
pretty-print a tag. These days, however, neither of those
matters much. The normal way to pretty-print a tag is with
"git show", which is much more flexible than "cat-file -p".
Commit a0f15fa also built "verify-tag --verbose" (and
subsequently "tag -v") around the "cat-file -p" output.
However, that behavior was lost in commit 62e09ce (Make git
tag a builtin, 2007-07-20), and we went back to printing
the raw tag contents. Nobody seems to have noticed the bug
since then (and it is arguably a saner behavior anyway, as
it shows the actual bytes for which we verified the
signature).
Let's drop the tagger-date formatting for "cat-file -p". It
makes us more consistent with cat-file's commit
pretty-printer, and as a bonus, we can drop the hand-rolled
tag parsing code in cat-file (which happened to behave
inconsistently with the tag pretty-printing code elsewhere).
This is a change of output format, so it's possible that
some callers could considered this a regression. However,
the original behavior was arguably a bug (due to the
inconsistency with commits), likely nobody was relying on it
(even we do not use it ourselves these days), and anyone
relying on the "-p" pretty-printer should be able to expect
a change in the output format (i.e., while "cat-file" is
plumbing, the output format of "-p" was never guaranteed to
be stable).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-04-17 23:00:48 +02:00
|
|
|
run_tests 'tag' $tag_sha1 $tag_size "$tag_content" "$tag_content" 1
|
2008-04-23 21:17:43 +02:00
|
|
|
|
|
|
|
test_expect_success \
|
|
|
|
"Reach a blob from a tag pointing to it" \
|
|
|
|
"test '$hello_content' = \"\$(git cat-file blob $tag_sha1)\""
|
|
|
|
|
2008-04-23 21:17:47 +02:00
|
|
|
for batch in batch batch-check
|
2008-04-23 21:17:46 +02:00
|
|
|
do
|
2008-04-23 21:17:47 +02:00
|
|
|
for opt in t s e p
|
|
|
|
do
|
|
|
|
test_expect_success "Passing -$opt with --$batch fails" '
|
|
|
|
test_must_fail git cat-file --$batch -$opt $hello_sha1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success "Passing --$batch with -$opt fails" '
|
|
|
|
test_must_fail git cat-file -$opt --$batch $hello_sha1
|
|
|
|
'
|
|
|
|
done
|
|
|
|
|
|
|
|
test_expect_success "Passing <type> with --$batch fails" '
|
|
|
|
test_must_fail git cat-file --$batch blob $hello_sha1
|
2008-04-23 21:17:46 +02:00
|
|
|
'
|
|
|
|
|
2008-04-23 21:17:47 +02:00
|
|
|
test_expect_success "Passing --$batch with <type> fails" '
|
|
|
|
test_must_fail git cat-file blob --$batch $hello_sha1
|
2008-04-23 21:17:46 +02:00
|
|
|
'
|
|
|
|
|
2008-04-23 21:17:47 +02:00
|
|
|
test_expect_success "Passing sha1 with --$batch fails" '
|
|
|
|
test_must_fail git cat-file --$batch $hello_sha1
|
|
|
|
'
|
|
|
|
done
|
2008-04-23 21:17:46 +02:00
|
|
|
|
2008-06-09 02:02:21 +02:00
|
|
|
test_expect_success "--batch-check for a non-existent named object" '
|
|
|
|
test "foobar42 missing
|
|
|
|
foobar84 missing" = \
|
|
|
|
"$( ( echo foobar42; echo_without_newline foobar84; ) | git cat-file --batch-check)"
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success "--batch-check for a non-existent hash" '
|
|
|
|
test "0000000000000000000000000000000000000042 missing
|
|
|
|
0000000000000000000000000000000000000084 missing" = \
|
|
|
|
"$( ( echo 0000000000000000000000000000000000000042;
|
|
|
|
echo_without_newline 0000000000000000000000000000000000000084; ) \
|
|
|
|
| git cat-file --batch-check)"
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success "--batch for an existent and a non-existent hash" '
|
|
|
|
test "$tag_sha1 tag $tag_size
|
|
|
|
$tag_content
|
|
|
|
0000000000000000000000000000000000000000 missing" = \
|
|
|
|
"$( ( echo $tag_sha1;
|
|
|
|
echo_without_newline 0000000000000000000000000000000000000000; ) \
|
|
|
|
| git cat-file --batch)"
|
2008-04-23 21:17:46 +02:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success "--batch-check for an emtpy line" '
|
|
|
|
test " missing" = "$(echo | git cat-file --batch-check)"
|
|
|
|
'
|
|
|
|
|
2013-11-06 19:00:57 +01:00
|
|
|
test_expect_success 'empty --batch-check notices missing object' '
|
|
|
|
echo "$_z40 missing" >expect &&
|
|
|
|
echo "$_z40" | git cat-file --batch-check="" >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2008-04-23 21:17:47 +02:00
|
|
|
batch_input="$hello_sha1
|
|
|
|
$commit_sha1
|
|
|
|
$tag_sha1
|
|
|
|
deadbeef
|
|
|
|
|
|
|
|
"
|
|
|
|
|
|
|
|
batch_output="$hello_sha1 blob $hello_size
|
|
|
|
$hello_content
|
|
|
|
$commit_sha1 commit $commit_size
|
|
|
|
$commit_content
|
|
|
|
$tag_sha1 tag $tag_size
|
|
|
|
$tag_content
|
|
|
|
deadbeef missing
|
|
|
|
missing"
|
|
|
|
|
2008-05-23 16:19:43 +02:00
|
|
|
test_expect_success '--batch with multiple sha1s gives correct format' '
|
|
|
|
test "$(maybe_remove_timestamp "$batch_output" 1)" = "$(maybe_remove_timestamp "$(echo_without_newline "$batch_input" | git cat-file --batch)" 1)"
|
|
|
|
'
|
2008-04-23 21:17:47 +02:00
|
|
|
|
2008-04-23 21:17:46 +02:00
|
|
|
batch_check_input="$hello_sha1
|
|
|
|
$tree_sha1
|
|
|
|
$commit_sha1
|
|
|
|
$tag_sha1
|
|
|
|
deadbeef
|
|
|
|
|
|
|
|
"
|
|
|
|
|
|
|
|
batch_check_output="$hello_sha1 blob $hello_size
|
|
|
|
$tree_sha1 tree $tree_size
|
|
|
|
$commit_sha1 commit $commit_size
|
|
|
|
$tag_sha1 tag $tag_size
|
|
|
|
deadbeef missing
|
|
|
|
missing"
|
|
|
|
|
|
|
|
test_expect_success "--batch-check with multiple sha1s gives correct format" '
|
|
|
|
test "$batch_check_output" = \
|
|
|
|
"$(echo_without_newline "$batch_check_input" | git cat-file --batch-check)"
|
|
|
|
'
|
|
|
|
|
2008-04-23 21:17:43 +02:00
|
|
|
test_done
|