Search code examples
c++gitgit-difflibgit2

Calling git diff on a specific direcotry with libgit2


Calling git diff with a specific directory is pretty straightforward on the cmd but I need to call it from a c++ program. I am a bit confused with all the different diff functions libgit2 provides but with help from this question, I got it to work by showing results for the whole repo. For a specific path I tried using git_index_get_bypath but it always fails with an abort message.

git_index_get_bypath(index, "path/of/the/directory/inside/repo", GIT_INDEX_STAGE_NORMAL);

Also every time I change the repo path to a more specific directory inside it, it crashes with an assertion failure and an abort message, which makes sense.

I call git_diff_index_to_index(&diff, repo, NULL, index, &diffopts); to get the differences with diffopts.flags = GIT_DIFF_FORMAT_NAME_ONLY;


UPDATE

git_repository *repo = NULL;
git_index *index = NULL;
git_diff *diff;
git_diff_options diffopts;

const char * REPO_PATH = "path/to/repo/"; 
//tried to be more specific with .../repo/.git but its the same thing
char *DIR_PATH = "path/to/repo/specific/dir"; 

git_repository_open(&repo, REPO_PATH);

diffopts = GIT_DIFF_OPTIONS_INIT;
diffopts.flags = GIT_DIFF_FORMAT_NAME_ONLY;

//diffopts.pathspec.count = 1;
//diffopts.pathspec.strings = &DIR_PATH;

git_repository_index(&index, repo);

git_diff_index_to_workdir(&diff, repo, index, &diffopts);

size_t num_deltas = git_diff_num_deltas(diff);

//do stuff with diff

Uncommenting

diffopts.pathspec.count = 1;
diffopts.pathspec.strings = &DIR_PATH;

git_diff_num_deltas returns 0.


Solution

  • As with most paths handled by the library, they're usually relative to the root of the repository (with a few caveats, hopefully fixable with a bit of documentation).

    In your example, you are passing absolute paths to both the repo (per the documentation) and your interesting pathspecs. Expectedly, no files show up when diffing, because the path are munged together behind-the-scene.