If the -L option is used to specify a line range in git blame, and the end of the range is past the end of the file, git will fail with a fatal error. It may instead be desirable to perform a git blame for the line numbers in the intersection of the file and the specified line range. This patch adds a --fuzzy-lines command line option to allow this. Signed-off-by: Isabella Stephens <istephens@xxxxxxxxxxxxx> --- Documentation/blame-options.txt | 5 +++++ builtin/blame.c | 4 ++++ t/t8003-blame-corner-cases.sh | 6 ++++++ 3 files changed, 15 insertions(+) diff --git a/Documentation/blame-options.txt b/Documentation/blame-options.txt index dc41957af..664cd8f8b 100644 --- a/Documentation/blame-options.txt +++ b/Documentation/blame-options.txt @@ -19,6 +19,11 @@ + include::line-range-format.txt[] +--fuzzy-lines:: + Use fuzzy line ranges. If a range specified with -L starts on a line + within the file but ends past the end of the file, display the blame + for the existing lines rather than failing. + -l:: Show long rev (Default: off). diff --git a/builtin/blame.c b/builtin/blame.c index 67adaef4d..d25b39d40 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -661,6 +661,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix) struct string_list range_list = STRING_LIST_INIT_NODUP; int output_option = 0, opt = 0; + int fuzzy_lines = 0; int show_stats = 0; const char *revs_file = NULL; const char *contents_from = NULL; @@ -670,6 +671,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix) OPT_BOOL(0, "root", &show_root, N_("Do not treat root commits as boundaries (Default: off)")), OPT_BOOL(0, "show-stats", &show_stats, N_("Show work cost statistics")), OPT_BOOL(0, "progress", &show_progress, N_("Force progress reporting")), + OPT_BOOL(0, "fuzzy-lines", &fuzzy_lines, N_("Use fuzzy line ranges")), OPT_BIT(0, "score-debug", &output_option, N_("Show output score for blame entries"), OUTPUT_SHOW_SCORE), OPT_BIT('f', "show-name", &output_option, N_("Show original filename (Default: auto)"), OUTPUT_SHOW_NAME), OPT_BIT('n', "show-number", &output_option, N_("Show original linenumber (Default: off)"), OUTPUT_SHOW_NUMBER), @@ -878,6 +880,8 @@ int cmd_blame(int argc, const char **argv, const char *prefix) nth_line_cb, &sb, lno, anchor, &bottom, &top, sb.path)) usage(blame_usage); + if (fuzzy_lines && lno < top) + top = lno; if (lno < top || ((lno || bottom) && lno < bottom)) die(Q_("file %s has only %lu line", "file %s has only %lu lines", diff --git a/t/t8003-blame-corner-cases.sh b/t/t8003-blame-corner-cases.sh index 661f9d430..6e7657df2 100755 --- a/t/t8003-blame-corner-cases.sh +++ b/t/t8003-blame-corner-cases.sh @@ -220,6 +220,12 @@ test_expect_success 'blame -L with invalid end' ' test_i18ngrep "has only 2 lines" errors ' +test_expect_success 'blame -L with invalid end and fuzzy-lines' ' + git blame -L1,5 tres --fuzzy-lines >out && + cat out && + test $(wc -l < out) -eq 2 +' + test_expect_success 'blame parses <end> part of -L' ' git blame -L1,1 tres >out && cat out && -- 2.14.1