Skip to content

Commit 21230b1

Browse files
Mroikgitster
authored andcommitted
revision.c: implement --max-count-oldest
--max-count is a commit limiting option sets a maximum amount of commits to be shown. If a user wants to see only the first N commits of the history (the oldest commits) they'd have to combine --max-count with --skip. This is not very user-friendly. Teach get_revision() the --max-count-oldest option. Signed-off-by: Mirko Faina <mroik@delayed.space> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 94f0577 commit 21230b1

4 files changed

Lines changed: 93 additions & 3 deletions

File tree

Documentation/rev-list-options.adoc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ ordering and formatting options, such as `--reverse`.
1818
`--max-count=<number>`::
1919
Limit the output to _<number>_ commits.
2020

21+
`--max-count-oldest=<number>`::
22+
Limit the output to the _<number>_ oldest commits.
23+
2124
`--skip=<number>`::
2225
Skip _<number>_ commits before starting to show the commit output.
2326

revision.c

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2339,10 +2339,24 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
23392339
}
23402340

23412341
if ((argcount = parse_long_opt("max-count", argv, &optarg))) {
2342+
if (revs->max_count_type == 1)
2343+
die(_("can't use --max-count with --max-count-oldest"));
23422344
revs->max_count = parse_count(optarg);
23432345
revs->no_walk = 0;
2346+
revs->max_count_type = 0;
23442347
return argcount;
2348+
} else if ((argcount = parse_long_opt("max-count-oldest", argv, &optarg))) {
2349+
if (revs->max_count_type == 0 && revs->max_count != -1)
2350+
die(_("can't use --max-count with --max-count-oldest"));
2351+
if (revs->skip_count > 0)
2352+
die(_("con't use --max-count-oldest with --skip"));
2353+
revs->max_count = parse_count(optarg);
2354+
revs->no_walk = 0;
2355+
revs->max_count_type = 1;
2356+
revs->max_count_stage = 0;
23452357
} else if ((argcount = parse_long_opt("skip", argv, &optarg))) {
2358+
if (revs->max_count_type == 1)
2359+
die(_("con't use --max-count-oldest with --skip"));
23462360
revs->skip_count = parse_count(optarg);
23472361
return argcount;
23482362
} else if ((*arg == '-') && isdigit(arg[1])) {
@@ -4521,15 +4535,68 @@ static struct commit *get_revision_internal(struct rev_info *revs)
45214535
return c;
45224536
}
45234537

4538+
static void retrieve_oldest_commits(struct rev_info *revs,
4539+
struct commit_list **queue)
4540+
{
4541+
struct commit *c;
4542+
int max_count = revs->max_count;
4543+
int queuei_count = 0;
4544+
int queueo_count = 0;
4545+
struct commit_list *queueo = NULL;
4546+
struct commit_list *queuei = NULL;
4547+
struct commit_list *reversed_queue = NULL;
4548+
4549+
revs->max_count = -1;
4550+
while ((c = get_revision_internal(revs))) {
4551+
c->object.flags &= ~SHOWN;
4552+
commit_list_insert(c, &queuei);
4553+
queuei_count++;
4554+
while (queuei_count + queueo_count > max_count) {
4555+
if (!queueo_count) {
4556+
while (queuei_count > 0) {
4557+
c = pop_commit(&queuei);
4558+
queuei_count--;
4559+
commit_list_insert(c, &queueo);
4560+
queueo_count++;
4561+
}
4562+
}
4563+
pop_commit(&queueo);
4564+
queueo_count--;
4565+
}
4566+
}
4567+
4568+
while ((c = pop_commit(&queueo)))
4569+
commit_list_insert(c, &reversed_queue);
4570+
while ((c = pop_commit(&queuei)))
4571+
commit_list_insert(c, &queueo);
4572+
while ((c = pop_commit(&queueo)))
4573+
commit_list_insert(c, &reversed_queue);
4574+
4575+
while ((c = pop_commit(&reversed_queue)))
4576+
commit_list_insert(c, queue);
4577+
}
4578+
45244579
struct commit *get_revision(struct rev_info *revs)
45254580
{
45264581
struct commit *c;
45274582
struct commit_list *reversed;
4583+
struct commit_list *queue = NULL;
4584+
4585+
if (revs->max_count_type == 1 && !revs->max_count_stage) {
4586+
retrieve_oldest_commits(revs, &queue);
4587+
commit_list_free(revs->commits);
4588+
revs->commits = queue;
4589+
revs->max_count_stage = 1;
4590+
}
45284591

45294592
if (revs->reverse) {
45304593
reversed = NULL;
4531-
while ((c = get_revision_internal(revs)))
4532-
commit_list_insert(c, &reversed);
4594+
if (revs->max_count_type == 1)
4595+
while ((c = pop_commit(&revs->commits)))
4596+
commit_list_insert(c, &reversed);
4597+
else
4598+
while ((c = get_revision_internal(revs)))
4599+
commit_list_insert(c, &reversed);
45334600
commit_list_free(revs->commits);
45344601
revs->commits = reversed;
45354602
revs->reverse = 0;
@@ -4543,7 +4610,11 @@ struct commit *get_revision(struct rev_info *revs)
45434610
return c;
45444611
}
45454612

4546-
c = get_revision_internal(revs);
4613+
if (revs->max_count_stage)
4614+
c = pop_commit(&revs->commits);
4615+
else
4616+
c = get_revision_internal(revs);
4617+
45474618
if (c && revs->graph)
45484619
graph_update(revs->graph, c);
45494620
if (!c) {

revision.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,8 @@ struct rev_info {
309309
/* special limits */
310310
int skip_count;
311311
int max_count;
312+
unsigned int max_count_type:1;
313+
unsigned int max_count_stage:1;
312314
timestamp_t max_age;
313315
timestamp_t max_age_as_filter;
314316
timestamp_t min_age;

t/t4202-log.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1882,6 +1882,20 @@ test_expect_success 'log --graph with --name-status' '
18821882
test_cmp_graph --name-status tangle..reach
18831883
'
18841884

1885+
test_expect_success 'log --max-count-oldest=3 --oneline' '
1886+
test_when_finished rm expect &&
1887+
git log --oneline | tail -n3 >expect &&
1888+
git log --oneline --max-count-oldest=3 >actual &&
1889+
test_cmp expect actual
1890+
'
1891+
1892+
test_expect_success 'log --max-count-oldest=3 --reverse --oneline' '
1893+
test_when_finished rm expect &&
1894+
git log --oneline | tail -n3 | tac >expect &&
1895+
git log --oneline --max-count-oldest=3 --reverse >actual &&
1896+
test_cmp expect actual
1897+
'
1898+
18851899
cat >expect <<-\EOF
18861900
* reach
18871901
|

0 commit comments

Comments
 (0)