summaryrefslogtreecommitdiff
path: root/src/diff.c
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2014-04-08 14:47:20 -0700
committerRussell Belfer <rb@github.com>2014-04-08 14:47:20 -0700
commiteb7e17cc900f1f59f653cd7b277750fb1d5b721a (patch)
tree70ddd6f3496bae4745308ca1174da2759ad7b33a /src/diff.c
parentce2e82694a19b9994acaa9376bff81bc8e968637 (diff)
downloadlibgit2-rb/fix-submodules-with-tracked-content.tar.gz
Update submodules with parent-tracked contentrb/fix-submodules-with-tracked-content
This updates how libgit2 treats submodule-like directories that actually have tracked content inside of them. This is a strange corner case, but it seems that many people have abortive submodule setups and then just went ahead and added the files into the parent repository. In this case, we should just treat the submodule as if it was a normal directory. Libgit2 will still try to skip over real submodules and contained repositories that do not have tracked files inside them, but this adds some new handling for cases where the apparently submodule data is in conflict with the actual list of tracked files.
Diffstat (limited to 'src/diff.c')
-rw-r--r--src/diff.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/src/diff.c b/src/diff.c
index 484273f4a..e62f45c22 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -876,7 +876,7 @@ static int handle_unmatched_new_item(
DIFF_FLAG_IS_SET(diff, GIT_DIFF_RECURSE_IGNORED_DIRS));
/* do not advance into directories that contain a .git file */
- if (recurse_into_dir) {
+ if (recurse_into_dir && !contains_oitem) {
git_buf *full = NULL;
if (git_iterator_current_workdir_path(&full, info->new_iter) < 0)
return -1;
@@ -969,6 +969,16 @@ static int handle_unmatched_new_item(
if (git_submodule_lookup(NULL, info->repo, nitem->path) != 0) {
giterr_clear();
delta_type = GIT_DELTA_IGNORED;
+
+ /* if this contains a tracked item, treat as normal TREE */
+ if (contains_oitem) {
+ error = git_iterator_advance_into(&info->nitem, info->new_iter);
+ if (error != GIT_ENOTFOUND)
+ return error;
+
+ giterr_clear();
+ return git_iterator_advance(&info->nitem, info->new_iter);
+ }
}
}