libgit2/libgit2 — pull request #2233 by arrbee (2014-04-02 04:45:59+00:00)
Title: Skip untracked contained repo contents even with gitlink files

Fix for #2232

When a git repository contains another git repository, we don't actually want to include diffs on all the files inside the contained repo. The logic to do this exclusion [was already present](https://github.com/libgit2/libgit2/blob/f28e4c97b38c1ec60dc6ce6e5306067ad24aeb8e/src/diff.c#L878-L885), but it only checked for `.git` directories to bypass contained repos, not `.git` plain files with a `gitdir: ` in them. Since that's what an abandoned submodule would contain, this case actually is more common and was broken.

This PR fixes that (literally just replaces `git_path_contains_dir` with `git_path_contains`) and adds a bunch of tests for the status of various untracked directories and repositories.

There are still a couple of minor differences from core Git regarding these contained repos.

1. We don't check that the contained repository is a valid repo. Core Git will error out if the repo doesn't look like a valid one whereas libgit2 will just skip it without verifying its integrity. I'd prefer to defer this check until the warning API is in place, because this seems like a good example of a problem that should not prevent the diff from being executed.
2. To perfectly mimic Git, contained repos should be treated as if `GIT_DIFF_ENABLE_FAST_UNTRACKED_DIRS` is set when `GIT_DIFF_RECURSE_UNTRACKED_DIRS` is passed in. That would mean that they are included as untracked diff entries without scanning their content for non-ignored files. That would probably give a nice little speedup, so it may be worth pursuing, even though it adds a strange asymmetry to the behavior of contained repositories and other untracked directories.

I believe this PR is merge-able even without those two issues being tackled, but I'm curious what @joshaber and others think about the importance of clearing up those remaining minor differences.