* [RFC] Possible optimization for gitweb
@ 2006-12-19 20:54 Robert Fitzsimons
2006-12-19 21:45 ` Jakub Narebski
2006-12-19 22:10 ` Junio C Hamano
0 siblings, 2 replies; 8+ messages in thread
From: Robert Fitzsimons @ 2006-12-19 20:54 UTC (permalink / raw)
To: git
While looking at the gitweb source yesterday, I noticed a number of
similar expensive workflows used by a number of actions (summary,
shortlog, log, rss, atom, and history).
The current workflows are:
get ~100 sha1's using rev-list
foreach sha1
get/parse 1 commit using rev-list
output commit
The new workflows I'm proposing would be:
get/parse ~100 commit's using rev-list
foreach commit
output commit
The following simplified commands gives an idea of the git only overhead
between these two workflows.
time \
for r in `git-rev-list --max-count=100 HEAD --` ; \
do git-rev-list --header --parents --max-count=1 $r -- ; \
done > /dev/null
real 0m0.490s
user 0m0.224s
sys 0m0.228s
time \
git-rev-list --header --parents --max-count=100 HEAD -- > /dev/null
real 0m0.058s
user 0m0.008s
sys 0m0.004s
There would seems to be a benefit from making the proposed change to
these workflows, when run on my machine against a clone of Linus's tree.
One issue with this change is that, gitweb is page orientated. Page 0
shows the first 100 items from a given hash, page 1 uses the same given
hash but show 100 to 199 items, etc. Using 'git-rev-list --header
--parents' and then throwing away most of the result is very wasteful.
So I'm suggesting we add a new option to git-rev-list which will only
start show results once its has iterated past a given number of items.
Using a caret or tilde doesn't seem to return the same result.
I've attached a discussion patch which adds a new option --start-count
to git-rev-list and changed the summary and showlog actions of gitweb to
use this new option.
I'm sure there are many improvements to this patch, comments?
Robert
-----
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 4059894..a1e0ccc 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -1260,6 +1260,30 @@ sub parse_tag {
return %tag
}
+sub parse_commits {
+ my $commit_id = shift;
+ my $start_count = shift;
+ my $max_count = shift;
+
+ my @cos;
+ my @commit_lines;
+
+ local $/ = "\0";
+ open my $fd, "-|", git_cmd(), "rev-list",
+ "--header", "--parents", "--start-count=$start_count", "--max-count=$max_count",
+ $commit_id, "--"
+ or return;
+ while (my $commit = <$fd>) {
+ @commit_lines = split '\n', $commit;
+ pop @commit_lines;
+ my %co = parse_commit(undef, \@commit_lines);
+ push @cos, \%co;
+ }
+ close $fd or return;
+
+ return @cos;
+}
+
sub parse_commit {
my $commit_id = shift;
my $commit_text = shift;
@@ -2633,29 +2657,29 @@ sub git_project_list_body {
sub git_shortlog_body {
# uses global variable $project
- my ($revlist, $from, $to, $refs, $extra) = @_;
+ my ($commitlist, $from, $to, $refs, $extra) = @_;
$from = 0 unless defined $from;
- $to = $#{$revlist} if (!defined $to || $#{$revlist} < $to);
+ $to = $#{$commitlist} if (!defined $to || $#{$commitlist} < $to);
print "<table class=\"shortlog\" cellspacing=\"0\">\n";
my $alternate = 1;
for (my $i = $from; $i <= $to; $i++) {
- my $commit = $revlist->[$i];
+ my $co = $commitlist->[$i];
+ my $commit = $co->{'id'};
#my $ref = defined $refs ? format_ref_marker($refs, $commit) : '';
my $ref = format_ref_marker($refs, $commit);
- my %co = parse_commit($commit);
if ($alternate) {
print "<tr class=\"dark\">\n";
} else {
print "<tr class=\"light\">\n";
}
$alternate ^= 1;
- # git_summary() used print "<td><i>$co{'age_string'}</i></td>\n" .
- print "<td title=\"$co{'age_string_age'}\"><i>$co{'age_string_date'}</i></td>\n" .
- "<td><i>" . esc_html(chop_str($co{'author_name'}, 10)) . "</i></td>\n" .
+ # git_summary() used print "<td><i>$co->{'age_string'}</i></td>\n" .
+ print "<td title=\"$co->{'age_string_age'}\"><i>$co->{'age_string_date'}</i></td>\n" .
+ "<td><i>" . esc_html(chop_str($co->{'author_name'}, 10)) . "</i></td>\n" .
"<td>";
- print format_subject_html($co{'title'}, $co{'title_short'},
+ print format_subject_html($co->{'title'}, $co->{'title_short'},
href(action=>"commit", hash=>$commit), $ref);
print "</td>\n" .
"<td class=\"link\">" .
@@ -2952,13 +2976,9 @@ sub git_summary {
}
}
- open my $fd, "-|", git_cmd(), "rev-list", "--max-count=17",
- git_get_head_hash($project), "--"
- or die_error(undef, "Open git-rev-list failed");
- my @revlist = map { chomp; $_ } <$fd>;
- close $fd;
+ my @commitlist = parse_commits($head, 0, 17);
git_print_header_div('shortlog');
- git_shortlog_body(\@revlist, 0, 15, $refs,
+ git_shortlog_body(\@commitlist, 0, 15, $refs,
$cgi->a({-href => href(action=>"shortlog")}, "..."));
if (@taglist) {
@@ -4313,15 +4333,12 @@ sub git_shortlog {
}
my $refs = git_get_references();
- my $limit = sprintf("--max-count=%i", (100 * ($page+1)));
- open my $fd, "-|", git_cmd(), "rev-list", $limit, $hash, "--"
- or die_error(undef, "Open git-rev-list failed");
- my @revlist = map { chomp; $_ } <$fd>;
- close $fd;
+ my $max_count = (100 * ($page+1));
+ my @commitlist = parse_commits($hash, (100 * $page), $max_count);
- my $paging_nav = format_paging_nav('shortlog', $hash, $head, $page, $#revlist);
+ my $paging_nav = format_paging_nav('shortlog', $hash, $head, $page, $max_count);
my $next_link = '';
- if ($#revlist >= (100 * ($page+1)-1)) {
+ if ($max_count >= 100) {
$next_link =
$cgi->a({-href => href(action=>"shortlog", hash=>$hash, page=>$page+1),
-title => "Alt-n"}, "next");
@@ -4332,7 +4349,7 @@ sub git_shortlog {
git_print_page_nav('shortlog','', $hash,$hash,$hash, $paging_nav);
git_print_header_div('summary', $project);
- git_shortlog_body(\@revlist, ($page * 100), $#revlist, $refs, $next_link);
+ git_shortlog_body(\@commitlist, 0, $#commitlist, $refs, $next_link);
git_footer_html();
}
diff --git a/list-objects.c b/list-objects.c
index f1fa21c..d96c8bf 100644
--- a/list-objects.c
+++ b/list-objects.c
@@ -108,8 +108,12 @@ void traverse_commit_list(struct rev_info *revs,
struct object_array objects = { 0, 0, NULL };
while ((commit = get_revision(revs)) != NULL) {
- process_tree(revs, commit->tree, &objects, NULL, "");
- show_commit(commit);
+ if (revs->start_count <= 0) {
+ process_tree(revs, commit->tree, &objects, NULL, "");
+ show_commit(commit);
+ } else {
+ revs->start_count--;
+ }
}
for (i = 0; i < revs->pending.nr; i++) {
struct object_array_entry *pending = revs->pending.objects + i;
diff --git a/revision.c b/revision.c
index 993bb66..3e3d929 100644
--- a/revision.c
+++ b/revision.c
@@ -524,6 +524,7 @@ void init_revisions(struct rev_info *revs, const char *prefix)
revs->prefix = prefix;
revs->max_age = -1;
revs->min_age = -1;
+ revs->start_count = -1;
revs->max_count = -1;
revs->prune_fn = NULL;
@@ -756,6 +757,10 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
const char *arg = argv[i];
if (*arg == '-') {
int opts;
+ if (!strncmp(arg, "--start-count=", 14)) {
+ revs->start_count = atoi(arg + 14);
+ continue;
+ }
if (!strncmp(arg, "--max-count=", 12)) {
revs->max_count = atoi(arg + 12);
continue;
diff --git a/revision.h b/revision.h
index 3adab95..c2dce8c 100644
--- a/revision.h
+++ b/revision.h
@@ -75,6 +75,7 @@ struct rev_info {
struct grep_opt *grep_filter;
/* special limits */
+ int start_count;
int max_count;
unsigned long max_age;
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [RFC] Possible optimization for gitweb
2006-12-19 20:54 [RFC] Possible optimization for gitweb Robert Fitzsimons
@ 2006-12-19 21:45 ` Jakub Narebski
2006-12-20 0:52 ` Robert Fitzsimons
2006-12-19 22:10 ` Junio C Hamano
1 sibling, 1 reply; 8+ messages in thread
From: Jakub Narebski @ 2006-12-19 21:45 UTC (permalink / raw)
To: git
[Please send replies Cc: git mailing list]
Robert Fitzsimons wrote:
> While looking at the gitweb source yesterday, I noticed a number of
> similar expensive workflows used by a number of actions (summary,
> shortlog, log, rss, atom, and history).
>
> The current workflows are:
> get ~100 sha1's using rev-list
> foreach sha1
> get/parse 1 commit using rev-list
> output commit
>
> The new workflows I'm proposing would be:
> get/parse ~100 commit's using rev-list
> foreach commit
> output commit
I have tried this approach too. Take a look at
http://repo.or.cz/w/git/jnareb-git.git?a=log;h=Attic/gitweb/parse_rev_list
or at discussion started with
Message-Id: <200609061504.40725.jnareb@gmail.com>
http://mid.gmane.org/200609061504.40725.jnareb@gmail.com
> The following simplified commands gives an idea of the git only overhead
> between these two workflows.
>
> time \
> for r in `git-rev-list --max-count=100 HEAD --` ; \
> do git-rev-list --header --parents --max-count=1 $r -- ; \
> done > /dev/null
>
> real 0m0.490s
> user 0m0.224s
> sys 0m0.228s
>
> time \
> git-rev-list --header --parents --max-count=100 HEAD -- > /dev/null
>
> real 0m0.058s
> user 0m0.008s
> sys 0m0.004s
>
> There would seems to be a benefit from making the proposed change to
> these workflows, when run on my machine against a clone of Linus's tree.
The problem is that it works only for "log" and "shortlog" views, but
it doesn't work for "history" view. Now both share the same infrastructure.
The problem is that when there is path limiter (be it file or directory)
the history is simplified, and parents are _rewritten_ according to
simplified history. And this happen depending on strange combination
of --header, --parents and --full-history. Should be somewhere in archives.
And we don't want to use parents from commit object, because there might
be grafts, or it might be shallow clone.
On the other hand, we don't really need parents for log, shortlog and
history...
> One issue with this change is that, gitweb is page orientated. Page 0
> shows the first 100 items from a given hash, page 1 uses the same given
> hash but show 100 to 199 items, etc. Using 'git-rev-list --header
> --parents' and then throwing away most of the result is very wasteful.
>
> So I'm suggesting we add a new option to git-rev-list which will only
> start show results once its has iterated past a given number of items.
> Using a caret or tilde doesn't seem to return the same result.
>
> I've attached a discussion patch which adds a new option --start-count
> to git-rev-list and changed the summary and showlog actions of gitweb to
> use this new option.
Very nice idea.
> I'm sure there are many improvements to this patch, comments?
Perhaps this patch should be split in two? (Usually either second mail is
reply to first mail, or both are replies to introductory letter, usually
with table of contents and diffstat of series).
[...]
Documentation (of --start-count / --skip option), please?
P.S. Thanks for the patches.
P.P.S. Do you have any comments to latest "[RFC] gitweb wishlist and TODO
list" series?
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC] Possible optimization for gitweb
2006-12-19 20:54 [RFC] Possible optimization for gitweb Robert Fitzsimons
2006-12-19 21:45 ` Jakub Narebski
@ 2006-12-19 22:10 ` Junio C Hamano
2006-12-19 22:22 ` Jakub Narebski
1 sibling, 1 reply; 8+ messages in thread
From: Junio C Hamano @ 2006-12-19 22:10 UTC (permalink / raw)
To: Robert Fitzsimons; +Cc: git
Robert Fitzsimons <robfitz@273k.net> writes:
> The new workflows I'm proposing would be:
> get/parse ~100 commit's using rev-list
> foreach commit
> output commit
Absolutely.
And Ok on rev-list part, but perhaps --skip would be more
appropriate name.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC] Possible optimization for gitweb
2006-12-19 22:10 ` Junio C Hamano
@ 2006-12-19 22:22 ` Jakub Narebski
2006-12-20 0:29 ` [PATCH] rev-list: Add a new option --skip Robert Fitzsimons
0 siblings, 1 reply; 8+ messages in thread
From: Jakub Narebski @ 2006-12-19 22:22 UTC (permalink / raw)
To: git
[Please Cc: git@vger.kernel.org]
Junio C Hamano wrote:
> Robert Fitzsimons <robfitz@273k.net> writes:
>
>> The new workflows I'm proposing would be:
>> get/parse ~100 commit's using rev-list
>> foreach commit
>> output commit
>
> Absolutely.
>
> And Ok on rev-list part, but perhaps --skip would be more
> appropriate name.
The only problem that you can't use --parents with "history" view, because
together with --full-history it shows also all merges (--full-history
without --parents doesn't show merges which does not affect given file or
directory; the sequence in which --parents and --full-history are taken is
a bit strange to me). So you have to keep current parse_commit (or extend
it), and if I remember correctly you do that.
I'm also for --skip (not --start-count), although... --start-count with
--max-count seems more natural; one place it can be confusing is that we
count skipped commits or not? I.e. we use --start-count=10 --max-count=20
to get second 10 of commits, or --skip=10 --max-count=10 to get second 10
of commits?
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH] rev-list: Add a new option --skip.
2006-12-19 22:22 ` Jakub Narebski
@ 2006-12-20 0:29 ` Robert Fitzsimons
2006-12-20 1:09 ` Junio C Hamano
0 siblings, 1 reply; 8+ messages in thread
From: Robert Fitzsimons @ 2006-12-20 0:29 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
Added a new option --skip=<N> which is used to allow the caller to
specify how many commit items to skip before displaying the commit
output. This option is most useful for programs which want to display
fixed length pages of commit items, i.e. gitweb.
Signed-off-by: Robert Fitzsimons <robfitz@273k.net>
---
> I'm also for --skip (not --start-count), although... --start-count with
> --max-count seems more natural; one place it can be confusing is that we
> count skipped commits or not? I.e. we use --start-count=10 --max-count=20
> to get second 10 of commits, or --skip=10 --max-count=10 to get second 10
> of commits?
Here's the patch with the renamed option. It also does not count
skipped commits, so --skip=10 --max-count=10 will display 10 items.
Robert
Documentation/git-rev-list.txt | 5 +++++
builtin-rev-list.c | 17 +++++++++++++++++
list-objects.c | 8 ++++++--
revision.c | 1 +
revision.h | 1 +
5 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt
index ec43c0b..7c86abc 100644
--- a/Documentation/git-rev-list.txt
+++ b/Documentation/git-rev-list.txt
@@ -12,6 +12,7 @@ SYNOPSIS
'git-rev-list' [ \--max-count=number ]
[ \--max-age=timestamp ]
[ \--min-age=timestamp ]
+ [ \--skip=number ]
[ \--sparse ]
[ \--no-merges ]
[ \--remove-empty ]
@@ -151,6 +152,10 @@ limiting may be applied.
Limit the commits output to specified time range.
+--skip='number'::
+
+ Skip 'number' commits before starting to display commit output.
+
--author='pattern', --committer='pattern'::
Limit the commits output to ones with author/committer
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index fb7fc92..432f901 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -20,6 +20,7 @@ static const char rev_list_usage[] =
" --max-count=nr\n"
" --max-age=epoch\n"
" --min-age=epoch\n"
+" --skip=nr\n"
" --sparse\n"
" --no-merges\n"
" --remove-empty\n"
@@ -219,6 +220,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
struct commit_list *list;
int i;
int read_from_stdin = 0;
+ int skip = -1;
init_revisions(&revs, prefix);
revs.abbrev = 0;
@@ -246,6 +248,10 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
read_revisions_from_stdin(&revs);
continue;
}
+ if (!strncmp(arg, "--skip=", 7)) {
+ skip = atoi(arg + 7);
+ continue;
+ }
usage(rev_list_usage);
}
@@ -261,6 +267,17 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
/* Only --header was specified */
revs.commit_format = CMIT_FMT_RAW;
+ /*
+ * If a skip value is specified set start_count appropriately,
+ * and if max_count is set it should be adjusted to account
+ * for the skip value.
+ */
+ if (skip > 0) {
+ revs.start_count = skip;
+ if (revs.max_count > 0)
+ revs.max_count += skip;
+ }
+
list = revs.commits;
if ((!list &&
diff --git a/list-objects.c b/list-objects.c
index f1fa21c..d96c8bf 100644
--- a/list-objects.c
+++ b/list-objects.c
@@ -108,8 +108,12 @@ void traverse_commit_list(struct rev_info *revs,
struct object_array objects = { 0, 0, NULL };
while ((commit = get_revision(revs)) != NULL) {
- process_tree(revs, commit->tree, &objects, NULL, "");
- show_commit(commit);
+ if (revs->start_count <= 0) {
+ process_tree(revs, commit->tree, &objects, NULL, "");
+ show_commit(commit);
+ } else {
+ revs->start_count--;
+ }
}
for (i = 0; i < revs->pending.nr; i++) {
struct object_array_entry *pending = revs->pending.objects + i;
diff --git a/revision.c b/revision.c
index 993bb66..70f4861 100644
--- a/revision.c
+++ b/revision.c
@@ -524,6 +524,7 @@ void init_revisions(struct rev_info *revs, const char *prefix)
revs->prefix = prefix;
revs->max_age = -1;
revs->min_age = -1;
+ revs->start_count = -1;
revs->max_count = -1;
revs->prune_fn = NULL;
diff --git a/revision.h b/revision.h
index 3adab95..c2dce8c 100644
--- a/revision.h
+++ b/revision.h
@@ -75,6 +75,7 @@ struct rev_info {
struct grep_opt *grep_filter;
/* special limits */
+ int start_count;
int max_count;
unsigned long max_age;
unsigned long min_age;
--
1.4.4.2.g80fef-dirty
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH] rev-list: Add a new option --skip.
2006-12-20 0:29 ` [PATCH] rev-list: Add a new option --skip Robert Fitzsimons
@ 2006-12-20 1:09 ` Junio C Hamano
2006-12-20 14:59 ` [PATCH] rev-list: Document --skip and add test cases Robert Fitzsimons
0 siblings, 1 reply; 8+ messages in thread
From: Junio C Hamano @ 2006-12-20 1:09 UTC (permalink / raw)
To: Robert Fitzsimons; +Cc: git
Robert Fitzsimons <robfitz@273k.net> writes:
> diff --git a/builtin-rev-list.c b/builtin-rev-list.c
> index fb7fc92..432f901 100644
> --- a/builtin-rev-list.c
> +++ b/builtin-rev-list.c
> @@ -246,6 +248,10 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
> read_revisions_from_stdin(&revs);
> continue;
> }
> + if (!strncmp(arg, "--skip=", 7)) {
> + skip = atoi(arg + 7);
> + continue;
> + }
> usage(rev_list_usage);
>
> }
Hmph....
I am having a hard time convincing myself that this is a feature
that is a narrow special case for rev-list and does not belong
to the generic revision traversal machinery.
That is, would people expect that 'log' family allow the to say:
$ git log --skip=10 -4 master
Declaring this as a special case for rev-list is certainly safer
(no risk to harm the revision machinery which is quite central
part of git), but if you define and initialize the new field
next to max_count, it makes me feel that it should somehow be
handled at the same layer.
In other words,...
---
revision.c | 46 ++++++++++++++++++++++++++++++++--------------
revision.h | 1 +
2 files changed, 33 insertions(+), 14 deletions(-)
diff --git a/revision.c b/revision.c
index 993bb66..aa63d10 100644
--- a/revision.c
+++ b/revision.c
@@ -524,6 +524,7 @@ void init_revisions(struct rev_info *revs, const char *prefix)
revs->prefix = prefix;
revs->max_age = -1;
revs->min_age = -1;
+ revs->skip_count = -1;
revs->max_count = -1;
revs->prune_fn = NULL;
@@ -760,6 +761,10 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
revs->max_count = atoi(arg + 12);
continue;
}
+ if (!strncmp(arg, "--skip=", 7)) {
+ revs->skip_count = atoi(arg + 7);
+ continue;
+ }
/* accept -<digit>, like traditional "head" */
if ((*arg == '-') && isdigit(arg[1])) {
revs->max_count = atoi(arg + 1);
@@ -1123,23 +1128,11 @@ static int commit_match(struct commit *commit, struct rev_info *opt)
commit->buffer, strlen(commit->buffer));
}
-struct commit *get_revision(struct rev_info *revs)
+static struct commit *get_revision_1(struct rev_info *revs)
{
- struct commit_list *list = revs->commits;
-
- if (!list)
+ if (!revs->commits)
return NULL;
- /* Check the max_count ... */
- switch (revs->max_count) {
- case -1:
- break;
- case 0:
- return NULL;
- default:
- revs->max_count--;
- }
-
do {
struct commit_list *entry = revs->commits;
struct commit *commit = entry->item;
@@ -1206,3 +1199,28 @@ struct commit *get_revision(struct rev_info *revs)
} while (revs->commits);
return NULL;
}
+
+struct commit *get_revision(struct rev_info *revs)
+{
+ struct commit *c = NULL;
+
+ if (0 < revs->skip_count) {
+ while ((c = get_revision_1(revs)) != NULL) {
+ if (revs->skip_count-- <= 0)
+ break;
+ }
+ }
+
+ /* Check the max_count ... */
+ switch (revs->max_count) {
+ case -1:
+ break;
+ case 0:
+ return NULL;
+ default:
+ revs->max_count--;
+ }
+ if (c)
+ return c;
+ return get_revision_1(revs);
+}
diff --git a/revision.h b/revision.h
index 3adab95..81f522c 100644
--- a/revision.h
+++ b/revision.h
@@ -75,6 +75,7 @@ struct rev_info {
struct grep_opt *grep_filter;
/* special limits */
+ int skip_count;
int max_count;
unsigned long max_age;
unsigned long min_age;
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH] rev-list: Document --skip and add test cases.
2006-12-20 1:09 ` Junio C Hamano
@ 2006-12-20 14:59 ` Robert Fitzsimons
0 siblings, 0 replies; 8+ messages in thread
From: Robert Fitzsimons @ 2006-12-20 14:59 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Robert Fitzsimons, git
Signed-off-by: Robert Fitzsimons <robfitz@273k.net>
---
> I am having a hard time convincing myself that this is a feature
> that is a narrow special case for rev-list and does not belong
> to the generic revision traversal machinery.
Your implementation is much better then mine. Here's some documentation
and a set of test cases.
Robert
Documentation/git-rev-list.txt | 5 ++++
t/t6005-rev-list-count.sh | 51 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 56 insertions(+), 0 deletions(-)
diff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt
index ec43c0b..9e0dcf8 100644
--- a/Documentation/git-rev-list.txt
+++ b/Documentation/git-rev-list.txt
@@ -10,6 +10,7 @@ SYNOPSIS
--------
[verse]
'git-rev-list' [ \--max-count=number ]
+ [ \--skip=number ]
[ \--max-age=timestamp ]
[ \--min-age=timestamp ]
[ \--sparse ]
@@ -139,6 +140,10 @@ limiting may be applied.
Limit the number of commits output.
+--skip='number'::
+
+ Skip 'number' commits before starting to show the commit output.
+
--since='date', --after='date'::
Show commits more recent than a specific date.
diff --git a/t/t6005-rev-list-count.sh b/t/t6005-rev-list-count.sh
new file mode 100755
index 0000000..334fccf
--- /dev/null
+++ b/t/t6005-rev-list-count.sh
@@ -0,0 +1,51 @@
+#!/bin/sh
+
+test_description='git-rev-list --max-count and --skip test'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ for n in 1 2 3 4 5 ; do \
+ echo $n > a ; \
+ git add a ; \
+ git commit -m "$n" ; \
+ done
+'
+
+test_expect_success 'no options' '
+ test $(git-rev-list HEAD | wc -l) = 5
+'
+
+test_expect_success '--max-count' '
+ test $(git-rev-list HEAD --max-count=0 | wc -l) = 0 &&
+ test $(git-rev-list HEAD --max-count=3 | wc -l) = 3 &&
+ test $(git-rev-list HEAD --max-count=5 | wc -l) = 5 &&
+ test $(git-rev-list HEAD --max-count=10 | wc -l) = 5
+'
+
+test_expect_success '--max-count all forms' '
+ test $(git-rev-list HEAD --max-count=1 | wc -l) = 1 &&
+ test $(git-rev-list HEAD -1 | wc -l) = 1 &&
+ test $(git-rev-list HEAD -n1 | wc -l) = 1 &&
+ test $(git-rev-list HEAD -n 1 | wc -l) = 1
+'
+
+test_expect_success '--skip' '
+ test $(git-rev-list HEAD --skip=0 | wc -l) = 5 &&
+ test $(git-rev-list HEAD --skip=3 | wc -l) = 2 &&
+ test $(git-rev-list HEAD --skip=5 | wc -l) = 0 &&
+ test $(git-rev-list HEAD --skip=10 | wc -l) = 0
+'
+
+test_expect_success '--skip --max-count' '
+ test $(git-rev-list HEAD --skip=0 --max-count=0 | wc -l) = 0 &&
+ test $(git-rev-list HEAD --skip=0 --max-count=10 | wc -l) = 5 &&
+ test $(git-rev-list HEAD --skip=3 --max-count=0 | wc -l) = 0 &&
+ test $(git-rev-list HEAD --skip=3 --max-count=1 | wc -l) = 1 &&
+ test $(git-rev-list HEAD --skip=3 --max-count=2 | wc -l) = 2 &&
+ test $(git-rev-list HEAD --skip=3 --max-count=10 | wc -l) = 2 &&
+ test $(git-rev-list HEAD --skip=5 --max-count=10 | wc -l) = 0 &&
+ test $(git-rev-list HEAD --skip=10 --max-count=10 | wc -l) = 0
+'
+
+test_done
--
1.4.4.2.g80fef-dirty
^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2006-12-20 15:00 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-12-19 20:54 [RFC] Possible optimization for gitweb Robert Fitzsimons
2006-12-19 21:45 ` Jakub Narebski
2006-12-20 0:52 ` Robert Fitzsimons
2006-12-19 22:10 ` Junio C Hamano
2006-12-19 22:22 ` Jakub Narebski
2006-12-20 0:29 ` [PATCH] rev-list: Add a new option --skip Robert Fitzsimons
2006-12-20 1:09 ` Junio C Hamano
2006-12-20 14:59 ` [PATCH] rev-list: Document --skip and add test cases Robert Fitzsimons
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).