libgit2/libgit2 — pull request #1624 by vmg (2013-05-30 16:02:41+00:00)
Title: Breaking RefDB changes

Here's a collection of breaking RefDB changes that I wanted to get in before the next release.

Some highlights:

- The refdb pointer in each reference is now properly refcounted, so you can free the refdb and refs will continue working
- The reference iterator now can yield both reference names and whole references for basically the same price.
- The reference iterator will no longer fail halfway through iteration when encountering invalid loose refs on disk, mimicing Core Git behavior
- The reference iterator now has its own allocation, its own API and is also refcounted towards the refdb, just like all the references it yields
- The reference iterator for the FS backend is now less racy, and snapshots the loose references at initialization instead of keeping a FS iterator open.
- Globbing now happens at the backend level, always. Backends that don't support globbing should fail to allocate an iterator when asked for a glob.
- Most of the RefDB backend API has been changed to use reference names instead of whole object references (e.g. `delete`)
- A new `rename` API pointer has been added to the RefDB backend to allow the backend to perform the rename atomically
- Reference availability checks now happen at the backend level instead of in `refs.c` to allow the backend to optimize them.
- Reference writing is now much faster for the FS backend because the availability checks have been optimized (hah)
- The old `git_reference_foreach` now yields full references. A replacement `git_reference_foreach_name` has been added.
- The in-memory refdb tests have been removed because they were pissing me off.

TODO:
- [ ] The new `rename` callback for the FS iterator still performs the rename in a racy way (i.e. first remove reference, then write). We should use this new callback to implement a proper atomic rename.
- [ ] The `write` callback for the RefDB still takes a `git_reference` pointer, which is pants-on-heads retarded because external clients will see it as opaque and won't be able to write it. I don't particularly like @nulltoken's solution in #1570.