static void check_tree_range( git_repository *repo, const char *start, const char *end, bool ignore_case, int expected_count) { git_tree *head; git_iterator *i; git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT; int error, count; i_opts.flags = ignore_case ? GIT_ITERATOR_IGNORE_CASE : GIT_ITERATOR_DONT_IGNORE_CASE; i_opts.start = start; i_opts.end = end; cl_git_pass(git_repository_head_tree(&head, repo)); cl_git_pass(git_iterator_for_tree(&i, head, &i_opts)); for (count = 0; !(error = git_iterator_advance(NULL, i)); ++count) /* count em up */; cl_assert_equal_i(GIT_ITEROVER, error); cl_assert_equal_i(expected_count, count); git_iterator_free(i); git_tree_free(head); }
void test_status_worktree__at_head_parent(void) { git_repository *repo = cl_git_sandbox_init("empty_standard_repo"); git_status_options opts = GIT_STATUS_OPTIONS_INIT; git_status_list *statuslist; git_tree *parent_tree; const git_status_entry *status; cl_git_mkfile("empty_standard_repo/file1", "ping"); stage_and_commit(repo, "file1"); cl_git_pass(git_repository_head_tree(&parent_tree, repo)); cl_git_mkfile("empty_standard_repo/file2", "pong"); stage_and_commit(repo, "file2"); cl_git_rewritefile("empty_standard_repo/file2", "pyng"); opts.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR; opts.baseline = parent_tree; cl_git_pass(git_status_list_new(&statuslist, repo, &opts)); cl_assert_equal_sz(1, git_status_list_entrycount(statuslist)); status = git_status_byindex(statuslist, 0); cl_assert(status != NULL); cl_assert_equal_s("file2", status->index_to_workdir->old_file.path); cl_assert_equal_i(GIT_STATUS_WT_MODIFIED | GIT_STATUS_INDEX_NEW, status->status); git_tree_free(parent_tree); git_status_list_free(statuslist); }
void test_repo_iterator__tree(void) { git_iterator *i; git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT; git_tree *head; g_repo = cl_git_sandbox_init("icase"); cl_git_pass(git_repository_head_tree(&head, g_repo)); /* auto expand with no tree entries */ cl_git_pass(git_iterator_for_tree(&i, head, NULL)); expect_iterator_items(i, 20, NULL, 20, NULL); git_iterator_free(i); /* auto expand with tree entries */ i_opts.flags = GIT_ITERATOR_INCLUDE_TREES; cl_git_pass(git_iterator_for_tree(&i, head, &i_opts)); expect_iterator_items(i, 22, NULL, 22, NULL); git_iterator_free(i); /* no auto expand (implies trees included) */ i_opts.flags = GIT_ITERATOR_DONT_AUTOEXPAND; cl_git_pass(git_iterator_for_tree(&i, head, &i_opts)); expect_iterator_items(i, 12, NULL, 22, NULL); git_iterator_free(i); git_tree_free(head); }
void test_repo_iterator__treefilelist(void) { git_iterator *i; git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT; git_vector filelist; git_tree *tree; bool default_icase; int expect; cl_git_pass(git_vector_init(&filelist, 100, &git__strcmp_cb)); cl_git_pass(git_vector_insert(&filelist, "a")); cl_git_pass(git_vector_insert(&filelist, "B")); cl_git_pass(git_vector_insert(&filelist, "c")); cl_git_pass(git_vector_insert(&filelist, "D")); cl_git_pass(git_vector_insert(&filelist, "e")); cl_git_pass(git_vector_insert(&filelist, "k.a")); cl_git_pass(git_vector_insert(&filelist, "k.b")); cl_git_pass(git_vector_insert(&filelist, "k/1")); cl_git_pass(git_vector_insert(&filelist, "k/a")); cl_git_pass(git_vector_insert(&filelist, "kZZZZZZZ")); cl_git_pass(git_vector_insert(&filelist, "L/1")); g_repo = cl_git_sandbox_init("icase"); git_repository_head_tree(&tree, g_repo); /* All indexfilelist iterator tests are "autoexpand with no tree entries" */ /* In this test we DO NOT force a case on the iteratords and verify default behavior. */ i_opts.pathlist.strings = (char **)filelist.contents; i_opts.pathlist.count = filelist.length; cl_git_pass(git_iterator_for_tree(&i, tree, &i_opts)); expect_iterator_items(i, 8, NULL, 8, NULL); git_iterator_free(i); i_opts.start = "c"; i_opts.end = NULL; cl_git_pass(git_iterator_for_tree(&i, tree, &i_opts)); default_icase = git_iterator_ignore_case(i); /* (c D e k/1 k/a L ==> 6) vs (c e k/1 k/a ==> 4) */ expect = ((default_icase) ? 6 : 4); expect_iterator_items(i, expect, NULL, expect, NULL); git_iterator_free(i); i_opts.start = NULL; i_opts.end = "e"; cl_git_pass(git_iterator_for_tree(&i, tree, &i_opts)); default_icase = git_iterator_ignore_case(i); /* (a B c D e ==> 5) vs (B D L/1 a c e ==> 6) */ expect = ((default_icase) ? 5 : 6); expect_iterator_items(i, expect, NULL, expect, NULL); git_iterator_free(i); git_vector_free(&filelist); git_tree_free(tree); }
void test_repo_iterator__treefilelist_icase(void) { git_iterator *i; git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT; git_vector filelist; git_tree *tree; cl_git_pass(git_vector_init(&filelist, 100, &git__strcmp_cb)); cl_git_pass(git_vector_insert(&filelist, "a")); cl_git_pass(git_vector_insert(&filelist, "B")); cl_git_pass(git_vector_insert(&filelist, "c")); cl_git_pass(git_vector_insert(&filelist, "D")); cl_git_pass(git_vector_insert(&filelist, "e")); cl_git_pass(git_vector_insert(&filelist, "k.a")); cl_git_pass(git_vector_insert(&filelist, "k.b")); cl_git_pass(git_vector_insert(&filelist, "k/1")); cl_git_pass(git_vector_insert(&filelist, "k/a")); cl_git_pass(git_vector_insert(&filelist, "kZZZZ")); cl_git_pass(git_vector_insert(&filelist, "L/1")); g_repo = cl_git_sandbox_init("icase"); git_repository_head_tree(&tree, g_repo); i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE; i_opts.pathlist.strings = (char **)filelist.contents; i_opts.pathlist.count = filelist.length; i_opts.start = "c"; i_opts.end = "k/D"; cl_git_pass(git_iterator_for_tree(&i, tree, &i_opts)); expect_iterator_items(i, 3, NULL, 3, NULL); git_iterator_free(i); i_opts.start = "k"; i_opts.end = "k/Z"; cl_git_pass(git_iterator_for_tree(&i, tree, &i_opts)); expect_iterator_items(i, 1, NULL, 1, NULL); git_iterator_free(i); i_opts.flags = GIT_ITERATOR_IGNORE_CASE; i_opts.start = "c"; i_opts.end = "k/D"; cl_git_pass(git_iterator_for_tree(&i, tree, &i_opts)); expect_iterator_items(i, 5, NULL, 5, NULL); git_iterator_free(i); i_opts.start = "k"; i_opts.end = "k/Z"; cl_git_pass(git_iterator_for_tree(&i, tree, &i_opts)); expect_iterator_items(i, 2, NULL, 2, NULL); git_iterator_free(i); git_vector_free(&filelist); git_tree_free(tree); }
void test_diff_workdir__cannot_diff_against_a_bare_repository(void) { git_diff_options opts = {0}; git_diff_list *diff = NULL; git_tree *tree; g_repo = cl_git_sandbox_init("testrepo.git"); cl_assert_equal_i(GIT_EBAREREPO, git_diff_workdir_to_index(g_repo, &opts, &diff)); cl_git_pass(git_repository_head_tree(&tree, g_repo)); cl_assert_equal_i(GIT_EBAREREPO, git_diff_workdir_to_tree(g_repo, &opts, tree, &diff)); git_tree_free(tree); }
void test_checkout_index__initialize(void) { git_tree *tree; g_repo = cl_git_sandbox_init("testrepo"); cl_git_pass(git_repository_head_tree(&tree, g_repo)); reset_index_to_treeish((git_object *)tree); git_tree_free(tree); cl_git_rewritefile( "./testrepo/.gitattributes", "* text eol=lf\n"); }
static int rebase_ensure_not_dirty( git_repository *repo, bool check_index, bool check_workdir, int fail_with) { git_tree *head = NULL; git_index *index = NULL; git_diff *diff = NULL; int error = 0; if (check_index) { if ((error = git_repository_head_tree(&head, repo)) < 0 || (error = git_repository_index(&index, repo)) < 0 || (error = git_diff_tree_to_index(&diff, repo, head, index, NULL)) < 0) goto done; if (git_diff_num_deltas(diff) > 0) { git_error_set(GIT_ERROR_REBASE, "uncommitted changes exist in index"); error = fail_with; goto done; } git_diff_free(diff); diff = NULL; } if (check_workdir) { git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT; diff_opts.ignore_submodules = GIT_SUBMODULE_IGNORE_UNTRACKED; if ((error = git_diff_index_to_workdir(&diff, repo, index, &diff_opts)) < 0) goto done; if (git_diff_num_deltas(diff) > 0) { git_error_set(GIT_ERROR_REBASE, "unstaged changes exist in workdir"); error = fail_with; goto done; } } done: git_diff_free(diff); git_index_free(index); git_tree_free(head); return error; }
static int rebase_ensure_not_dirty( git_repository *repo, bool check_index, bool check_workdir, int fail_with) { git_tree *head = NULL; git_index *index = NULL; git_diff *diff = NULL; int error = 0; if (check_index) { if ((error = git_repository_head_tree(&head, repo)) < 0 || (error = git_repository_index(&index, repo)) < 0 || (error = git_diff_tree_to_index(&diff, repo, head, index, NULL)) < 0) goto done; if (git_diff_num_deltas(diff) > 0) { giterr_set(GITERR_REBASE, "Uncommitted changes exist in index"); error = fail_with; goto done; } git_diff_free(diff); diff = NULL; } if (check_workdir) { if ((error = git_diff_index_to_workdir(&diff, repo, index, NULL)) < 0) goto done; if (git_diff_num_deltas(diff) > 0) { giterr_set(GITERR_REBASE, "Unstaged changes exist in workdir"); error = fail_with; goto done; } } done: git_diff_free(diff); git_index_free(index); git_tree_free(head); return error; }
void test_checkout_index__initialize(void) { git_tree *tree; memset(&g_opts, 0, sizeof(g_opts)); g_opts.checkout_strategy = GIT_CHECKOUT_CREATE_MISSING; g_repo = cl_git_sandbox_init("testrepo"); cl_git_pass(git_repository_head_tree(&tree, g_repo)); reset_index_to_treeish((git_object *)tree); git_tree_free(tree); cl_git_rewritefile( "./testrepo/.gitattributes", "* text eol=lf\n"); }
int git_checkout_head( git_repository *repo, git_checkout_opts *opts, git_indexer_stats *stats) { int error; git_tree *tree = NULL; assert(repo); if (git_repository_head_tree(&tree, repo) < 0) return -1; error = git_checkout_tree(repo, (git_object *)tree, opts, stats); git_tree_free(tree); return error; }
void test_diff_iterator__index_handles_icase_range(void) { git_repository *repo; git_index *index; git_tree *head; repo = cl_git_sandbox_init("testrepo"); /* reset index to match HEAD */ cl_git_pass(git_repository_head_tree(&head, repo)); cl_git_pass(git_repository_index(&index, repo)); cl_git_pass(git_index_read_tree(index, head)); cl_git_pass(git_index_write(index)); git_tree_free(head); git_index_free(index); /* do some ranged iterator checks toggling case sensitivity */ check_index_range(repo, "B", "C", false, 0); check_index_range(repo, "B", "C", true, 1); check_index_range(repo, "a", "z", false, 3); check_index_range(repo, "a", "z", true, 4); }
void test_diff_submodules__submod2_head_to_index(void) { git_diff_options opts = GIT_DIFF_OPTIONS_INIT; git_tree *head; git_diff_list *diff = NULL; static const char *expected[] = { "<SKIP>", /* .gitmodules */ "diff --git a/sm_added_and_uncommited b/sm_added_and_uncommited\nnew file mode 160000\nindex 0000000..4800958\n--- /dev/null\n+++ b/sm_added_and_uncommited\n@@ -0,0 +1 @@\n+Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n", /* sm_added_and_uncommited */ "<END>" }; setup_submodules2(); cl_git_pass(git_repository_head_tree(&head, g_repo)); opts.flags = GIT_DIFF_INCLUDE_UNTRACKED; cl_git_pass(git_diff_tree_to_index(&diff, g_repo, head, NULL, &opts)); check_diff_patches(diff, expected); git_diff_list_free(diff); git_tree_free(head); }
void test_repo_iterator__tree_icase(void) { git_iterator *i; git_tree *head; git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT; g_repo = cl_git_sandbox_init("icase"); cl_git_pass(git_repository_head_tree(&head, g_repo)); i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE; /* auto expand with no tree entries */ i_opts.start = "c"; i_opts.end = "k/D"; cl_git_pass(git_iterator_for_tree(&i, head, &i_opts)); expect_iterator_items(i, 7, NULL, 7, NULL); git_iterator_free(i); i_opts.start = "k"; i_opts.end = "k/Z"; cl_git_pass(git_iterator_for_tree(&i, head, &i_opts)); expect_iterator_items(i, 3, NULL, 3, NULL); git_iterator_free(i); i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE | GIT_ITERATOR_INCLUDE_TREES; /* auto expand with tree entries */ i_opts.start = "c"; i_opts.end = "k/Z"; cl_git_pass(git_iterator_for_tree(&i, head, &i_opts)); expect_iterator_items(i, 8, NULL, 8, NULL); git_iterator_free(i); i_opts.start = "k"; i_opts.end = "k/Z"; cl_git_pass(git_iterator_for_tree(&i, head, &i_opts)); expect_iterator_items(i, 4, NULL, 4, NULL); git_iterator_free(i); /* no auto expand (implies trees included) */ i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE | GIT_ITERATOR_DONT_AUTOEXPAND; i_opts.start = "c"; i_opts.end = "k/D"; cl_git_pass(git_iterator_for_tree(&i, head, &i_opts)); expect_iterator_items(i, 5, NULL, 8, NULL); git_iterator_free(i); i_opts.start = "k"; i_opts.end = "k/D"; cl_git_pass(git_iterator_for_tree(&i, head, &i_opts)); expect_iterator_items(i, 1, NULL, 4, NULL); git_iterator_free(i); /* auto expand with no tree entries */ i_opts.flags = GIT_ITERATOR_IGNORE_CASE; i_opts.start = "c"; i_opts.end = "k/D"; cl_git_pass(git_iterator_for_tree(&i, head, &i_opts)); expect_iterator_items(i, 13, NULL, 13, NULL); git_iterator_free(i); i_opts.start = "k"; i_opts.end = "k/Z"; cl_git_pass(git_iterator_for_tree(&i, head, &i_opts)); expect_iterator_items(i, 5, NULL, 5, NULL); git_iterator_free(i); /* auto expand with tree entries */ i_opts.flags = GIT_ITERATOR_IGNORE_CASE | GIT_ITERATOR_INCLUDE_TREES; i_opts.start = "c"; i_opts.end = "k/D"; cl_git_pass(git_iterator_for_tree(&i, head, &i_opts)); expect_iterator_items(i, 14, NULL, 14, NULL); git_iterator_free(i); i_opts.start = "k"; i_opts.end = "k/Z"; cl_git_pass(git_iterator_for_tree(&i, head, &i_opts)); expect_iterator_items(i, 6, NULL, 6, NULL); git_iterator_free(i); /* no auto expand (implies trees included) */ i_opts.flags = GIT_ITERATOR_IGNORE_CASE | GIT_ITERATOR_DONT_AUTOEXPAND; i_opts.start = "c"; i_opts.end = "k/D"; cl_git_pass(git_iterator_for_tree(&i, head, &i_opts)); expect_iterator_items(i, 9, NULL, 14, NULL); git_iterator_free(i); i_opts.start = "k"; i_opts.end = "k/Z"; cl_git_pass(git_iterator_for_tree(&i, head, &i_opts)); expect_iterator_items(i, 1, NULL, 6, NULL); git_iterator_free(i); git_tree_free(head); }
static int rebase_next_merge( git_rebase_operation **out, git_rebase *rebase) { git_buf path = GIT_BUF_INIT; git_commit *current_commit = NULL, *parent_commit = NULL; git_tree *current_tree = NULL, *head_tree = NULL, *parent_tree = NULL; git_index *index = NULL; git_indexwriter indexwriter = GIT_INDEXWRITER_INIT; git_rebase_operation *operation; git_checkout_options checkout_opts; char current_idstr[GIT_OID_HEXSZ]; unsigned int parent_count; int error; *out = NULL; operation = git_array_get(rebase->operations, rebase->current); if ((error = git_commit_lookup(¤t_commit, rebase->repo, &operation->id)) < 0 || (error = git_commit_tree(¤t_tree, current_commit)) < 0 || (error = git_repository_head_tree(&head_tree, rebase->repo)) < 0) goto done; if ((parent_count = git_commit_parentcount(current_commit)) > 1) { giterr_set(GITERR_REBASE, "Cannot rebase a merge commit"); error = -1; goto done; } else if (parent_count) { if ((error = git_commit_parent(&parent_commit, current_commit, 0)) < 0 || (error = git_commit_tree(&parent_tree, parent_commit)) < 0) goto done; } git_oid_fmt(current_idstr, &operation->id); normalize_checkout_options_for_apply(&checkout_opts, rebase, current_commit); if ((error = git_indexwriter_init_for_operation(&indexwriter, rebase->repo, &checkout_opts.checkout_strategy)) < 0 || (error = rebase_setupfile(rebase, MSGNUM_FILE, -1, "%" PRIuZ "\n", rebase->current+1)) < 0 || (error = rebase_setupfile(rebase, CURRENT_FILE, -1, "%.*s\n", GIT_OID_HEXSZ, current_idstr)) < 0 || (error = git_merge_trees(&index, rebase->repo, parent_tree, head_tree, current_tree, &rebase->options.merge_options)) < 0 || (error = git_merge__check_result(rebase->repo, index)) < 0 || (error = git_checkout_index(rebase->repo, index, &checkout_opts)) < 0 || (error = git_indexwriter_commit(&indexwriter)) < 0) goto done; *out = operation; done: git_indexwriter_cleanup(&indexwriter); git_index_free(index); git_tree_free(current_tree); git_tree_free(head_tree); git_tree_free(parent_tree); git_commit_free(parent_commit); git_commit_free(current_commit); git_buf_free(&path); return error; }
void test_repo_iterator__tree_more(void) { git_iterator *i; git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT; git_tree *head; static const char *expect_basic[] = { "current_file", "file_deleted", "modified_file", "staged_changes", "staged_changes_file_deleted", "staged_changes_modified_file", "staged_delete_file_deleted", "staged_delete_modified_file", "subdir.txt", "subdir/current_file", "subdir/deleted_file", "subdir/modified_file", NULL, }; static const char *expect_trees[] = { "current_file", "file_deleted", "modified_file", "staged_changes", "staged_changes_file_deleted", "staged_changes_modified_file", "staged_delete_file_deleted", "staged_delete_modified_file", "subdir.txt", "subdir/", "subdir/current_file", "subdir/deleted_file", "subdir/modified_file", NULL, }; static const char *expect_noauto[] = { "current_file", "file_deleted", "modified_file", "staged_changes", "staged_changes_file_deleted", "staged_changes_modified_file", "staged_delete_file_deleted", "staged_delete_modified_file", "subdir.txt", "subdir/", NULL }; g_repo = cl_git_sandbox_init("status"); cl_git_pass(git_repository_head_tree(&head, g_repo)); /* auto expand with no tree entries */ cl_git_pass(git_iterator_for_tree(&i, head, NULL)); expect_iterator_items(i, 12, expect_basic, 12, expect_basic); git_iterator_free(i); /* auto expand with tree entries */ i_opts.flags = GIT_ITERATOR_INCLUDE_TREES; cl_git_pass(git_iterator_for_tree(&i, head, &i_opts)); expect_iterator_items(i, 13, expect_trees, 13, expect_trees); git_iterator_free(i); /* no auto expand (implies trees included) */ i_opts.flags = GIT_ITERATOR_DONT_AUTOEXPAND; cl_git_pass(git_iterator_for_tree(&i, head, &i_opts)); expect_iterator_items(i, 10, expect_noauto, 13, expect_trees); git_iterator_free(i); git_tree_free(head); }
void test_iterator_workdir__bounded_submodules(void) { git_iterator *i; git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT; git_vector filelist; git_index *index; git_tree *head; cl_git_pass(git_vector_init(&filelist, 5, NULL)); g_repo = setup_fixture_submod2(); cl_git_pass(git_repository_index(&index, g_repo)); cl_git_pass(git_repository_head_tree(&head, g_repo)); /* Test that a submodule matches */ { const char *expected[] = { "sm_changed_head" }; size_t expected_len = 1; git_vector_clear(&filelist); cl_git_pass(git_vector_insert(&filelist, "sm_changed_head")); i_opts.pathlist.strings = (char **)filelist.contents; i_opts.pathlist.count = filelist.length; i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE; cl_git_pass(git_iterator_for_workdir(&i, g_repo, index, head, &i_opts)); expect_iterator_items(i, expected_len, expected, expected_len, expected); git_iterator_free(i); } /* Test that a submodule still matches when suffixed with a '/' */ { const char *expected[] = { "sm_changed_head" }; size_t expected_len = 1; git_vector_clear(&filelist); cl_git_pass(git_vector_insert(&filelist, "sm_changed_head/")); i_opts.pathlist.strings = (char **)filelist.contents; i_opts.pathlist.count = filelist.length; i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE; cl_git_pass(git_iterator_for_workdir(&i, g_repo, index, head, &i_opts)); expect_iterator_items(i, expected_len, expected, expected_len, expected); git_iterator_free(i); } /* Test that start/end work with a submodule */ { const char *expected[] = { "sm_changed_head", "sm_changed_index" }; size_t expected_len = 2; i_opts.start = "sm_changed_head"; i_opts.end = "sm_changed_index"; i_opts.pathlist.strings = NULL; i_opts.pathlist.count = 0; i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE; cl_git_pass(git_iterator_for_workdir(&i, g_repo, index, head, &i_opts)); expect_iterator_items(i, expected_len, expected, expected_len, expected); git_iterator_free(i); } /* Test that start and end allow '/' suffixes of submodules */ { const char *expected[] = { "sm_changed_head", "sm_changed_index" }; size_t expected_len = 2; i_opts.start = "sm_changed_head"; i_opts.end = "sm_changed_index"; i_opts.pathlist.strings = NULL; i_opts.pathlist.count = 0; i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE; cl_git_pass(git_iterator_for_workdir(&i, g_repo, index, head, &i_opts)); expect_iterator_items(i, expected_len, expected, expected_len, expected); git_iterator_free(i); } git_vector_free(&filelist); git_index_free(index); git_tree_free(head); }
static int all_submodules(git_repository *repo, git_strmap *map) { int error = 0; git_index *idx = NULL; git_tree *head = NULL; const char *wd = NULL; git_buf path = GIT_BUF_INIT; git_submodule *sm; git_config_backend *mods = NULL; uint32_t mask; assert(repo && map); /* get sources that we will need to check */ if (git_repository_index(&idx, repo) < 0) giterr_clear(); if (git_repository_head_tree(&head, repo) < 0) giterr_clear(); wd = git_repository_workdir(repo); if (wd && (error = git_buf_joinpath(&path, wd, GIT_MODULES_FILE)) < 0) goto cleanup; /* clear submodule flags that are to be refreshed */ mask = 0; mask |= GIT_SUBMODULE_STATUS_IN_INDEX | GIT_SUBMODULE_STATUS__INDEX_FLAGS | GIT_SUBMODULE_STATUS__INDEX_OID_VALID | GIT_SUBMODULE_STATUS__INDEX_MULTIPLE_ENTRIES; mask |= GIT_SUBMODULE_STATUS_IN_HEAD | GIT_SUBMODULE_STATUS__HEAD_OID_VALID; mask |= GIT_SUBMODULE_STATUS_IN_CONFIG; if (mask != 0) mask |= GIT_SUBMODULE_STATUS_IN_WD | GIT_SUBMODULE_STATUS__WD_SCANNED | GIT_SUBMODULE_STATUS__WD_FLAGS | GIT_SUBMODULE_STATUS__WD_OID_VALID; /* add back submodule information from index */ if (idx) { if ((error = submodules_from_index(map, idx)) < 0) goto cleanup; } /* add submodule information from HEAD */ if (head) { if ((error = submodules_from_head(map, head)) < 0) goto cleanup; } /* add submodule information from .gitmodules */ if (wd) { lfc_data data = { 0 }; data.map = map; data.repo = repo; if ((mods = open_gitmodules(repo, false)) != NULL && (error = git_config_file_foreach( mods, submodule_load_from_config, &data)) < 0) goto cleanup; } /* shallow scan submodules in work tree as needed */ if (wd && mask != 0) { git_strmap_foreach_value(map, sm, { submodule_load_from_wd_lite(sm); });