I'm not sure throwing here is going to have the right effect. You probably want to call giterr_set and return -1 from the callback. If you want to make this easy to read, then you can still throw here, but have the entire method body be in a try/catch block that catches exceptions and marshals them back to unmanaged code. Some of the ODB backend logic does this and you could copy it.