Merge branch 'pb/blame-funcname-range-userdiff'
"git blame -L :funcname -- path" did not work well for a path for which a userdiff driver is defined. * pb/blame-funcname-range-userdiff: blame: simplify 'setup_blame_bloom_data' interface blame: simplify 'setup_scoreboard' interface blame: enable funcname blaming with userdiff driver line-log: mention both modes in 'blame' and 'log' short help doc: add more pointers to gitattributes(5) for userdiff blame-options.txt: also mention 'funcname' in '-L' description doc: line-range: improve formatting doc: log, gitk: move '-L' description to 'line-range-options.txt'
This commit is contained in:
commit
3f6dc9c366
@ -11,11 +11,12 @@
|
||||
|
||||
-L <start>,<end>::
|
||||
-L :<funcname>::
|
||||
Annotate only the given line range. May be specified multiple times.
|
||||
Overlapping ranges are allowed.
|
||||
Annotate only the line range given by '<start>,<end>',
|
||||
or by the function name regex '<funcname>'.
|
||||
May be specified multiple times. Overlapping ranges are allowed.
|
||||
+
|
||||
<start> and <end> are optional. ``-L <start>'' or ``-L <start>,'' spans from
|
||||
<start> to end of file. ``-L ,<end>'' spans from start of file to <end>.
|
||||
'<start>' and '<end>' are optional. `-L <start>` or `-L <start>,` spans from
|
||||
'<start>' to end of file. `-L ,<end>` spans from start of file to '<end>'.
|
||||
+
|
||||
include::line-range-format.txt[]
|
||||
|
||||
|
@ -704,7 +704,10 @@ endif::git-format-patch[]
|
||||
|
||||
-W::
|
||||
--function-context::
|
||||
Show whole surrounding functions of changes.
|
||||
Show whole function as context lines for each change.
|
||||
The function names are determined in the same way as
|
||||
`git diff` works out patch hunk headers (see 'Defining a
|
||||
custom hunk-header' in linkgit:gitattributes[5]).
|
||||
|
||||
ifndef::git-format-patch[]
|
||||
ifndef::git-log[]
|
||||
|
@ -241,7 +241,7 @@ providing this option will cause it to die.
|
||||
--show-function::
|
||||
Show the preceding line that contains the function name of
|
||||
the match, unless the matching line is a function name itself.
|
||||
The name is determined in the same way as 'git diff' works out
|
||||
The name is determined in the same way as `git diff` works out
|
||||
patch hunk headers (see 'Defining a custom hunk-header' in
|
||||
linkgit:gitattributes[5]).
|
||||
|
||||
@ -266,7 +266,9 @@ providing this option will cause it to die.
|
||||
Show the surrounding text from the previous line containing a
|
||||
function name up to the one before the next function name,
|
||||
effectively showing the whole function in which the match was
|
||||
found.
|
||||
found. The function names are determined in the same way as
|
||||
`git diff` works out patch hunk headers (see 'Defining a
|
||||
custom hunk-header' in linkgit:gitattributes[5]).
|
||||
|
||||
--threads <num>::
|
||||
Number of grep worker threads to use.
|
||||
|
@ -77,20 +77,7 @@ produced by `--stat`, etc.
|
||||
Intended to speed up tools that read log messages from `git log`
|
||||
output by allowing them to allocate space in advance.
|
||||
|
||||
-L <start>,<end>:<file>::
|
||||
-L :<funcname>:<file>::
|
||||
Trace the evolution of the line range given by "<start>,<end>"
|
||||
(or the function name regex <funcname>) within the <file>. You may
|
||||
not give any pathspec limiters. This is currently limited to
|
||||
a walk starting from a single revision, i.e., you may only
|
||||
give zero or one positive revision arguments, and
|
||||
<start> and <end> (or <funcname>) must exist in the starting revision.
|
||||
You can specify this option more than once. Implies `--patch`.
|
||||
Patch output can be suppressed using `--no-patch`, but other diff formats
|
||||
(namely `--raw`, `--numstat`, `--shortstat`, `--dirstat`, `--summary`,
|
||||
`--name-only`, `--name-status`, `--check`) are not currently implemented.
|
||||
+
|
||||
include::line-range-format.txt[]
|
||||
include::line-range-options.txt[]
|
||||
|
||||
<revision range>::
|
||||
Show only commits in the specified revision range. When no
|
||||
|
@ -98,25 +98,7 @@ linkgit:git-rev-list[1] for a complete list.
|
||||
(See "History simplification" in linkgit:git-log[1] for a more
|
||||
detailed explanation.)
|
||||
|
||||
-L<start>,<end>:<file>::
|
||||
-L:<funcname>:<file>::
|
||||
|
||||
Trace the evolution of the line range given by "<start>,<end>"
|
||||
(or the function name regex <funcname>) within the <file>. You may
|
||||
not give any pathspec limiters. This is currently limited to
|
||||
a walk starting from a single revision, i.e., you may only
|
||||
give zero or one positive revision arguments, and
|
||||
<start> and <end> (or <funcname>) must exist in the starting revision.
|
||||
You can specify this option more than once. Implies `--patch`.
|
||||
Patch output can be suppressed using `--no-patch`, but other diff formats
|
||||
(namely `--raw`, `--numstat`, `--shortstat`, `--dirstat`, `--summary`,
|
||||
`--name-only`, `--name-status`, `--check`) are not currently implemented.
|
||||
+
|
||||
*Note:* gitk (unlike linkgit:git-log[1]) currently only understands
|
||||
this option if you specify it "glued together" with its argument. Do
|
||||
*not* put a space after `-L`.
|
||||
+
|
||||
include::line-range-format.txt[]
|
||||
include::line-range-options.txt[]
|
||||
|
||||
<revision range>::
|
||||
|
||||
|
@ -1,30 +1,32 @@
|
||||
<start> and <end> can take one of these forms:
|
||||
'<start>' and '<end>' can take one of these forms:
|
||||
|
||||
- number
|
||||
+
|
||||
If <start> or <end> is a number, it specifies an
|
||||
If '<start>' or '<end>' is a number, it specifies an
|
||||
absolute line number (lines count from 1).
|
||||
+
|
||||
|
||||
- /regex/
|
||||
- `/regex/`
|
||||
+
|
||||
This form will use the first line matching the given
|
||||
POSIX regex. If <start> is a regex, it will search from the end of
|
||||
POSIX regex. If '<start>' is a regex, it will search from the end of
|
||||
the previous `-L` range, if any, otherwise from the start of file.
|
||||
If <start> is ``^/regex/'', it will search from the start of file.
|
||||
If <end> is a regex, it will search
|
||||
starting at the line given by <start>.
|
||||
If '<start>' is `^/regex/`, it will search from the start of file.
|
||||
If '<end>' is a regex, it will search
|
||||
starting at the line given by '<start>'.
|
||||
+
|
||||
|
||||
- +offset or -offset
|
||||
+
|
||||
This is only valid for <end> and will specify a number
|
||||
of lines before or after the line given by <start>.
|
||||
This is only valid for '<end>' and will specify a number
|
||||
of lines before or after the line given by '<start>'.
|
||||
|
||||
+
|
||||
If ``:<funcname>'' is given in place of <start> and <end>, it is a
|
||||
If `:<funcname>` is given in place of '<start>' and '<end>', it is a
|
||||
regular expression that denotes the range from the first funcname line
|
||||
that matches <funcname>, up to the next funcname line. ``:<funcname>''
|
||||
that matches '<funcname>', up to the next funcname line. `:<funcname>`
|
||||
searches from the end of the previous `-L` range, if any, otherwise
|
||||
from the start of file. ``^:<funcname>'' searches from the start of
|
||||
file.
|
||||
from the start of file. `^:<funcname>` searches from the start of
|
||||
file. The function names are determined in the same way as `git diff`
|
||||
works out patch hunk headers (see 'Defining a custom hunk-header'
|
||||
in linkgit:gitattributes[5]).
|
||||
|
15
Documentation/line-range-options.txt
Normal file
15
Documentation/line-range-options.txt
Normal file
@ -0,0 +1,15 @@
|
||||
-L<start>,<end>:<file>::
|
||||
-L:<funcname>:<file>::
|
||||
|
||||
Trace the evolution of the line range given by '<start>,<end>',
|
||||
or by the function name regex '<funcname>', within the '<file>'. You may
|
||||
not give any pathspec limiters. This is currently limited to
|
||||
a walk starting from a single revision, i.e., you may only
|
||||
give zero or one positive revision arguments, and
|
||||
'<start>' and '<end>' (or '<funcname>') must exist in the starting revision.
|
||||
You can specify this option more than once. Implies `--patch`.
|
||||
Patch output can be suppressed using `--no-patch`, but other diff formats
|
||||
(namely `--raw`, `--numstat`, `--shortstat`, `--dirstat`, `--summary`,
|
||||
`--name-only`, `--name-status`, `--check`) are not currently implemented.
|
||||
+
|
||||
include::line-range-format.txt[]
|
16
blame.c
16
blame.c
@ -2764,7 +2764,6 @@ void init_scoreboard(struct blame_scoreboard *sb)
|
||||
}
|
||||
|
||||
void setup_scoreboard(struct blame_scoreboard *sb,
|
||||
const char *path,
|
||||
struct blame_origin **orig)
|
||||
{
|
||||
const char *final_commit_name = NULL;
|
||||
@ -2803,7 +2802,7 @@ void setup_scoreboard(struct blame_scoreboard *sb,
|
||||
setup_work_tree();
|
||||
sb->final = fake_working_tree_commit(sb->repo,
|
||||
&sb->revs->diffopt,
|
||||
path, sb->contents_from);
|
||||
sb->path, sb->contents_from);
|
||||
add_pending_object(sb->revs, &(sb->final->object), ":");
|
||||
}
|
||||
|
||||
@ -2846,12 +2845,12 @@ void setup_scoreboard(struct blame_scoreboard *sb,
|
||||
sb->final_buf_size = o->file.size;
|
||||
}
|
||||
else {
|
||||
o = get_origin(sb->final, path);
|
||||
o = get_origin(sb->final, sb->path);
|
||||
if (fill_blob_sha1_and_mode(sb->repo, o))
|
||||
die(_("no such path %s in %s"), path, final_commit_name);
|
||||
die(_("no such path %s in %s"), sb->path, final_commit_name);
|
||||
|
||||
if (sb->revs->diffopt.flags.allow_textconv &&
|
||||
textconv_object(sb->repo, path, o->mode, &o->blob_oid, 1, (char **) &sb->final_buf,
|
||||
textconv_object(sb->repo, sb->path, o->mode, &o->blob_oid, 1, (char **) &sb->final_buf,
|
||||
&sb->final_buf_size))
|
||||
;
|
||||
else
|
||||
@ -2861,7 +2860,7 @@ void setup_scoreboard(struct blame_scoreboard *sb,
|
||||
if (!sb->final_buf)
|
||||
die(_("cannot read blob %s for path %s"),
|
||||
oid_to_hex(&o->blob_oid),
|
||||
path);
|
||||
sb->path);
|
||||
}
|
||||
sb->num_read_blob++;
|
||||
prepare_lines(sb);
|
||||
@ -2888,8 +2887,7 @@ struct blame_entry *blame_entry_prepend(struct blame_entry *head,
|
||||
return new_head;
|
||||
}
|
||||
|
||||
void setup_blame_bloom_data(struct blame_scoreboard *sb,
|
||||
const char *path)
|
||||
void setup_blame_bloom_data(struct blame_scoreboard *sb)
|
||||
{
|
||||
struct blame_bloom_data *bd;
|
||||
struct bloom_filter_settings *bs;
|
||||
@ -2909,7 +2907,7 @@ void setup_blame_bloom_data(struct blame_scoreboard *sb,
|
||||
bd->nr = 0;
|
||||
ALLOC_ARRAY(bd->keys, bd->alloc);
|
||||
|
||||
add_bloom_key(bd, path);
|
||||
add_bloom_key(bd, sb->path);
|
||||
|
||||
sb->bloom_data = bd;
|
||||
}
|
||||
|
4
blame.h
4
blame.h
@ -181,10 +181,8 @@ const char *blame_nth_line(struct blame_scoreboard *sb, long lno);
|
||||
|
||||
void init_scoreboard(struct blame_scoreboard *sb);
|
||||
void setup_scoreboard(struct blame_scoreboard *sb,
|
||||
const char *path,
|
||||
struct blame_origin **orig);
|
||||
void setup_blame_bloom_data(struct blame_scoreboard *sb,
|
||||
const char *path);
|
||||
void setup_blame_bloom_data(struct blame_scoreboard *sb);
|
||||
void cleanup_scoreboard(struct blame_scoreboard *sb);
|
||||
|
||||
struct blame_entry *blame_entry_prepend(struct blame_entry *head,
|
||||
|
@ -891,7 +891,8 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
|
||||
OPT_STRING(0, "contents", &contents_from, N_("file"), N_("Use <file>'s contents as the final image")),
|
||||
OPT_CALLBACK_F('C', NULL, &opt, N_("score"), N_("Find line copies within and across files"), PARSE_OPT_OPTARG, blame_copy_callback),
|
||||
OPT_CALLBACK_F('M', NULL, &opt, N_("score"), N_("Find line movements within and across files"), PARSE_OPT_OPTARG, blame_move_callback),
|
||||
OPT_STRING_LIST('L', NULL, &range_list, N_("n,m"), N_("Process only line range n,m, counting from 1")),
|
||||
OPT_STRING_LIST('L', NULL, &range_list, N_("range"),
|
||||
N_("Process only line range <start>,<end> or function :<funcname>")),
|
||||
OPT__ABBREV(&abbrev),
|
||||
OPT_END()
|
||||
};
|
||||
@ -1082,17 +1083,18 @@ parse_done:
|
||||
sb.contents_from = contents_from;
|
||||
sb.reverse = reverse;
|
||||
sb.repo = the_repository;
|
||||
sb.path = path;
|
||||
build_ignorelist(&sb, &ignore_revs_file_list, &ignore_rev_list);
|
||||
string_list_clear(&ignore_revs_file_list, 0);
|
||||
string_list_clear(&ignore_rev_list, 0);
|
||||
setup_scoreboard(&sb, path, &o);
|
||||
setup_scoreboard(&sb, &o);
|
||||
|
||||
/*
|
||||
* Changed-path Bloom filters are disabled when looking
|
||||
* for copies.
|
||||
*/
|
||||
if (!(opt & PICKAXE_BLAME_COPY))
|
||||
setup_blame_bloom_data(&sb, path);
|
||||
setup_blame_bloom_data(&sb);
|
||||
|
||||
lno = sb.num_lines;
|
||||
|
||||
@ -1111,7 +1113,7 @@ parse_done:
|
||||
if ((!lno && (top || bottom)) || lno < bottom)
|
||||
die(Q_("file %s has only %lu line",
|
||||
"file %s has only %lu lines",
|
||||
lno), path, lno);
|
||||
lno), sb.path, lno);
|
||||
if (bottom < 1)
|
||||
bottom = 1;
|
||||
if (top < 1 || lno < top)
|
||||
@ -1136,7 +1138,6 @@ parse_done:
|
||||
string_list_clear(&range_list, 0);
|
||||
|
||||
sb.ent = NULL;
|
||||
sb.path = path;
|
||||
|
||||
if (blame_move_score)
|
||||
sb.move_score = blame_move_score;
|
||||
|
@ -183,8 +183,8 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
|
||||
N_("pattern"), N_("do not decorate refs that match <pattern>")),
|
||||
OPT_CALLBACK_F(0, "decorate", NULL, NULL, N_("decorate options"),
|
||||
PARSE_OPT_OPTARG, decorate_callback),
|
||||
OPT_CALLBACK('L', NULL, &line_cb, "n,m:file",
|
||||
N_("Process line range n,m in file, counting from 1"),
|
||||
OPT_CALLBACK('L', NULL, &line_cb, "range:file",
|
||||
N_("Trace the evolution of line range <start>,<end> or function :<funcname> in <file>"),
|
||||
log_line_range_callback),
|
||||
OPT_END()
|
||||
};
|
||||
|
@ -479,6 +479,24 @@ test_expect_success 'blame -L ^:RE (absolute: end-of-file)' '
|
||||
check_count -f hello.c -L$n -L^:ma.. F 4 G 1 H 1
|
||||
'
|
||||
|
||||
test_expect_success 'setup -L :funcname with userdiff driver' '
|
||||
echo "fortran-* diff=fortran" >.gitattributes &&
|
||||
fortran_file=fortran-external-function &&
|
||||
orig_file="$TEST_DIRECTORY/t4018/$fortran_file" &&
|
||||
cp $orig_file . &&
|
||||
git add $fortran_file &&
|
||||
GIT_AUTHOR_NAME="A" GIT_AUTHOR_EMAIL="A@test.git" \
|
||||
git commit -m "add fortran file" &&
|
||||
sed -e "s/ChangeMe/IWasChanged/" <"$orig_file" >$fortran_file &&
|
||||
git add $fortran_file &&
|
||||
GIT_AUTHOR_NAME="B" GIT_AUTHOR_EMAIL="B@test.git" \
|
||||
git commit -m "change fortran file"
|
||||
'
|
||||
|
||||
test_expect_success 'blame -L :funcname with userdiff driver' '
|
||||
check_count -f fortran-external-function -L:RIGHT A 7 B 1
|
||||
'
|
||||
|
||||
test_expect_success 'setup incremental' '
|
||||
(
|
||||
GIT_AUTHOR_NAME=I &&
|
||||
|
Loading…
Reference in New Issue
Block a user