I find the convention of using a callback function so the caller can tell you when to stop iterating awkward.

I would prefer to have this behave like an iterator that the caller can invoke to get the next Revision built and returned to them, and expose a release() method that the caller can use to clean up your RevWalk. That implies moving the RevWalk and TreeWalk into instance members. But the API then starts to work and behave like RevWalk itself, making it more consistent.