Reproduction steps
Two trees with foo-bar/c and foo/y, both files changed between them. Diff them with a pathlist:
char *paths[] = { "foo", "foo-bar/b" };
opts.flags = GIT_DIFF_DISABLE_PATHSPEC_MATCH;
opts.pathspec.strings = paths;
opts.pathspec.count = 2;
git_diff_tree_to_tree(&diff, repo, old_tree, new_tree, &opts);
Expected behavior
M foo/y, same as git diff-tree -r <old> <new> -- foo foo-bar/b.
Actual behavior
The diff is empty.
It looks like the problem is in iterator_pathlist_next_is. It bumps pathlist_walk_idx whenever some pathlist entry sorts before the path, even if that entry isn't the one at pathlist_walk_idx. At foo-bar/c, foo-bar/b sorts before it, so the index moves past foo, and foo/y never matches after that.
Tree and index iterators both go through this code, so it's not only diff. With the same two paths and pathlist:
git_status_list with GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH, after changing both files in the workdir, reports foo/ as untracked. git status -- foo foo-bar/b shows M foo/y.
git_checkout_tree of the new tree with paths and GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH doesn't update foo/y. With GIT_CHECKOUT_FORCE it deletes foo/y from the workdir.
Version of libgit2 (release number or SHA1)
main (0551dfd)
Operating system(s) tested
Linux
Reproduction steps
Two trees with
foo-bar/candfoo/y, both files changed between them. Diff them with a pathlist:Expected behavior
M foo/y, same asgit diff-tree -r <old> <new> -- foo foo-bar/b.Actual behavior
The diff is empty.
It looks like the problem is in
iterator_pathlist_next_is. It bumpspathlist_walk_idxwhenever some pathlist entry sorts before the path, even if that entry isn't the one atpathlist_walk_idx. Atfoo-bar/c,foo-bar/bsorts before it, so the index moves pastfoo, andfoo/ynever matches after that.Tree and index iterators both go through this code, so it's not only diff. With the same two paths and pathlist:
git_status_listwithGIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH, after changing both files in the workdir, reportsfoo/as untracked.git status -- foo foo-bar/bshowsM foo/y.git_checkout_treeof the new tree withpathsandGIT_CHECKOUT_DISABLE_PATHSPEC_MATCHdoesn't updatefoo/y. WithGIT_CHECKOUT_FORCEit deletesfoo/yfrom the workdir.Version of libgit2 (release number or SHA1)
main (0551dfd)
Operating system(s) tested
Linux