void Index::update_all(git_strarray const & pathspec, matched_path_callback_t cb) { int res = cb ? git_index_update_all(index_.get(), &pathspec, &apply_callback, &cb) : git_index_update_all(index_.get(), &pathspec, nullptr, nullptr); assert(res == 0); }
/* * call-seq: * index.update_all(pathspec = []) -> nil * index.update_all(pathspec = []) { |path, pathspec| block } -> nil * * Update all index entries to match the working directory. * * Searches +index+ for entries that match +pathspec+ and synchronizes * them with the content of the working directory. * * +pathspec+ can either be a String, or an Array of Strings. * If +pathspec+ is empty, all entries in the index will be matched. * * Entries where the corresponding working directory file no longer exists * get deleted, all other matched entries will get updated to reflect their * working directory state (the latest version of the a file's content will * automatically be added to the ODB). * * If a block is given, each matched +path+ and the +pathspec+ that matched * it will be passed to the block. If the return value of +block+ is * falsy, the matching item will not be updated in the index. * * This method will fail in bare index instances. */ static VALUE rb_git_index_update_all(int argc, VALUE *argv, VALUE self) { VALUE rb_pathspecs = rb_ary_new(); git_index *index; git_strarray pathspecs; int error, exception = 0; Data_Get_Struct(self, git_index, index); rb_scan_args(argc, argv, "01", &rb_pathspecs); rugged_rb_ary_to_strarray(rb_pathspecs, &pathspecs); error = git_index_update_all(index, &pathspecs, rb_block_given_p() ? rugged__index_matched_path_cb : NULL, &exception); xfree(pathspecs.strings); if (exception) rb_jump_tag(exception); rugged_exception_check(error); return Qnil; }
int main (int argc, char** argv) { git_index_matched_path_cb matched_cb = NULL; git_repository *repo = NULL; git_index *index; git_strarray array = {0}; int options = 0, count = 0; struct print_payload payload = {0}; git_threads_init(); parse_opts(&options, &count, argc, argv); init_array(&array, argc-count, argv+count); check_lg2(git_repository_open(&repo, "."), "No git repository", NULL); check_lg2(git_repository_index(&index, repo), "Could not open repository index", NULL); if (options&VERBOSE || options&SKIP) { matched_cb = &print_matched_cb; } payload.options = options; payload.repo = repo; if (options&UPDATE) { git_index_update_all(index, &array, matched_cb, &payload); } else { git_index_add_all(index, &array, 0, matched_cb, &payload); } git_index_write(index); git_index_free(index); git_repository_free(repo); git_threads_shutdown(); return 0; }
void test_index_addall__callback_filtering(void) { git_index *index; addall_create_test_repo(false); cl_git_pass(git_repository_index(&index, g_repo)); cl_git_pass( git_index_add_all(index, NULL, 0, addall_match_prefix, "file.")); check_stat_data(index, TEST_DIR "/file.bar", true); check_status(g_repo, 1, 0, 0, 1, 0, 0, 1); cl_git_mkfile(TEST_DIR "/file.zzz", "yet another one"); cl_git_mkfile(TEST_DIR "/more.zzz", "yet another one"); cl_git_mkfile(TEST_DIR "/other.zzz", "yet another one"); cl_git_pass(git_index_update_all(index, NULL, NULL, NULL)); check_stat_data(index, TEST_DIR "/file.bar", true); check_status(g_repo, 1, 0, 0, 4, 0, 0, 1); cl_git_pass( git_index_add_all(index, NULL, 0, addall_match_prefix, "other")); check_stat_data(index, TEST_DIR "/other.zzz", true); check_status(g_repo, 2, 0, 0, 3, 0, 0, 1); cl_git_pass( git_index_add_all(index, NULL, 0, addall_match_suffix, ".zzz")); check_status(g_repo, 4, 0, 0, 1, 0, 0, 1); cl_git_pass( git_index_remove_all(index, NULL, addall_match_suffix, ".zzz")); check_status(g_repo, 1, 0, 0, 4, 0, 0, 1); cl_git_fail_with( git_index_add_all(index, NULL, 0, addall_cancel_at, "more.zzz"), -123); check_status(g_repo, 3, 0, 0, 2, 0, 0, 1); cl_git_fail_with( git_index_add_all(index, NULL, 0, addall_cancel_at, "other.zzz"), -123); check_status(g_repo, 4, 0, 0, 1, 0, 0, 1); cl_git_pass( git_index_add_all(index, NULL, 0, addall_match_suffix, ".zzz")); check_status(g_repo, 5, 0, 0, 0, 0, 0, 1); cl_must_pass(p_unlink(TEST_DIR "/file.zzz")); cl_must_pass(p_unlink(TEST_DIR "/more.zzz")); cl_must_pass(p_unlink(TEST_DIR "/other.zzz")); cl_git_fail_with( git_index_update_all(index, NULL, addall_cancel_at, "more.zzz"), -123); /* file.zzz removed from index (so Index Adds 5 -> 4) and * more.zzz + other.zzz removed (so Worktree Dels 0 -> 2) */ check_status(g_repo, 4, 0, 0, 0, 2, 0, 1); cl_git_fail_with( git_index_update_all(index, NULL, addall_cancel_at, "other.zzz"), -123); /* more.zzz removed from index (so Index Adds 4 -> 3) and * Just other.zzz removed (so Worktree Dels 2 -> 1) */ check_status(g_repo, 3, 0, 0, 0, 1, 0, 1); git_index_free(index); }
void test_index_addall__repo_lifecycle(void) { int error; git_index *index; git_strarray paths = { NULL, 0 }; char *strs[1]; addall_create_test_repo(true); cl_git_pass(git_repository_index(&index, g_repo)); strs[0] = "file.*"; paths.strings = strs; paths.count = 1; cl_git_pass(git_index_add_all(index, &paths, 0, NULL, NULL)); check_stat_data(index, TEST_DIR "/file.bar", true); check_status(g_repo, 1, 0, 0, 1, 0, 0, 1); cl_git_rewritefile(TEST_DIR "/file.bar", "new content for file"); check_stat_data(index, TEST_DIR "/file.bar", false); check_status(g_repo, 1, 0, 0, 1, 0, 1, 1); cl_git_mkfile(TEST_DIR "/file.zzz", "yet another one"); cl_git_mkfile(TEST_DIR "/other.zzz", "yet another one"); cl_git_mkfile(TEST_DIR "/more.zzz", "yet another one"); check_status(g_repo, 1, 0, 0, 4, 0, 1, 1); cl_git_pass(git_index_update_all(index, NULL, NULL, NULL)); check_stat_data(index, TEST_DIR "/file.bar", true); check_status(g_repo, 1, 0, 0, 4, 0, 0, 1); cl_git_pass(git_index_add_all(index, &paths, 0, NULL, NULL)); check_stat_data(index, TEST_DIR "/file.zzz", true); check_status(g_repo, 2, 0, 0, 3, 0, 0, 1); cl_repo_commit_from_index(NULL, g_repo, NULL, 0, "first commit"); check_status(g_repo, 0, 0, 0, 3, 0, 0, 1); /* attempt to add an ignored file - does nothing */ strs[0] = "file.foo"; cl_git_pass(git_index_add_all(index, &paths, 0, NULL, NULL)); check_status(g_repo, 0, 0, 0, 3, 0, 0, 1); /* add with check - should generate error */ error = git_index_add_all( index, &paths, GIT_INDEX_ADD_CHECK_PATHSPEC, NULL, NULL); cl_assert_equal_i(GIT_EINVALIDSPEC, error); check_status(g_repo, 0, 0, 0, 3, 0, 0, 1); /* add with force - should allow */ cl_git_pass(git_index_add_all( index, &paths, GIT_INDEX_ADD_FORCE, NULL, NULL)); check_stat_data(index, TEST_DIR "/file.foo", true); check_status(g_repo, 1, 0, 0, 3, 0, 0, 0); /* now it's in the index, so regular add should work */ cl_git_rewritefile(TEST_DIR "/file.foo", "new content for file"); check_stat_data(index, TEST_DIR "/file.foo", false); check_status(g_repo, 1, 0, 0, 3, 0, 1, 0); cl_git_pass(git_index_add_all(index, &paths, 0, NULL, NULL)); check_stat_data(index, TEST_DIR "/file.foo", true); check_status(g_repo, 1, 0, 0, 3, 0, 0, 0); cl_git_pass(git_index_add_bypath(index, "more.zzz")); check_stat_data(index, TEST_DIR "/more.zzz", true); check_status(g_repo, 2, 0, 0, 2, 0, 0, 0); cl_git_rewritefile(TEST_DIR "/file.zzz", "new content for file"); check_status(g_repo, 2, 0, 0, 2, 0, 1, 0); cl_git_pass(git_index_add_bypath(index, "file.zzz")); check_stat_data(index, TEST_DIR "/file.zzz", true); check_status(g_repo, 2, 0, 1, 2, 0, 0, 0); strs[0] = "*.zzz"; cl_git_pass(git_index_remove_all(index, &paths, NULL, NULL)); check_status(g_repo, 1, 1, 0, 4, 0, 0, 0); cl_git_pass(git_index_add_bypath(index, "file.zzz")); check_status(g_repo, 1, 0, 1, 3, 0, 0, 0); cl_repo_commit_from_index(NULL, g_repo, NULL, 0, "second commit"); check_status(g_repo, 0, 0, 0, 3, 0, 0, 0); cl_must_pass(p_unlink(TEST_DIR "/file.zzz")); check_status(g_repo, 0, 0, 0, 3, 1, 0, 0); /* update_all should be able to remove entries */ cl_git_pass(git_index_update_all(index, NULL, NULL, NULL)); check_status(g_repo, 0, 1, 0, 3, 0, 0, 0); strs[0] = "*"; cl_git_pass(git_index_add_all(index, &paths, 0, NULL, NULL)); check_status(g_repo, 3, 1, 0, 0, 0, 0, 0); /* must be able to remove at any position while still updating other files */ cl_must_pass(p_unlink(TEST_DIR "/.gitignore")); cl_git_rewritefile(TEST_DIR "/file.zzz", "reconstructed file"); cl_git_rewritefile(TEST_DIR "/more.zzz", "altered file reality"); check_status(g_repo, 3, 1, 0, 1, 1, 1, 0); cl_git_pass(git_index_update_all(index, NULL, NULL, NULL)); check_status(g_repo, 2, 1, 0, 1, 0, 0, 0); /* this behavior actually matches 'git add -u' where "file.zzz" has * been removed from the index, so when you go to update, even though * it exists in the HEAD, it is not re-added to the index, leaving it * as a DELETE when comparing HEAD to index and as an ADD comparing * index to worktree */ git_index_free(index); }
int main() { git_libgit2_init(); git_repository* rep = nullptr; git_rebase* prebase = nullptr; git_rebase_options rebase_opt = GIT_REBASE_OPTIONS_INIT; git_reference* onto_branch = nullptr; git_annotated_commit* onto = nullptr; git_rebase_operation* operation = nullptr; size_t entrycount; size_t current; git_signature* me = nullptr; git_index* index = nullptr; git_oid new_commit; int error = 0; // git open git_repository_open(&rep, path); error = git_rebase_open(&prebase, rep, &rebase_opt); // There is no rebase in progress if (error == GIT_ENOTFOUND) { git_branch_lookup(&onto_branch, rep, "new", GIT_BRANCH_LOCAL); git_annotated_commit_from_ref(&onto, rep, onto_branch); git_rebase_init(&prebase, rep, nullptr /* current branch */, nullptr /* upstream */ , onto /* branch to rebase onto */, &rebase_opt); } else if (error < 0) { const git_error *e = giterr_last(); std::cout << "Error: " << error << " / " << e->klass << " : " << e->message << std::endl; goto SHUTDOWN; } entrycount = git_rebase_operation_entrycount(prebase); std::cout<< "rebase entry count: " << entrycount << "\n"; while (git_rebase_next(&operation, prebase) != GIT_ITEROVER) { current = git_rebase_operation_current(prebase); // (called `init` but not yet `next`) then this returns `GIT_REBASE_NO_OPERATION` std::cout<< "rebase current index: " << current << "\n"; if (GIT_REBASE_NO_OPERATION == current) { std::cout<< "rebase no operation" << "\n"; } operation = git_rebase_operation_byindex(prebase, 0); } // reslove conflicts git_repository_index(&index, rep); if (git_index_has_conflicts(index)) { // git checkout --theirs git_checkout_options opt = GIT_CHECKOUT_OPTIONS_INIT; opt.checkout_strategy |= GIT_CHECKOUT_USE_THEIRS; git_checkout_index(rep, index, &opt); } // add git_index_update_all(index, nullptr, nullptr, nullptr); git_index_write(index); // commit git_signature_now(&me, "XiaochenFTX", "*****@*****.**"); git_rebase_commit(&new_commit, prebase, me, me, "UTF-8", "new rebase"); error = git_rebase_finish(prebase, me); if (error < 0) { const git_error *e = giterr_last(); std::cout << "Error: " << error << " / " << e->klass << " : " << e->message << std::endl; goto SHUTDOWN; } // git_rebase_abort(prebase); git_rebase_free(prebase); SHUTDOWN: git_repository_free(rep); git_libgit2_shutdown(); return 0; }
int main() { git_libgit2_init(); git_repository* rep = nullptr; const git_annotated_commit* their_head[10]; git_merge_options merge_opt = GIT_MERGE_OPTIONS_INIT; git_checkout_options checkout_opt = GIT_CHECKOUT_OPTIONS_INIT; git_reference* branch = nullptr; git_index* index = nullptr; git_index_conflict_iterator* conflict_iterator = nullptr; git_oid new_tree_id; git_tree* new_tree = nullptr; git_signature* me = nullptr; git_reference* head = nullptr; git_commit* parent_our = nullptr; git_commit* parent_their = nullptr; git_oid commit_id; int error = 0; // git open error = git_repository_open(&rep, path); if (error < 0) { const git_error *e = giterr_last(); std::cout << "Error: " << error << " / " << e->klass << " : " << e->message << std::endl; goto SHUTDOWN; } // git merge <branch> git_reference_dwim(&branch, rep, "new"); git_annotated_commit_from_ref((git_annotated_commit **)&their_head[0], rep, branch); error = git_merge(rep, their_head, 1, &merge_opt, &checkout_opt); if (error < 0) { const git_error *e = giterr_last(); std::cout << "Error: " << error << " / " << e->klass << " : " << e->message << std::endl; goto SHUTDOWN; } git_repository_index(&index, rep); // reslove conflicts if (git_index_has_conflicts(index)) { const git_index_entry* ancestor_out = nullptr; const git_index_entry* our_out = nullptr; const git_index_entry* their_out = nullptr; git_index_conflict_iterator_new(&conflict_iterator, index); while (git_index_conflict_next(&ancestor_out, &our_out, &their_out, conflict_iterator) != GIT_ITEROVER) { if (ancestor_out) std::cout<< "ancestor: " << ancestor_out->path <<std::endl; if (our_out) std::cout<< "our: " << our_out->path <<std::endl; if (their_out) std::cout<< "their: " << their_out->path <<std::endl; // do sth. or rewrite file by code. ... // and remove the conflict // git_index_conflict_remove(index, "..."); } // git checkout --theirs <file> git_checkout_options opt = GIT_CHECKOUT_OPTIONS_INIT; opt.checkout_strategy |= GIT_CHECKOUT_USE_THEIRS; // const char* p = "file"; // opt.paths.strings = (char**)&p; // opt.paths.count = 1; git_checkout_index(rep, index, &opt); git_index_conflict_iterator_free(conflict_iterator); } // add and commit git_index_update_all(index, nullptr, nullptr, nullptr); git_index_write(index); git_index_write_tree(&new_tree_id, index); git_tree_lookup(&new_tree, rep, &new_tree_id); git_signature_now(&me, "XiaochenFTX", "*****@*****.**"); git_repository_head(&head, rep); git_commit_lookup(&parent_our, rep, git_reference_target(head)); git_commit_lookup(&parent_their, rep, git_reference_target(branch)); git_commit_create_v(&commit_id, rep, "HEAD", me, me, "UTF-8", "merge commit", new_tree, 2, parent_our, parent_their); git_repository_state_cleanup(rep); SHUTDOWN: git_repository_free(rep); git_libgit2_shutdown(); return 0; }