diff --git a/src/iterator.c b/src/iterator.c index 401b5de93..e9ec65250 100644 --- a/src/iterator.c +++ b/src/iterator.c @@ -1313,8 +1313,8 @@ static int workdir_iterator__update_entry(fs_iterator *fi) if (error < 0) giterr_clear(); - /* mark submodule (or any dir with .git) as GITLINK and remove slash */ - if (!error || error == GIT_EEXISTS) { + /* mark submodule as GITLINK and remove slash */ + if (!error) { fi->entry.mode = S_IFGITLINK; fi->entry.path[strlen(fi->entry.path) - 1] = '\0'; } diff --git a/src/path.c b/src/path.c index fa800b74c..1dccf90da 100644 --- a/src/path.c +++ b/src/path.c @@ -1051,15 +1051,8 @@ int git_path_dirload_with_stat( } if (S_ISDIR(ps->st.st_mode)) { - if ((error = git_buf_joinpath(&full, full.ptr, ".git")) < 0) - break; - - if (p_access(full.ptr, F_OK) == 0) { - ps->st.st_mode = GIT_FILEMODE_COMMIT; - } else { - ps->path[ps->path_len++] = '/'; - ps->path[ps->path_len] = '\0'; - } + ps->path[ps->path_len++] = '/'; + ps->path[ps->path_len] = '\0'; } } diff --git a/tests/diff/iterator.c b/tests/diff/iterator.c index 92e6f723b..891d8a6e5 100644 --- a/tests/diff/iterator.c +++ b/tests/diff/iterator.c @@ -737,13 +737,13 @@ void test_diff_iterator__workdir_builtin_ignores(void) { "root_test2", false }, { "root_test3", false }, { "root_test4.txt", false }, - { "sub", false }, + { "sub/", false }, { "sub/.gitattributes", false }, { "sub/abc", false }, { "sub/dir/", true }, { "sub/file", false }, { "sub/ign/", true }, - { "sub/sub", false }, + { "sub/sub/", false }, { "sub/sub/.gitattributes", false }, { "sub/sub/dir", false }, /* file is not actually a dir */ { "sub/sub/file", false }, diff --git a/tests/diff/submodules.c b/tests/diff/submodules.c index da96ba9c5..314cf1fad 100644 --- a/tests/diff/submodules.c +++ b/tests/diff/submodules.c @@ -1,6 +1,7 @@ #include "clar_libgit2.h" #include "repository.h" #include "posix.h" +#include "diff_helpers.h" #include "../submodule/submodule_helpers.h" static git_repository *g_repo = NULL; @@ -11,6 +12,7 @@ void test_diff_submodules__initialize(void) void test_diff_submodules__cleanup(void) { + cl_git_sandbox_cleanup(); } #define get_buf_ptr(buf) ((buf)->asize ? (buf)->ptr : NULL) @@ -34,6 +36,10 @@ static void check_diff_patches_at_line( if (expected[d] && !strcmp(expected[d], "")) continue; + if (expected[d] && !strcmp(expected[d], "")) { + cl_assert_at_line(delta->status == GIT_DELTA_UNTRACKED, file, line); + continue; + } if (expected[d] && !strcmp(expected[d], "")) { cl_git_pass(git_patch_to_buf(&buf, patch)); cl_assert_at_line(!strcmp(expected[d], ""), file, line); @@ -115,7 +121,9 @@ void test_diff_submodules__dirty_submodule_2(void) git_diff_options opts = GIT_DIFF_OPTIONS_INIT; git_diff *diff = NULL, *diff2 = NULL; char *smpath = "testrepo"; - static const char *expected_none[] = { "" }; + static const char *expected_none[] = { + "" + }; static const char *expected_dirty[] = { "diff --git a/testrepo b/testrepo\nindex a65fedf..a65fedf 160000\n--- a/testrepo\n+++ b/testrepo\n@@ -1 +1 @@\n-Subproject commit a65fedf39aefe402d3bb6e24df4d4f5fe4547750\n+Subproject commit a65fedf39aefe402d3bb6e24df4d4f5fe4547750-dirty\n", /* testrepo.git */ "" @@ -170,6 +178,8 @@ void test_diff_submodules__submod2_index_to_wd(void) git_diff *diff = NULL; static const char *expected[] = { "", /* .gitmodules */ + "", /* not-submodule */ + "", /* not */ "diff --git a/sm_changed_file b/sm_changed_file\nindex 4800958..4800958 160000\n--- a/sm_changed_file\n+++ b/sm_changed_file\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0-dirty\n", /* sm_changed_file */ "diff --git a/sm_changed_head b/sm_changed_head\nindex 4800958..3d9386c 160000\n--- a/sm_changed_head\n+++ b/sm_changed_head\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 3d9386c507f6b093471a3e324085657a3c2b4247\n", /* sm_changed_head */ "diff --git a/sm_changed_index b/sm_changed_index\nindex 4800958..4800958 160000\n--- a/sm_changed_index\n+++ b/sm_changed_index\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0-dirty\n", /* sm_changed_index */ @@ -349,6 +359,8 @@ void test_diff_submodules__diff_ignore_options(void) git_config *cfg; static const char *expected_normal[] = { "", /* .gitmodules */ + "", /* not-submodule */ + "", /* not */ "diff --git a/sm_changed_file b/sm_changed_file\nindex 4800958..4800958 160000\n--- a/sm_changed_file\n+++ b/sm_changed_file\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0-dirty\n", /* sm_changed_file */ "diff --git a/sm_changed_head b/sm_changed_head\nindex 4800958..3d9386c 160000\n--- a/sm_changed_head\n+++ b/sm_changed_head\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 3d9386c507f6b093471a3e324085657a3c2b4247\n", /* sm_changed_head */ "diff --git a/sm_changed_index b/sm_changed_index\nindex 4800958..4800958 160000\n--- a/sm_changed_index\n+++ b/sm_changed_index\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0-dirty\n", /* sm_changed_index */ @@ -358,10 +370,14 @@ void test_diff_submodules__diff_ignore_options(void) }; static const char *expected_ignore_all[] = { "", /* .gitmodules */ + "", /* not-submodule */ + "", /* not */ "" }; static const char *expected_ignore_dirty[] = { "", /* .gitmodules */ + "", /* not-submodule */ + "", /* not */ "diff --git a/sm_changed_head b/sm_changed_head\nindex 4800958..3d9386c 160000\n--- a/sm_changed_head\n+++ b/sm_changed_head\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 3d9386c507f6b093471a3e324085657a3c2b4247\n", /* sm_changed_head */ "diff --git a/sm_missing_commits b/sm_missing_commits\nindex 4800958..5e49635 160000\n--- a/sm_missing_commits\n+++ b/sm_missing_commits\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 5e4963595a9774b90524d35a807169049de8ccad\n", /* sm_missing_commits */ "" @@ -423,3 +439,49 @@ void test_diff_submodules__diff_ignore_options(void) git_config_free(cfg); } + +void test_diff_submodules__skips_empty_includes_used(void) +{ + git_diff_options opts = GIT_DIFF_OPTIONS_INIT; + git_diff *diff = NULL; + diff_expects exp; + git_repository *r2; + + /* A side effect of of Git's handling of untracked directories and + * auto-ignoring of ".git" entries is that a newly initialized Git + * repo inside another repo will be skipped by diff, but one that + * actually has a commit it in will show as an untracked directory. + * Let's make sure that works. + */ + + g_repo = cl_git_sandbox_init("empty_standard_repo"); + + opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED; + + cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts)); + memset(&exp, 0, sizeof(exp)); + cl_git_pass(git_diff_foreach( + diff, diff_file_cb, diff_hunk_cb, diff_line_cb, &exp)); + cl_assert_equal_i(0, exp.files); + git_diff_free(diff); + + cl_git_pass(git_repository_init(&r2, "empty_standard_repo/subrepo", 0)); + + cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts)); + memset(&exp, 0, sizeof(exp)); + cl_git_pass(git_diff_foreach( + diff, diff_file_cb, diff_hunk_cb, diff_line_cb, &exp)); + cl_assert_equal_i(1, exp.files); + cl_assert_equal_i(1, exp.file_status[GIT_DELTA_IGNORED]); + git_diff_free(diff); + + cl_git_mkfile("empty_standard_repo/subrepo/README.txt", "hello\n"); + + cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts)); + memset(&exp, 0, sizeof(exp)); + cl_git_pass(git_diff_foreach( + diff, diff_file_cb, diff_hunk_cb, diff_line_cb, &exp)); + cl_assert_equal_i(1, exp.files); + cl_assert_equal_i(1, exp.file_status[GIT_DELTA_UNTRACKED]); + git_diff_free(diff); +} diff --git a/tests/diff/workdir.c b/tests/diff/workdir.c index 449dc6363..6128e820e 100644 --- a/tests/diff/workdir.c +++ b/tests/diff/workdir.c @@ -881,7 +881,7 @@ void test_diff_workdir__submodules(void) * only significant difference is that those Added items will show up * as Untracked items in the pure libgit2 diff. * - * Then add in the two extra ignored items "not" and "not-submodule" + * Then add in the two extra untracked items "not" and "not-submodule" * to get the 12 files reported here. */ @@ -890,8 +890,8 @@ void test_diff_workdir__submodules(void) cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]); cl_assert_equal_i(0, exp.file_status[GIT_DELTA_DELETED]); cl_assert_equal_i(2, exp.file_status[GIT_DELTA_MODIFIED]); - cl_assert_equal_i(2, exp.file_status[GIT_DELTA_IGNORED]); - cl_assert_equal_i(8, exp.file_status[GIT_DELTA_UNTRACKED]); + cl_assert_equal_i(0, exp.file_status[GIT_DELTA_IGNORED]); + cl_assert_equal_i(10, exp.file_status[GIT_DELTA_UNTRACKED]); /* the following numbers match "git diff 873585" exactly */ diff --git a/tests/submodule/status.c b/tests/submodule/status.c index f5111c84f..324592301 100644 --- a/tests/submodule/status.c +++ b/tests/submodule/status.c @@ -324,7 +324,7 @@ static int confirm_submodule_status( { submodule_expectations *exp = payload; - while (git__suffixcmp(exp->paths[exp->counter], "/") == 0) + while (exp->statuses[exp->counter] < 0) exp->counter++; cl_assert_equal_i(exp->statuses[exp->counter], (int)status_flags); @@ -345,8 +345,10 @@ void test_submodule_status__iterator(void) "just_a_dir/", "just_a_dir/contents", "just_a_file", - "not", - "not-submodule", + "not-submodule/", + "not-submodule/README.txt", + "not/", + "not/README.txt", "README.txt", "sm_added_and_uncommited", "sm_changed_file", @@ -359,11 +361,13 @@ void test_submodule_status__iterator(void) }; static int expected_flags[] = { GIT_STATUS_INDEX_MODIFIED | GIT_STATUS_WT_MODIFIED, /* ".gitmodules" */ - 0, /* "just_a_dir/" will be skipped */ + -1, /* "just_a_dir/" will be skipped */ GIT_STATUS_CURRENT, /* "just_a_dir/contents" */ GIT_STATUS_CURRENT, /* "just_a_file" */ - GIT_STATUS_IGNORED, /* "not" (contains .git) */ - GIT_STATUS_IGNORED, /* "not-submodule" (contains .git) */ + GIT_STATUS_WT_NEW, /* "not-submodule/" untracked item */ + -1, /* "not-submodule/README.txt" */ + GIT_STATUS_WT_NEW, /* "not/" untracked item */ + -1, /* "not/README.txt" */ GIT_STATUS_CURRENT, /* "README.txt */ GIT_STATUS_INDEX_NEW, /* "sm_added_and_uncommited" */ GIT_STATUS_WT_MODIFIED, /* "sm_changed_file" */