libgit2/libgit2 — pull request #684 by benstraub (2012-05-11 19:02:29+00:00)
Title: Rev parse

*[This is a rebased version of #648.]*

Support for the [rev-parse revision-specification language](http://schacon.github.com/git/git-rev-parse.html#_specifying_revisions), which takes a string and provides a `git_object`. So far, these are working:

* `a65fedf39aefe402d3bb6e24df4d4f5fe4547750` -> object with that exact hash
* `a65fedf39a` -> object with that hash prefix (uses `git_object_lookup_prefix`)
* `v0.16.0-234-gd98fa70` (output from `git describe`) -> object with the hash prefix that follows "-g"
* `refs/heads/master` or `master` -> object pointed to by a fully- or partially-named ref
* `tag^{}` -> dereference until we find something that isn't a tag
* `tag^{tree}` -> dereference until we find an object of the given type
* `tag^` or `master^3` -> dereference until we find a commit, then get the Nth parent
* `tag~3` -> commit that is N steps back from the ref, always following the 1st parent
* `HEAD@{2}` -> object that was pointed to by a ref N steps back in the reflog
* `branch@{yesterday}`, `master@{5 minutes ago}` -> object that was pointed to by a ref at the specified time
* `@{-3}` -> commit pointed to by the Nth branch checked out before the current one
* `tag^{/foo}` -> youngest commit whose message matches the regex after "/", which is reachable from the given starting point

Things that are still missing:

* `:/foo` -> youngest commit whose message matches the regex after "/", which is reachable from *any* ref
* `tag:README.md` -> dereference to a tree, then return the blob or tree at the given path
* `:2:Makefile` -> blob object in the index at the given merge stage

The entry point is `git_revparse_single`, and it's expected that there will eventually be a `git_revparse_range` which supports the rev-parse syntax for finding ranges of commits (a la `git rev-list`).