diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt index fd4f4e26c9..195e74eec6 100644 --- a/Documentation/rev-list-options.txt +++ b/Documentation/rev-list-options.txt @@ -25,6 +25,11 @@ ordering and formatting options, such as `--reverse`. --after=:: Show commits more recent than a specific date. +--since-as-filter=:: + Show all commits more recent than a specific date. This visits + all commits in the range, rather than stopping at the first commit which + is older than a specific date. + --until=:: --before=:: Show commits older than a specific date. diff --git a/revision.c b/revision.c index 7d435f8048..c367273c00 100644 --- a/revision.c +++ b/revision.c @@ -1440,6 +1440,9 @@ static int limit_list(struct rev_info *revs) if (revs->min_age != -1 && (commit->date > revs->min_age) && !revs->line_level_traverse) continue; + if (revs->max_age_as_filter != -1 && + (commit->date < revs->max_age_as_filter) && !revs->line_level_traverse) + continue; date = commit->date; p = &commit_list_insert(commit, p)->next; @@ -1838,6 +1841,7 @@ void repo_init_revisions(struct repository *r, revs->dense = 1; revs->prefix = prefix; revs->max_age = -1; + revs->max_age_as_filter = -1; revs->min_age = -1; revs->skip_count = -1; revs->max_count = -1; @@ -2218,6 +2222,9 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg } else if ((argcount = parse_long_opt("since", argv, &optarg))) { revs->max_age = approxidate(optarg); return argcount; + } else if ((argcount = parse_long_opt("since-as-filter", argv, &optarg))) { + revs->max_age_as_filter = approxidate(optarg); + return argcount; } else if ((argcount = parse_long_opt("after", argv, &optarg))) { revs->max_age = approxidate(optarg); return argcount; @@ -3862,6 +3869,9 @@ enum commit_action get_commit_action(struct rev_info *revs, struct commit *commi if (revs->min_age != -1 && comparison_date(revs, commit) > revs->min_age) return commit_ignore; + if (revs->max_age_as_filter != -1 && + comparison_date(revs, commit) < revs->max_age_as_filter) + return commit_ignore; if (revs->min_parents || (revs->max_parents >= 0)) { int n = commit_list_count(commit->parents); if ((n < revs->min_parents) || diff --git a/revision.h b/revision.h index 5bc59c7bfe..e80c148b19 100644 --- a/revision.h +++ b/revision.h @@ -263,6 +263,7 @@ struct rev_info { int skip_count; int max_count; timestamp_t max_age; + timestamp_t max_age_as_filter; timestamp_t min_age; int min_parents; int max_parents; diff --git a/t/t4217-log-limit.sh b/t/t4217-log-limit.sh new file mode 100755 index 0000000000..6e01e2629c --- /dev/null +++ b/t/t4217-log-limit.sh @@ -0,0 +1,41 @@ +#!/bin/sh + +test_description='git log with filter options limiting the output' + +. ./test-lib.sh + +test_expect_success 'setup test' ' + git init && + echo a >file && + git add file && + GIT_COMMITTER_DATE="2021-02-01 00:00" git commit -m init && + echo a >>file && + git add file && + GIT_COMMITTER_DATE="2022-02-01 00:00" git commit -m first && + echo a >>file && + git add file && + GIT_COMMITTER_DATE="2021-03-01 00:00" git commit -m second && + echo a >>file && + git add file && + GIT_COMMITTER_DATE="2022-03-01 00:00" git commit -m third +' + +test_expect_success 'git log --since-as-filter=...' ' + git log --since-as-filter="2022-01-01" --format=%s >actual && + cat >expect <<-\EOF && + third + first + EOF + test_cmp expect actual +' + +test_expect_success 'git log --children --since-as-filter=...' ' + git log --children --since-as-filter="2022-01-01" --format=%s >actual && + cat >expect <<-\EOF && + third + first + EOF + test_cmp expect actual +' + +test_done