2006-03-05 11:13:34 +00:00
|
|
|
# This file isn't used as a test script directly, instead it is
|
2011-04-21 22:07:36 +00:00
|
|
|
# sourced from t8001-annotate.sh and t8002-blame.sh.
|
2006-03-05 11:13:34 +00:00
|
|
|
|
2014-07-17 15:37:05 +00:00
|
|
|
if test_have_prereq MINGW
|
|
|
|
then
|
|
|
|
sanitize_L () {
|
|
|
|
echo "$1" | sed 'sX\(^-L\|,\)\^\?/X&\\;*Xg'
|
|
|
|
}
|
|
|
|
else
|
|
|
|
sanitize_L () {
|
|
|
|
echo "$1"
|
|
|
|
}
|
|
|
|
fi
|
|
|
|
|
2006-03-06 06:07:37 +00:00
|
|
|
check_count () {
|
2013-07-17 21:25:28 +00:00
|
|
|
head= &&
|
2013-07-17 21:25:30 +00:00
|
|
|
file='file' &&
|
2013-07-17 21:25:29 +00:00
|
|
|
options= &&
|
|
|
|
while :
|
|
|
|
do
|
|
|
|
case "$1" in
|
|
|
|
-h) head="$2"; shift; shift ;;
|
2013-07-17 21:25:30 +00:00
|
|
|
-f) file="$2"; shift; shift ;;
|
2014-07-17 15:37:05 +00:00
|
|
|
-L*) options="$options $(sanitize_L "$1")"; shift ;;
|
2013-07-17 21:25:29 +00:00
|
|
|
-*) options="$options $1"; shift ;;
|
|
|
|
*) break ;;
|
|
|
|
esac
|
|
|
|
done &&
|
2013-07-17 21:25:30 +00:00
|
|
|
echo "$PROG $options $file $head" >&4 &&
|
|
|
|
$PROG $options $file $head >actual &&
|
2013-07-17 21:25:28 +00:00
|
|
|
perl -e '
|
2006-03-06 06:07:37 +00:00
|
|
|
my %expect = (@ARGV);
|
2010-10-16 11:09:20 +00:00
|
|
|
my %count = map { $_ => 0 } keys %expect;
|
2006-03-06 06:07:37 +00:00
|
|
|
while (<STDIN>) {
|
|
|
|
if (/^[0-9a-f]+\t\(([^\t]+)\t/) {
|
|
|
|
my $author = $1;
|
|
|
|
for ($author) { s/^\s*//; s/\s*$//; }
|
2010-10-16 11:09:20 +00:00
|
|
|
$count{$author}++;
|
2006-03-06 06:07:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
my $bad = 0;
|
|
|
|
while (my ($author, $count) = each %count) {
|
|
|
|
my $ok;
|
2010-10-16 11:09:20 +00:00
|
|
|
my $value = 0;
|
|
|
|
$value = $expect{$author} if defined $expect{$author};
|
|
|
|
if ($value != $count) {
|
2006-03-06 06:07:37 +00:00
|
|
|
$bad = 1;
|
|
|
|
$ok = "bad";
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$ok = "good";
|
|
|
|
}
|
2010-10-16 11:09:20 +00:00
|
|
|
print STDERR "Author $author (expected $value, attributed $count) $ok\n";
|
2006-03-06 06:07:37 +00:00
|
|
|
}
|
|
|
|
exit($bad);
|
2013-07-17 21:25:28 +00:00
|
|
|
' "$@" <actual
|
2006-03-06 06:07:37 +00:00
|
|
|
}
|
|
|
|
|
2013-07-17 21:25:28 +00:00
|
|
|
test_expect_success 'setup A lines' '
|
|
|
|
echo "1A quick brown fox jumps over the" >file &&
|
|
|
|
echo "lazy dog" >>file &&
|
|
|
|
git add file &&
|
|
|
|
GIT_AUTHOR_NAME="A" GIT_AUTHOR_EMAIL="A@test.git" \
|
|
|
|
git commit -a -m "Initial."
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame 1 author' '
|
|
|
|
check_count A 2
|
|
|
|
'
|
|
|
|
|
blame: default to HEAD in a bare repo when no start commit is given
When 'git blame' is invoked without specifying the commit to start
blaming from, it starts from the given file's state in the work tree.
However, when invoked in a bare repository without a start commit,
then there is no work tree state to start from, and it dies with the
following error message:
$ git rev-parse --is-bare-repository
true
$ git blame file.c
fatal: this operation must be run in a work tree
This is misleading, because it implies that 'git blame' doesn't work
in bare repositories at all, but it does, in fact, work just fine when
it is given a commit to start from.
We could improve the error message, of course, but let's just default
to HEAD in a bare repository instead, as most likely that is what the
user wanted anyway (if they wanted to start from an other commit, then
they would have specified that in the first place).
'git annotate' is just a thin wrapper around 'git blame', so in the
same situation it printed the same misleading error message, and this
patch fixes it, too.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-04-07 23:43:27 +00:00
|
|
|
test_expect_success 'blame in a bare repo without starting commit' '
|
|
|
|
git clone --bare . bare.git &&
|
|
|
|
(
|
|
|
|
cd bare.git &&
|
|
|
|
check_count A 2
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
blame: fix object casting regression
Commit 1b0d400 refactored the prepare_final() function so
that it could be reused in multiple places. Originally, the
loop had two outputs: a commit to stuff into sb->final, and
the name of the commit from the rev->pending array.
After the refactor, that loop is put in its own function
with a single return value: the object_array_entry from the
rev->pending array. This contains both the name and the object,
but with one important difference: the object is the
_original_ object found by the revision parser, not the
dereferenced commit. If one feeds a tag to "git blame", we
end up casting the tag object to a "struct commit", which
causes a segfault.
Instead, let's return the commit (properly casted) directly
from the function, and take the "name" as an optional
out-parameter. This does the right thing, and actually
simplifies the callers, who no longer need to cast or
dereference the object_array_entry themselves.
[test case by Max Kirillov <max@max630.net>]
Signed-off-by: Jeff King <peff@peff.net>
2015-11-17 23:22:37 +00:00
|
|
|
test_expect_success 'blame by tag objects' '
|
|
|
|
git tag -m "test tag" testTag &&
|
|
|
|
git tag -m "test tag #2" testTag2 testTag &&
|
|
|
|
check_count -h testTag A 2 &&
|
|
|
|
check_count -h testTag2 A 2
|
|
|
|
'
|
|
|
|
|
2013-07-17 21:25:28 +00:00
|
|
|
test_expect_success 'setup B lines' '
|
|
|
|
echo "2A quick brown fox jumps over the" >>file &&
|
|
|
|
echo "lazy dog" >>file &&
|
|
|
|
GIT_AUTHOR_NAME="B" GIT_AUTHOR_EMAIL="B@test.git" \
|
|
|
|
git commit -a -m "Second."
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame 2 authors' '
|
|
|
|
check_count A 2 B 2
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'setup B1 lines (branch1)' '
|
2020-11-18 23:44:41 +00:00
|
|
|
git checkout -b branch1 main &&
|
2013-07-17 21:25:28 +00:00
|
|
|
echo "3A slow green fox jumps into the" >>file &&
|
|
|
|
echo "well." >>file &&
|
|
|
|
GIT_AUTHOR_NAME="B1" GIT_AUTHOR_EMAIL="B1@test.git" \
|
|
|
|
git commit -a -m "Branch1-1"
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame 2 authors + 1 branch1 author' '
|
|
|
|
check_count A 2 B 2 B1 2
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'setup B2 lines (branch2)' '
|
2020-11-18 23:44:41 +00:00
|
|
|
git checkout -b branch2 main &&
|
2013-07-17 21:25:28 +00:00
|
|
|
sed -e "s/2A quick brown/4A quick brown lazy dog/" <file >file.new &&
|
|
|
|
mv file.new file &&
|
|
|
|
GIT_AUTHOR_NAME="B2" GIT_AUTHOR_EMAIL="B2@test.git" \
|
|
|
|
git commit -a -m "Branch2-1"
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame 2 authors + 1 branch2 author' '
|
|
|
|
check_count A 2 B 1 B2 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'merge branch1 & branch2' '
|
2013-10-31 09:25:33 +00:00
|
|
|
git merge branch1
|
2013-07-17 21:25:28 +00:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame 2 authors + 2 merged-in authors' '
|
|
|
|
check_count A 2 B 1 B1 2 B2 1
|
|
|
|
'
|
|
|
|
|
2015-09-15 10:05:39 +00:00
|
|
|
test_expect_success 'blame --first-parent blames merge for branch1' '
|
|
|
|
check_count --first-parent A 2 B 1 "A U Thor" 2 B2 1
|
|
|
|
'
|
|
|
|
|
2013-07-17 21:25:28 +00:00
|
|
|
test_expect_success 'blame ancestor' '
|
2020-11-18 23:44:41 +00:00
|
|
|
check_count -h main A 2 B 2
|
2013-07-17 21:25:28 +00:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame great-ancestor' '
|
2020-11-18 23:44:41 +00:00
|
|
|
check_count -h main^ A 2
|
2013-07-17 21:25:28 +00:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'setup evil merge' '
|
|
|
|
echo "evil merge." >>file &&
|
|
|
|
git commit -a --amend
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame evil merge' '
|
|
|
|
check_count A 2 B 1 B1 2 B2 1 "A U Thor" 1
|
|
|
|
'
|
|
|
|
|
2013-12-27 20:49:57 +00:00
|
|
|
test_expect_success 'blame huge graft' '
|
|
|
|
test_when_finished "git checkout branch2" &&
|
|
|
|
test_when_finished "rm -f .git/info/grafts" &&
|
|
|
|
graft= &&
|
|
|
|
for i in 0 1 2
|
|
|
|
do
|
|
|
|
for j in 0 1 2 3 4 5 6 7 8 9
|
|
|
|
do
|
|
|
|
git checkout --orphan "$i$j" &&
|
|
|
|
printf "%s\n" "$i" "$j" >file &&
|
|
|
|
test_tick &&
|
|
|
|
GIT_AUTHOR_NAME=$i$j GIT_AUTHOR_EMAIL=$i$j@test.git \
|
|
|
|
git commit -a -m "$i$j" &&
|
|
|
|
commit=$(git rev-parse --verify HEAD) &&
|
2021-12-09 05:11:15 +00:00
|
|
|
graft="$graft$commit " || return 1
|
2013-12-27 20:49:57 +00:00
|
|
|
done
|
|
|
|
done &&
|
|
|
|
printf "%s " $graft >.git/info/grafts &&
|
|
|
|
check_count -h 00 01 1 10 1
|
|
|
|
'
|
|
|
|
|
2013-07-17 21:25:28 +00:00
|
|
|
test_expect_success 'setup incomplete line' '
|
|
|
|
echo "incomplete" | tr -d "\\012" >>file &&
|
|
|
|
GIT_AUTHOR_NAME="C" GIT_AUTHOR_EMAIL="C@test.git" \
|
|
|
|
git commit -a -m "Incomplete"
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame incomplete line' '
|
|
|
|
check_count A 2 B 1 B1 2 B2 1 "A U Thor" 1 C 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'setup edits' '
|
|
|
|
mv file file.orig &&
|
|
|
|
{
|
|
|
|
cat file.orig &&
|
|
|
|
echo
|
|
|
|
} | sed -e "s/^3A/99/" -e "/^1A/d" -e "/^incomplete/d" >file &&
|
|
|
|
echo "incomplete" | tr -d "\\012" >>file &&
|
|
|
|
GIT_AUTHOR_NAME="D" GIT_AUTHOR_EMAIL="D@test.git" \
|
|
|
|
git commit -a -m "edit"
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame edits' '
|
|
|
|
check_count A 1 B 1 B1 1 B2 1 "A U Thor" 1 C 1 D 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'setup obfuscated email' '
|
|
|
|
echo "No robots allowed" >file.new &&
|
|
|
|
cat file >>file.new &&
|
|
|
|
mv file.new file &&
|
|
|
|
GIT_AUTHOR_NAME="E" GIT_AUTHOR_EMAIL="E at test dot git" \
|
|
|
|
git commit -a -m "norobots"
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame obfuscated email' '
|
|
|
|
check_count A 1 B 1 B1 1 B2 1 "A U Thor" 1 C 1 D 1 E 1
|
|
|
|
'
|
2013-07-17 21:25:29 +00:00
|
|
|
|
|
|
|
test_expect_success 'blame -L 1 (all)' '
|
|
|
|
check_count -L1 A 1 B 1 B1 1 B2 1 "A U Thor" 1 C 1 D 1 E 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L , (all)' '
|
|
|
|
check_count -L, A 1 B 1 B1 1 B2 1 "A U Thor" 1 C 1 D 1 E 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L X (X to end)' '
|
|
|
|
check_count -L5 B1 1 C 1 D 1 "A U Thor" 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L X, (X to end)' '
|
|
|
|
check_count -L5, B1 1 C 1 D 1 "A U Thor" 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L ,Y (up to Y)' '
|
|
|
|
check_count -L,3 A 1 B2 1 E 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L X,X' '
|
|
|
|
check_count -L3,3 B2 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L X,Y' '
|
|
|
|
check_count -L3,6 B 1 B1 1 B2 1 D 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L Y,X (undocumented)' '
|
|
|
|
check_count -L6,3 B 1 B1 1 B2 1 D 1
|
|
|
|
'
|
|
|
|
|
2013-08-06 13:59:49 +00:00
|
|
|
test_expect_success 'blame -L -X' '
|
2013-08-06 13:59:48 +00:00
|
|
|
test_must_fail $PROG -L-1 file
|
|
|
|
'
|
|
|
|
|
2013-08-06 13:59:49 +00:00
|
|
|
test_expect_success 'blame -L 0' '
|
2013-08-06 13:59:48 +00:00
|
|
|
test_must_fail $PROG -L0 file
|
|
|
|
'
|
|
|
|
|
2013-08-06 13:59:49 +00:00
|
|
|
test_expect_success 'blame -L ,0' '
|
2013-08-06 13:59:48 +00:00
|
|
|
test_must_fail $PROG -L,0 file
|
|
|
|
'
|
|
|
|
|
2013-07-31 08:15:45 +00:00
|
|
|
test_expect_success 'blame -L ,+0' '
|
2013-07-31 08:15:44 +00:00
|
|
|
test_must_fail $PROG -L,+0 file
|
|
|
|
'
|
|
|
|
|
2013-07-31 08:15:43 +00:00
|
|
|
test_expect_success 'blame -L X,+0' '
|
2013-07-31 08:15:42 +00:00
|
|
|
test_must_fail $PROG -L1,+0 file
|
|
|
|
'
|
|
|
|
|
2013-07-17 21:25:29 +00:00
|
|
|
test_expect_success 'blame -L X,+1' '
|
|
|
|
check_count -L3,+1 B2 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L X,+N' '
|
|
|
|
check_count -L3,+4 B 1 B1 1 B2 1 D 1
|
|
|
|
'
|
|
|
|
|
2013-07-31 08:15:45 +00:00
|
|
|
test_expect_success 'blame -L ,-0' '
|
2013-07-31 08:15:44 +00:00
|
|
|
test_must_fail $PROG -L,-0 file
|
|
|
|
'
|
|
|
|
|
2013-07-31 08:15:43 +00:00
|
|
|
test_expect_success 'blame -L X,-0' '
|
2013-07-31 08:15:42 +00:00
|
|
|
test_must_fail $PROG -L1,-0 file
|
|
|
|
'
|
|
|
|
|
2013-07-17 21:25:29 +00:00
|
|
|
test_expect_success 'blame -L X,-1' '
|
|
|
|
check_count -L3,-1 B2 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L X,-N' '
|
|
|
|
check_count -L6,-4 B 1 B1 1 B2 1 D 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L /RE/ (RE to end)' '
|
|
|
|
check_count -L/evil/ C 1 "A U Thor" 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L /RE/,/RE2/' '
|
|
|
|
check_count -L/robot/,/green/ A 1 B 1 B2 1 D 1 E 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L X,/RE/' '
|
|
|
|
check_count -L5,/evil/ B1 1 D 1 "A U Thor" 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L /RE/,Y' '
|
|
|
|
check_count -L/99/,7 B1 1 D 1 "A U Thor" 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L /RE/,+N' '
|
|
|
|
check_count -L/99/,+3 B1 1 D 1 "A U Thor" 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L /RE/,-N' '
|
|
|
|
check_count -L/99/,-3 B 1 B2 1 D 1
|
|
|
|
'
|
|
|
|
|
2013-07-31 08:15:36 +00:00
|
|
|
# 'file' ends with an incomplete line, so 'wc' reports one fewer lines than
|
|
|
|
# git-blame sees, hence the last line is actually $(wc...)+1.
|
|
|
|
test_expect_success 'blame -L X (X == nlines)' '
|
|
|
|
n=$(expr $(wc -l <file) + 1) &&
|
|
|
|
check_count -L$n C 1
|
|
|
|
'
|
|
|
|
|
blame: fix -L bounds checking bug
Since inception, -LX,Y has correctly reported an out-of-range error when
Y is beyond end of file, however, X was not checked, and an out-of-range
X would cause a crash. 92f9e273 (blame: prevent a segv when -L given
start > EOF; 2010-02-08) attempted to rectify this shortcoming but has
its own off-by-one error which allows X to extend one line past end of
file. For example, given a file with 5 lines:
git blame -L5 foo # OK, blames line 5
git blame -L6 foo # accepted, no error, no output, huh?
git blame -L7 foo # error "fatal: file foo has only 5 lines"
Fix this bug.
In order to avoid regressing "blame foo" when foo is an empty file, the
fix is slightly more complicated than changing '<' to '<='.
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-31 08:15:38 +00:00
|
|
|
test_expect_success 'blame -L X (X == nlines + 1)' '
|
2013-07-31 08:15:36 +00:00
|
|
|
n=$(expr $(wc -l <file) + 2) &&
|
|
|
|
test_must_fail $PROG -L$n file
|
|
|
|
'
|
|
|
|
|
2013-07-17 21:25:29 +00:00
|
|
|
test_expect_success 'blame -L X (X > nlines)' '
|
|
|
|
test_must_fail $PROG -L12345 file
|
|
|
|
'
|
|
|
|
|
2013-07-31 08:15:36 +00:00
|
|
|
test_expect_success 'blame -L ,Y (Y == nlines)' '
|
|
|
|
n=$(expr $(wc -l <file) + 1) &&
|
|
|
|
check_count -L,$n A 1 B 1 B1 1 B2 1 "A U Thor" 1 C 1 D 1 E 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L ,Y (Y == nlines + 1)' '
|
|
|
|
n=$(expr $(wc -l <file) + 2) &&
|
2018-06-15 06:29:27 +00:00
|
|
|
check_count -L,$n A 1 B 1 B1 1 B2 1 "A U Thor" 1 C 1 D 1 E 1
|
2013-07-31 08:15:36 +00:00
|
|
|
'
|
|
|
|
|
2013-07-17 21:25:29 +00:00
|
|
|
test_expect_success 'blame -L ,Y (Y > nlines)' '
|
2018-06-15 06:29:27 +00:00
|
|
|
check_count -L,12345 A 1 B 1 B1 1 B2 1 "A U Thor" 1 C 1 D 1 E 1
|
2013-07-17 21:25:29 +00:00
|
|
|
'
|
|
|
|
|
2013-08-06 13:59:39 +00:00
|
|
|
test_expect_success 'blame -L multiple (disjoint)' '
|
|
|
|
check_count -L2,3 -L6,7 A 1 B1 1 B2 1 "A U Thor" 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L multiple (disjoint: unordered)' '
|
|
|
|
check_count -L6,7 -L2,3 A 1 B1 1 B2 1 "A U Thor" 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L multiple (adjacent)' '
|
|
|
|
check_count -L2,3 -L4,5 A 1 B 1 B2 1 D 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L multiple (adjacent: unordered)' '
|
|
|
|
check_count -L4,5 -L2,3 A 1 B 1 B2 1 D 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L multiple (overlapping)' '
|
|
|
|
check_count -L2,4 -L3,5 A 1 B 1 B2 1 D 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L multiple (overlapping: unordered)' '
|
|
|
|
check_count -L3,5 -L2,4 A 1 B 1 B2 1 D 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L multiple (superset/subset)' '
|
|
|
|
check_count -L2,8 -L3,5 A 1 B 1 B1 1 B2 1 C 1 D 1 "A U Thor" 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L multiple (superset/subset: unordered)' '
|
|
|
|
check_count -L3,5 -L2,8 A 1 B 1 B1 1 B2 1 C 1 D 1 "A U Thor" 1
|
|
|
|
'
|
|
|
|
|
2013-08-06 13:59:42 +00:00
|
|
|
test_expect_success 'blame -L /RE/ (relative)' '
|
|
|
|
check_count -L3,3 -L/fox/ B1 1 B2 1 C 1 D 1 "A U Thor" 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L /RE/ (relative: no preceding range)' '
|
|
|
|
check_count -L/dog/ A 1 B 1 B1 1 B2 1 C 1 D 1 "A U Thor" 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L /RE/ (relative: adjacent)' '
|
|
|
|
check_count -L1,1 -L/dog/,+1 A 1 E 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L /RE/ (relative: not found)' '
|
|
|
|
test_must_fail $PROG -L4,4 -L/dog/ file
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L /RE/ (relative: end-of-file)' '
|
|
|
|
test_must_fail $PROG -L, -L/$/ file
|
|
|
|
'
|
|
|
|
|
2013-08-06 13:59:45 +00:00
|
|
|
test_expect_success 'blame -L ^/RE/ (absolute)' '
|
|
|
|
check_count -L3,3 -L^/dog/,+2 A 1 B2 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L ^/RE/ (absolute: no preceding range)' '
|
|
|
|
check_count -L^/dog/,+2 A 1 B2 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L ^/RE/ (absolute: not found)' '
|
|
|
|
test_must_fail $PROG -L4,4 -L^/tambourine/ file
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L ^/RE/ (absolute: end-of-file)' '
|
|
|
|
n=$(expr $(wc -l <file) + 1) &&
|
|
|
|
check_count -L$n -L^/$/,+2 A 1 C 1 E 1
|
|
|
|
'
|
|
|
|
|
2013-07-17 21:25:30 +00:00
|
|
|
test_expect_success 'setup -L :regex' '
|
|
|
|
tr Q "\\t" >hello.c <<-\EOF &&
|
|
|
|
int main(int argc, const char *argv[])
|
|
|
|
{
|
|
|
|
Qputs("hello");
|
|
|
|
}
|
|
|
|
EOF
|
|
|
|
git add hello.c &&
|
|
|
|
GIT_AUTHOR_NAME="F" GIT_AUTHOR_EMAIL="F@test.git" \
|
|
|
|
git commit -m "hello" &&
|
|
|
|
|
|
|
|
mv hello.c hello.orig &&
|
t8001, t8002: fix "blame -L :literal" test on NetBSD
Sub-test 42 of t8001 and t8002 ("blame -L :literal") fails on NetBSD
with the following verbose output:
git annotate -L:main hello.c
Author F (expected 4, attributed 3) bad
Author G (expected 1, attributed 1) good
This is not caused by different behaviour of git blame or annotate on
that platform, but by different test input, in turn caused by a sed
command that forgets to add a newline on NetBSD. Here's the diff of the
commit that adds "goodbye" to hello.c, for Linux:
@@ -1,4 +1,5 @@
int main(int argc, const char *argv[])
{
puts("hello");
+ puts("goodbye");
}
We see that it adds an extra TAB, but that's not a problem. Here's the
same on NetBSD:
@@ -1,4 +1,4 @@
int main(int argc, const char *argv[])
{
puts("hello");
-}
+ puts("goodbye");}
It also adds an extra TAB, but it is missing the newline character
after the semicolon.
The following patch gets rid of the extra TAB at the beginning, but
more importantly adds the missing newline at the end in a (hopefully)
portable way, mentioned in http://sed.sourceforge.net/sedfaq4.html.
The diff becomes this, on both Linux and NetBSD:
@@ -1,4 +1,5 @@
int main(int argc, const char *argv[])
{
puts("hello");
+ puts("goodbye");
}
Signed-off-by: Rene Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-08-05 15:21:17 +00:00
|
|
|
sed -e "/}/ {x; s/$/Qputs(\"goodbye\");/; G;}" <hello.orig |
|
|
|
|
tr Q "\\t" >hello.c &&
|
2013-07-17 21:25:30 +00:00
|
|
|
GIT_AUTHOR_NAME="G" GIT_AUTHOR_EMAIL="G@test.git" \
|
|
|
|
git commit -a -m "goodbye" &&
|
|
|
|
|
|
|
|
mv hello.c hello.orig &&
|
|
|
|
echo "#include <stdio.h>" >hello.c &&
|
|
|
|
cat hello.orig >>hello.c &&
|
2015-03-20 10:07:15 +00:00
|
|
|
tr Q "\\t" >>hello.c <<-\EOF &&
|
2013-07-17 21:25:30 +00:00
|
|
|
void mail()
|
|
|
|
{
|
|
|
|
Qputs("mail");
|
|
|
|
}
|
|
|
|
EOF
|
|
|
|
GIT_AUTHOR_NAME="H" GIT_AUTHOR_EMAIL="H@test.git" \
|
|
|
|
git commit -a -m "mail"
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L :literal' '
|
|
|
|
check_count -f hello.c -L:main F 4 G 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L :regex' '
|
|
|
|
check_count -f hello.c "-L:m[a-z][a-z]l" H 4
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L :nomatch' '
|
|
|
|
test_must_fail $PROG -L:nomatch hello.c
|
|
|
|
'
|
|
|
|
|
2013-08-06 13:59:46 +00:00
|
|
|
test_expect_success 'blame -L :RE (relative)' '
|
|
|
|
check_count -f hello.c -L3,3 -L:ma.. F 1 H 4
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L :RE (relative: no preceding range)' '
|
|
|
|
check_count -f hello.c -L:ma.. F 4 G 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L :RE (relative: not found)' '
|
|
|
|
test_must_fail $PROG -L3,3 -L:tambourine hello.c
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L :RE (relative: end-of-file)' '
|
|
|
|
test_must_fail $PROG -L, -L:main hello.c
|
|
|
|
'
|
|
|
|
|
2013-08-06 13:59:47 +00:00
|
|
|
test_expect_success 'blame -L ^:RE (absolute)' '
|
|
|
|
check_count -f hello.c -L3,3 -L^:ma.. F 4 G 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L ^:RE (absolute: no preceding range)' '
|
|
|
|
check_count -f hello.c -L^:ma.. F 4 G 1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L ^:RE (absolute: not found)' '
|
|
|
|
test_must_fail $PROG -L4,4 -L^:tambourine hello.c
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L ^:RE (absolute: end-of-file)' '
|
|
|
|
n=$(printf "%d" $(wc -l <hello.c)) &&
|
|
|
|
check_count -f hello.c -L$n -L^:ma.. F 4 G 1 H 1
|
|
|
|
'
|
|
|
|
|
2021-04-08 15:04:24 +00:00
|
|
|
test_expect_success 'blame -L :funcname with userdiff driver' '
|
|
|
|
cat >file.template <<-\EOF &&
|
|
|
|
DO NOT MATCH THIS LINE
|
2021-04-08 15:04:23 +00:00
|
|
|
function RIGHT(a, b) result(c)
|
2021-04-08 15:04:24 +00:00
|
|
|
AS THE DEFAULT DRIVER WOULD
|
2021-04-08 15:04:23 +00:00
|
|
|
|
|
|
|
integer, intent(in) :: ChangeMe
|
|
|
|
EOF
|
blame: enable funcname blaming with userdiff driver
In blame.c::cmd_blame, we send the 'path' field of the 'sb' 'struct
blame_scoreboard' as the 'path' argument to
'line-range.c::parse_range_arg', but 'sb.path' is not set yet; it's set
to the local variable 'path' a few lines later at line 1137.
This 'path' argument is only used in 'parse_range_arg' if we are blaming
a funcname, i.e. `git blame -L :<funcname> <path>`, and in that case it
is sent to 'parse_range_funcname', where it is used to determine if a
userdiff driver should be used for said <path> to match the given
funcname.
Since 'path' is yet unset, the userdiff driver is never used, so we fall
back to the default funcname regex, which is usually not appropriate for
paths that are set to use a specific userdiff driver, and thus either we
match some unrelated lines, or we die with
fatal: -L parameter '<funcname>' starting at line 1: no match
This has been the case ever since `git blame` learned to blame a
funcname in 13b8f68c1f (log -L: :pattern:file syntax to find by
funcname, 2013-03-28).
Enable funcname blaming for paths using specific userdiff drivers by
initializing 'sb.path' earlier in 'cmd_blame', when some of its other
fields are initialized, so that it is set when passed to
'parse_range_arg'.
Add a regression test in 'annotate-tests.sh', which is sourced in
t8001-annotate.sh and t8002-blame.sh, leveraging an existing file used
to test the userdiff patterns in t4018-diff-funcname.
Also, use 'sb.path' instead of 'path' when constructing the error
message at line 1114, for consistency.
Signed-off-by: Philippe Blain <levraiphilippeblain@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-11-01 17:28:45 +00:00
|
|
|
|
2021-04-08 15:04:24 +00:00
|
|
|
fortran_file=file.f03 &&
|
|
|
|
test_when_finished "rm .gitattributes" &&
|
|
|
|
echo "$fortran_file diff=fortran" >.gitattributes &&
|
|
|
|
|
|
|
|
test_commit --author "A <A@test.git>" \
|
|
|
|
"add" "$fortran_file" \
|
|
|
|
"$(cat file.template)" &&
|
|
|
|
test_commit --author "B <B@test.git>" \
|
|
|
|
"change" "$fortran_file" \
|
|
|
|
"$(cat file.template | sed -e s/ChangeMe/IWasChanged/)" &&
|
|
|
|
check_count -f "$fortran_file" -L:RIGHT A 3 B 1
|
blame: enable funcname blaming with userdiff driver
In blame.c::cmd_blame, we send the 'path' field of the 'sb' 'struct
blame_scoreboard' as the 'path' argument to
'line-range.c::parse_range_arg', but 'sb.path' is not set yet; it's set
to the local variable 'path' a few lines later at line 1137.
This 'path' argument is only used in 'parse_range_arg' if we are blaming
a funcname, i.e. `git blame -L :<funcname> <path>`, and in that case it
is sent to 'parse_range_funcname', where it is used to determine if a
userdiff driver should be used for said <path> to match the given
funcname.
Since 'path' is yet unset, the userdiff driver is never used, so we fall
back to the default funcname regex, which is usually not appropriate for
paths that are set to use a specific userdiff driver, and thus either we
match some unrelated lines, or we die with
fatal: -L parameter '<funcname>' starting at line 1: no match
This has been the case ever since `git blame` learned to blame a
funcname in 13b8f68c1f (log -L: :pattern:file syntax to find by
funcname, 2013-03-28).
Enable funcname blaming for paths using specific userdiff drivers by
initializing 'sb.path' earlier in 'cmd_blame', when some of its other
fields are initialized, so that it is set when passed to
'parse_range_arg'.
Add a regression test in 'annotate-tests.sh', which is sourced in
t8001-annotate.sh and t8002-blame.sh, leveraging an existing file used
to test the userdiff patterns in t4018-diff-funcname.
Also, use 'sb.path' instead of 'path' when constructing the error
message at line 1114, for consistency.
Signed-off-by: Philippe Blain <levraiphilippeblain@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-11-01 17:28:45 +00:00
|
|
|
'
|
|
|
|
|
2013-07-31 08:15:37 +00:00
|
|
|
test_expect_success 'setup incremental' '
|
|
|
|
(
|
|
|
|
GIT_AUTHOR_NAME=I &&
|
|
|
|
export GIT_AUTHOR_NAME &&
|
|
|
|
GIT_AUTHOR_EMAIL=I@test.git &&
|
|
|
|
export GIT_AUTHOR_EMAIL &&
|
|
|
|
>incremental &&
|
|
|
|
git add incremental &&
|
|
|
|
git commit -m "step 0" &&
|
|
|
|
printf "partial" >>incremental &&
|
|
|
|
git commit -a -m "step 0.5" &&
|
|
|
|
echo >>incremental &&
|
|
|
|
git commit -a -m "step 1"
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame empty' '
|
|
|
|
check_count -h HEAD^^ -f incremental
|
|
|
|
'
|
|
|
|
|
2013-08-06 13:59:49 +00:00
|
|
|
test_expect_success 'blame -L 0 empty' '
|
|
|
|
test_must_fail $PROG -L0 incremental HEAD^^
|
2013-07-31 08:15:37 +00:00
|
|
|
'
|
|
|
|
|
blame: fix -L bounds checking bug
Since inception, -LX,Y has correctly reported an out-of-range error when
Y is beyond end of file, however, X was not checked, and an out-of-range
X would cause a crash. 92f9e273 (blame: prevent a segv when -L given
start > EOF; 2010-02-08) attempted to rectify this shortcoming but has
its own off-by-one error which allows X to extend one line past end of
file. For example, given a file with 5 lines:
git blame -L5 foo # OK, blames line 5
git blame -L6 foo # accepted, no error, no output, huh?
git blame -L7 foo # error "fatal: file foo has only 5 lines"
Fix this bug.
In order to avoid regressing "blame foo" when foo is an empty file, the
fix is slightly more complicated than changing '<' to '<='.
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-31 08:15:38 +00:00
|
|
|
test_expect_success 'blame -L 1 empty' '
|
2013-07-31 08:15:37 +00:00
|
|
|
test_must_fail $PROG -L1 incremental HEAD^^
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L 2 empty' '
|
|
|
|
test_must_fail $PROG -L2 incremental HEAD^^
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame half' '
|
|
|
|
check_count -h HEAD^ -f incremental I 1
|
|
|
|
'
|
|
|
|
|
2013-08-06 13:59:49 +00:00
|
|
|
test_expect_success 'blame -L 0 half' '
|
|
|
|
test_must_fail $PROG -L0 incremental HEAD^
|
2013-07-31 08:15:37 +00:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L 1 half' '
|
|
|
|
check_count -h HEAD^ -f incremental -L1 I 1
|
|
|
|
'
|
|
|
|
|
blame: fix -L bounds checking bug
Since inception, -LX,Y has correctly reported an out-of-range error when
Y is beyond end of file, however, X was not checked, and an out-of-range
X would cause a crash. 92f9e273 (blame: prevent a segv when -L given
start > EOF; 2010-02-08) attempted to rectify this shortcoming but has
its own off-by-one error which allows X to extend one line past end of
file. For example, given a file with 5 lines:
git blame -L5 foo # OK, blames line 5
git blame -L6 foo # accepted, no error, no output, huh?
git blame -L7 foo # error "fatal: file foo has only 5 lines"
Fix this bug.
In order to avoid regressing "blame foo" when foo is an empty file, the
fix is slightly more complicated than changing '<' to '<='.
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-31 08:15:38 +00:00
|
|
|
test_expect_success 'blame -L 2 half' '
|
2013-07-31 08:15:37 +00:00
|
|
|
test_must_fail $PROG -L2 incremental HEAD^
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L 3 half' '
|
|
|
|
test_must_fail $PROG -L3 incremental HEAD^
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame full' '
|
|
|
|
check_count -f incremental I 1
|
|
|
|
'
|
|
|
|
|
2013-08-06 13:59:49 +00:00
|
|
|
test_expect_success 'blame -L 0 full' '
|
|
|
|
test_must_fail $PROG -L0 incremental
|
2013-07-31 08:15:37 +00:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L 1 full' '
|
|
|
|
check_count -f incremental -L1 I 1
|
|
|
|
'
|
|
|
|
|
blame: fix -L bounds checking bug
Since inception, -LX,Y has correctly reported an out-of-range error when
Y is beyond end of file, however, X was not checked, and an out-of-range
X would cause a crash. 92f9e273 (blame: prevent a segv when -L given
start > EOF; 2010-02-08) attempted to rectify this shortcoming but has
its own off-by-one error which allows X to extend one line past end of
file. For example, given a file with 5 lines:
git blame -L5 foo # OK, blames line 5
git blame -L6 foo # accepted, no error, no output, huh?
git blame -L7 foo # error "fatal: file foo has only 5 lines"
Fix this bug.
In order to avoid regressing "blame foo" when foo is an empty file, the
fix is slightly more complicated than changing '<' to '<='.
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-31 08:15:38 +00:00
|
|
|
test_expect_success 'blame -L 2 full' '
|
2013-07-31 08:15:37 +00:00
|
|
|
test_must_fail $PROG -L2 incremental
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L 3 full' '
|
|
|
|
test_must_fail $PROG -L3 incremental
|
|
|
|
'
|
|
|
|
|
2013-07-31 08:15:35 +00:00
|
|
|
test_expect_success 'blame -L' '
|
|
|
|
test_must_fail $PROG -L file
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L X,+' '
|
|
|
|
test_must_fail $PROG -L1,+ file
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L X,-' '
|
|
|
|
test_must_fail $PROG -L1,- file
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L X (non-numeric X)' '
|
|
|
|
test_must_fail $PROG -LX file
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L X,Y (non-numeric Y)' '
|
|
|
|
test_must_fail $PROG -L1,Y file
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L X,+N (non-numeric N)' '
|
|
|
|
test_must_fail $PROG -L1,+N file
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'blame -L X,-N (non-numeric N)' '
|
2013-07-17 21:25:29 +00:00
|
|
|
test_must_fail $PROG -L1,-N file
|
|
|
|
'
|
2013-08-06 13:59:45 +00:00
|
|
|
|
|
|
|
test_expect_success 'blame -L ,^/RE/' '
|
|
|
|
test_must_fail $PROG -L1,^/99/ file
|
|
|
|
'
|