NAME

Git::Native::Revwalker - Walk commits in topological / time order

VERSION

version 0.005

SYNOPSIS

my $walker = $repo->revwalker;
$walker->push_head;
$walker->sorting( Git::Native::Revwalker::GIT_SORT_TIME );
while ( my $oid = $walker->next ) {
  say $oid->hex;
}

DESCRIPTION

Wraps libgit2's git_revwalk*. Push starting points (commits, refs, globs), optionally hide commits to exclude, then iterate with next.

Seeding is mandatory. A walker that has had no push_* call has no starting point and therefore yields nothing at all: next returns undef straight away and all gives an empty arrayref. There is no implicit "walk HEAD" — say $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 push_* and hide_* returns the walker, so seeding chains.

A walker keeps its repository alive for as long as it is in scope.

push_oid

$walker->push_oid($oid);
$walker->push_oid('35104eb6815e52f24b06c95cbc53e95943cb532b');

Add a commit as a starting point. $oid is a Git::Native::Oid or a 40-character hex string, and must resolve to something committish — a blob OID throws a Git::Native::Error ("object is not a committish").

push_head

$walker->push_head;

Start from whatever HEAD resolves to.

push_ref

$walker->push_ref('refs/heads/topic');

Start from the commit a reference points at. Throws if the ref does not exist.

push_glob

$walker->push_glob('refs/heads/*');

Start from every reference matching the pattern at once — the union of all those histories.

push_range

$walker->push_range("$old..$new");

Push B and hide A for a range written "A..B", the same spelling git log takes.

hide_oid / hide_head / hide_ref / hide_glob

$walker->push_head->hide_ref('refs/heads/main');

Exclude a commit and all of its ancestors from the walk — what makes "on this branch but not on main" expressible. Same argument forms as the matching push_*.

sorting

$walker->sorting(
  Git::Native::Revwalker::GIT_SORT_TIME | Git::Native::Revwalker::GIT_SORT_REVERSE
);

Set the ordering: a bitfield of GIT_SORT_NONE (libgit2's default walk order), GIT_SORT_TOPOLOGICAL, GIT_SORT_TIME and GIT_SORT_REVERSE, which are constants in this package and not exported.

Set it before the first 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.

reset

$walker->reset->push_ref('refs/heads/other');

Return the walker to its just-created state so it can be used for a different walk. This clears the pushed and hidden commits as well as the sorting mode — re-seed before iterating again, or the walk is empty.

simplify_first_parent

$walker->push_head->simplify_first_parent;

Follow only the first parent of each commit, so a merge does not pull the merged-in side branch into the walk. Applies to the walking still to come.

next

while ( defined( my $oid = $walker->next ) ) { ... }

The next Git::Native::Oid, or undef once the walk is exhausted — libgit2's GIT_ITEROVER is the normal end of iteration and is not raised as an error. Real failures still throw a Git::Native::Error.

all

my $oids = $walker->all;

Drain the walker from where it stands into an arrayref of Git::Native::Oid. It consumes the same iterator next does, so a second all without a reset and fresh push_* comes back empty.

SEE ALSO

Git::Native::Repository, Git::Native::Commit, Git::Native::Oid

SUPPORT

Issues

Please report bugs and feature requests on GitHub at https://github.com/Getty/p5-git-native/issues.

CONTRIBUTING

Contributions are welcome! Please fork the repository and submit a pull request.

AUTHOR

Torsten Raudssus <getty@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2026 by Torsten Raudssus <torsten@raudssus.de> https://raudssus.de/.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.