Git-Native
view release on metacpan or search on metacpan
lib/Git/Native/Revwalker.pm view on Meta::CPAN
my $self = shift;
my $raw = "\0" x 20;
my ($p) = scalar_to_buffer($raw);
my $rc = Git::Libgit2::FFI::git_revwalk_next( $p, $self->_handle );
return undef if $rc == GIT_ITEROVER;
check_rc $rc;
return Git::Native::Oid->from_raw($raw);
}
sub all {
my $self = shift;
my @out;
while ( defined( my $o = $self->next ) ) { push @out, $o }
return \@out;
}
sub DEMOLISH {
my $self = shift;
Git::Libgit2::FFI::git_revwalk_free( $self->{_handle} ) if $self->{_handle};
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Git::Native::Revwalker - Walk commits in topological / time order
=head1 VERSION
version 0.005
=head1 SYNOPSIS
my $walker = $repo->revwalker;
$walker->push_head;
$walker->sorting( Git::Native::Revwalker::GIT_SORT_TIME );
while ( my $oid = $walker->next ) {
say $oid->hex;
}
=head1 DESCRIPTION
Wraps libgit2's C<git_revwalk*>. Push starting points (commits, refs,
globs), optionally hide commits to exclude, then iterate with C<next>.
B<Seeding is mandatory.> A walker that has had no C<push_*> call has no
starting point and therefore yields nothing at all: C<next> returns
C<undef> straight away and C<all> gives an empty arrayref. There is no
implicit "walk HEAD" â say C<< $walker->push_head >> for that.
The walk goes from the pushed commits towards their ancestors, so a child
always comes out before its parents. Every C<push_*> and C<hide_*> returns
the walker, so seeding chains.
A walker keeps its repository alive for as long as it is in scope.
=head2 push_oid
$walker->push_oid($oid);
$walker->push_oid('35104eb6815e52f24b06c95cbc53e95943cb532b');
Add a commit as a starting point. C<$oid> is a L<Git::Native::Oid> or a
40-character hex string, and must resolve to something committish â a blob
OID throws a L<Git::Native::Error> ("object is not a committish").
=head2 push_head
$walker->push_head;
Start from whatever HEAD resolves to.
=head2 push_ref
$walker->push_ref('refs/heads/topic');
Start from the commit a reference points at. Throws if the ref does not
exist.
=head2 push_glob
$walker->push_glob('refs/heads/*');
Start from every reference matching the pattern at once â the union of all
those histories.
=head2 push_range
$walker->push_range("$old..$new");
Push C<B> and hide C<A> for a range written C<"A..B">, the same spelling
C<git log> takes.
=head2 hide_oid / hide_head / hide_ref / hide_glob
$walker->push_head->hide_ref('refs/heads/main');
Exclude a commit B<and all of its ancestors> from the walk â what makes
"on this branch but not on main" expressible. Same argument forms as the
matching C<push_*>.
=head2 sorting
$walker->sorting(
Git::Native::Revwalker::GIT_SORT_TIME | Git::Native::Revwalker::GIT_SORT_REVERSE
);
Set the ordering: a bitfield of C<GIT_SORT_NONE> (libgit2's default walk
order), C<GIT_SORT_TOPOLOGICAL>, C<GIT_SORT_TIME> and C<GIT_SORT_REVERSE>,
which are constants in this package and not exported.
Set it B<before the first C<next>>: changing the sorting mode of a walk
already in progress resets the walker, which drops the pushed starting
points along with it and leaves you iterating nothing.
=head2 reset
( run in 3.867 seconds using v1.01-cache-2.11-cpan-14f38c9f855 )