diff --git a/Documentation/blame-options.txt b/Documentation/blame-options.txt index 88750af7ae..dc3bceb6d1 100644 --- a/Documentation/blame-options.txt +++ b/Documentation/blame-options.txt @@ -11,11 +11,12 @@ -L ,:: -L ::: - Annotate only the given line range. May be specified multiple times. - Overlapping ranges are allowed. + Annotate only the line range given by ',', + or by the function name regex ''. + May be specified multiple times. Overlapping ranges are allowed. + - and are optional. ``-L '' or ``-L ,'' spans from - to end of file. ``-L ,'' spans from start of file to . +'' and '' are optional. `-L ` or `-L ,` spans from +'' to end of file. `-L ,` spans from start of file to ''. + include::line-range-format.txt[] diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index 2e7a93894c..746b144c76 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.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[] diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt index 6077ff01a4..4e0ba8234a 100644 --- a/Documentation/git-grep.txt +++ b/Documentation/git-grep.txt @@ -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 :: Number of grep worker threads to use. diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt index 2b8ac5ff88..dd189a353a 100644 --- a/Documentation/git-log.txt +++ b/Documentation/git-log.txt @@ -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 ,::: --L :::: - Trace the evolution of the line range given by "," - (or the function name regex ) within the . 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 - and (or ) 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[] :: Show only commits in the specified revision range. When no diff --git a/Documentation/gitk.txt b/Documentation/gitk.txt index c653ebb6a8..d50e9ed10e 100644 --- a/Documentation/gitk.txt +++ b/Documentation/gitk.txt @@ -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,::: --L:::: - - Trace the evolution of the line range given by "," - (or the function name regex ) within the . 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 - and (or ) 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[] :: diff --git a/Documentation/line-range-format.txt b/Documentation/line-range-format.txt index 829676ff98..9b51e9fb66 100644 --- a/Documentation/line-range-format.txt +++ b/Documentation/line-range-format.txt @@ -1,30 +1,32 @@ - and can take one of these forms: +'' and '' can take one of these forms: - number + -If or is a number, it specifies an +If '' or '' 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 is a regex, it will search from the end of +POSIX regex. If '' is a regex, it will search from the end of the previous `-L` range, if any, otherwise from the start of file. -If is ``^/regex/'', it will search from the start of file. -If is a regex, it will search -starting at the line given by . +If '' is `^/regex/`, it will search from the start of file. +If '' is a regex, it will search +starting at the line given by ''. + - +offset or -offset + -This is only valid for and will specify a number -of lines before or after the line given by . +This is only valid for '' and will specify a number +of lines before or after the line given by ''. + -If ``:'' is given in place of and , it is a +If `:` is given in place of '' and '', it is a regular expression that denotes the range from the first funcname line -that matches , up to the next funcname line. ``:'' +that matches '', up to the next funcname line. `:` searches from the end of the previous `-L` range, if any, otherwise -from the start of file. ``^:'' searches from the start of -file. +from the start of file. `^:` 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]). diff --git a/Documentation/line-range-options.txt b/Documentation/line-range-options.txt new file mode 100644 index 0000000000..8e295a62b8 --- /dev/null +++ b/Documentation/line-range-options.txt @@ -0,0 +1,15 @@ +-L,::: +-L:::: + + Trace the evolution of the line range given by ',', + or by the function name regex '', within the ''. 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 + '' and '' (or '') 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[] diff --git a/blame.c b/blame.c index de7b5d411f..9156ebeafd 100644 --- a/blame.c +++ b/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; } diff --git a/blame.h b/blame.h index b6bbee4147..38bde535b3 100644 --- a/blame.h +++ b/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, diff --git a/builtin/blame.c b/builtin/blame.c index b5036ab327..6f7e32411a 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -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 '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 , or function :")), 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; diff --git a/builtin/log.c b/builtin/log.c index 6619e10abc..49eb8f6431 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -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 ")), 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 , or function : in "), log_line_range_callback), OPT_END() }; diff --git a/t/annotate-tests.sh b/t/annotate-tests.sh index d933af5714..3aee61d2cc 100644 --- a/t/annotate-tests.sh +++ b/t/annotate-tests.sh @@ -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 &&