libgit2/libgit2 — pull request #2181 by anuraggup (2014-03-11 19:18:30+00:00)
Title: Callback function to hide commit and its parents in revision walker

I had opened an issue https://github.com/libgit2/libgit2/issues/2173. In this issue, I suggested that revision walker should provide a capability to let users provide a callback function to hide a commit and its parents.

In this PR, I have added a callback function to hide commit and its parents in revision walker. I have added unit tests for the new functionality.

More details on this:

`git_revwalk` provides a means to walk revision (commit) tree by specifying the start commits using `git_revwalk_push` function and the stop commits by using `git_revwalk_hide` function.
This is a very simple mechanism to specify part of commit tree that the user is interested in. However, if the user wants to get commits using a reasonably complex criteria (e.g, commits made for last one month or commits where a particular file was added), `rev_walk` does not meet the requirements.
My proposal is to provide a mechanism to add a callback function, which will be called for every commit `rev_walk` visits. If callback function returns non-zero value, this commit and its parents will be hidden.

Signature of new function is as following:

```
/**
* This is a callback function that user can provide to hide a
* commit and its parents. If the callback function returns non-zero value,
* then this commit and its parents will be hidden.
*
* @param commit_id oid of Commit
* @param payload User-specified pointer to data to be passed as data payload
*/
typedef int(*git_revwalk_hide_cb)(
const git_oid *commit_id,
void *payload);

/**
* Adds a callback function to hide a commit and its parents
*
* @param walk the revision walker
* @param hide_cb callback function to hide a commit and its parents
* @param payload data payload to be passed to callback function
*/
GIT_EXTERN(int) git_revwalk_add_hide_cb(
git_revwalk *walk,
git_revwalk_hide_cb hide_cb,
void *payload);
```

I am keeping the term “hide” in the new function names to make it consistent with existing functions ( `git_revwalk_hide` ). Calling this function is optional. If such a callback is set, `process_commit` function will call this user-provided function to determine whether to hide this commit and its parents.
This will add a lot of flexibility in walking the tree. For example, if the user is looking for history of only one file or folder (since it was added), callback function will return false when tree of commit does not contain this file. This will make `revwalk` walk only the appropriate part of commit tree and hence improving the performance.