static void *run_index_diffs_with_modifier(void *arg) { int thread = *(int *)arg; git_diff_options opts = GIT_DIFF_OPTIONS_INIT; git_diff *diff = NULL; git_index *idx = NULL; git_repository *repo; cl_git_pass(git_repository_open(&repo, git_repository_path(_repo))); cl_git_pass(git_repository_index(&idx, repo)); /* have first thread altering the index as we go */ if (thread == 0) { int i; for (i = 0; i < 300; ++i) { switch (i & 0x03) { case 0: (void)git_index_add_bypath(idx, "new_file"); break; case 1: (void)git_index_remove_bypath(idx, "modified_file"); break; case 2: (void)git_index_remove_bypath(idx, "new_file"); break; case 3: (void)git_index_add_bypath(idx, "modified_file"); break; } git_thread_yield(); } goto done; } /* only use explicit index in this test to prevent reloading */ switch (thread & 0x03) { case 0: /* diff index to workdir */; cl_git_pass(git_diff_index_to_workdir(&diff, repo, idx, &opts)); break; case 1: /* diff tree 'a' to index */; cl_git_pass(git_diff_tree_to_index(&diff, repo, _a, idx, &opts)); break; case 2: /* diff tree 'b' to index */; cl_git_pass(git_diff_tree_to_index(&diff, repo, _b, idx, &opts)); break; case 3: /* diff index to workdir reversed */; opts.flags |= GIT_DIFF_REVERSE; cl_git_pass(git_diff_index_to_workdir(&diff, repo, idx, &opts)); break; } /* results will be unpredictable with index modifier thread running */ git_diff_free(diff); done: git_index_free(idx); git_repository_free(repo); git_error_clear(); return arg; }
static void create_index(struct checkout_index_entry *entries, size_t entries_len) { git_buf path = GIT_BUF_INIT; size_t i; for (i = 0; i < entries_len; i++) { git_buf_joinpath(&path, TEST_REPO_PATH, entries[i].path); if (entries[i].stage == 3 && (i == 0 || strcmp(entries[i-1].path, entries[i].path) != 0 || entries[i-1].stage != 2)) p_unlink(git_buf_cstr(&path)); git_index_remove_bypath(g_index, entries[i].path); } for (i = 0; i < entries_len; i++) { git_index_entry entry; memset(&entry, 0x0, sizeof(git_index_entry)); entry.mode = entries[i].mode; GIT_IDXENTRY_STAGE_SET(&entry, entries[i].stage); git_oid_fromstr(&entry.id, entries[i].oid_str); entry.path = entries[i].path; cl_git_pass(git_index_add(g_index, &entry)); } git_buf_free(&path); }
void GitWrapper::removeDeletedFromIndex(git_repository *repo, git_index* index) { git_status_foreach(repo, [] (const char *path, unsigned int status_flags, void *payload) -> int { if(status_flags & GIT_STATUS_WT_DELETED) { int i = 55; git_index * index = static_cast<git_index*>(payload); git_index_remove_bypath(index,path); } return 0; }, index); }
void test_index_conflicts__moved_to_reuc_on_remove(void) { const git_index_entry *entry; size_t i; cl_assert(git_index_entrycount(repo_index) == 8); cl_git_pass(p_unlink("./mergedrepo/conflicts-one.txt")); cl_git_pass(git_index_remove_bypath(repo_index, "conflicts-one.txt")); cl_assert(git_index_entrycount(repo_index) == 5); for (i = 0; i < git_index_entrycount(repo_index); i++) { cl_assert(entry = git_index_get_byindex(repo_index, i)); cl_assert(strcmp(entry->path, "conflicts-one.txt") != 0); } }
void test_stash_save__deleted_in_index_modified_in_workdir(void) { git_index *index; git_repository_index(&index, repo); cl_git_pass(git_index_remove_bypath(index, "who")); cl_git_pass(git_index_write(index)); assert_status(repo, "who", GIT_STATUS_WT_NEW | GIT_STATUS_INDEX_DELETED); cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT)); assert_blob_oid("stash@{0}^0:who", "a0400d4954659306a976567af43125a0b1aa8595"); assert_blob_oid("stash@{0}^2:who", NULL); git_index_free(index); }
void test_checkout_tree__donot_update_deleted_file_by_default(void) { git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; git_oid old_id, new_id; git_commit *old_commit = NULL, *new_commit = NULL; git_index *index = NULL; checkout_counts ct; opts.checkout_strategy = GIT_CHECKOUT_SAFE; memset(&ct, 0, sizeof(ct)); opts.notify_flags = GIT_CHECKOUT_NOTIFY_ALL; opts.notify_cb = checkout_count_callback; opts.notify_payload = &ct; cl_git_pass(git_repository_index(&index, g_repo)); cl_git_pass(git_oid_fromstr(&old_id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644")); cl_git_pass(git_commit_lookup(&old_commit, g_repo, &old_id)); cl_git_pass(git_reset(g_repo, (git_object *)old_commit, GIT_RESET_HARD, NULL)); cl_git_pass(p_unlink("testrepo/branch_file.txt")); cl_git_pass(git_index_remove_bypath(index ,"branch_file.txt")); cl_git_pass(git_index_write(index)); cl_assert(!git_path_exists("testrepo/branch_file.txt")); cl_git_pass(git_oid_fromstr(&new_id, "099fabac3a9ea935598528c27f866e34089c2eff")); cl_git_pass(git_commit_lookup(&new_commit, g_repo, &new_id)); cl_git_fail(git_checkout_tree(g_repo, (git_object *)new_commit, &opts)); cl_assert_equal_i(1, ct.n_conflicts); cl_assert_equal_i(1, ct.n_updates); git_commit_free(old_commit); git_commit_free(new_commit); git_index_free(index); }
void test_submodule_lookup__just_added(void) { git_submodule *sm; git_buf snap1 = GIT_BUF_INIT, snap2 = GIT_BUF_INIT; git_reference *original_head = NULL; refute_submodule_exists(g_repo, "sm_just_added", GIT_ENOTFOUND); refute_submodule_exists(g_repo, "sm_just_added_2", GIT_ENOTFOUND); refute_submodule_exists(g_repo, "sm_just_added_idx", GIT_ENOTFOUND); refute_submodule_exists(g_repo, "sm_just_added_head", GIT_ENOTFOUND); refute_submodule_exists(g_repo, "mismatch_name", GIT_ENOTFOUND); refute_submodule_exists(g_repo, "mismatch_path", GIT_ENOTFOUND); baseline_tests(); cl_git_pass(git_futils_readbuffer(&snap1, "submod2/.gitmodules")); cl_git_pass(git_repository_head(&original_head, g_repo)); cl_git_pass(git_submodule_add_setup(&sm, g_repo, "https://github.com/libgit2/libgit2.git", "sm_just_added", 1)); git_submodule_free(sm); assert_submodule_exists(g_repo, "sm_just_added"); cl_git_pass(git_submodule_add_setup(&sm, g_repo, "https://github.com/libgit2/libgit2.git", "sm_just_added_2", 1)); assert_submodule_exists(g_repo, "sm_just_added_2"); cl_git_fail(git_submodule_add_finalize(sm)); /* fails if no HEAD */ git_submodule_free(sm); add_submodule_with_commit("sm_just_added_head"); cl_repo_commit_from_index(NULL, g_repo, NULL, 0, "commit new sm to head"); assert_submodule_exists(g_repo, "sm_just_added_head"); add_submodule_with_commit("sm_just_added_idx"); assert_submodule_exists(g_repo, "sm_just_added_idx"); cl_git_pass(git_futils_readbuffer(&snap2, "submod2/.gitmodules")); cl_git_append2file( "submod2/.gitmodules", "\n[submodule \"mismatch_name\"]\n" "\tpath = mismatch_path\n" "\turl = https://example.com/example.git\n\n"); assert_submodule_exists(g_repo, "mismatch_name"); assert_submodule_exists(g_repo, "mismatch_path"); assert_submodule_exists(g_repo, "sm_just_added"); assert_submodule_exists(g_repo, "sm_just_added_2"); assert_submodule_exists(g_repo, "sm_just_added_idx"); assert_submodule_exists(g_repo, "sm_just_added_head"); baseline_tests(); cl_git_rewritefile("submod2/.gitmodules", snap2.ptr); git_buf_free(&snap2); refute_submodule_exists(g_repo, "mismatch_name", GIT_ENOTFOUND); refute_submodule_exists(g_repo, "mismatch_path", GIT_ENOTFOUND); assert_submodule_exists(g_repo, "sm_just_added"); assert_submodule_exists(g_repo, "sm_just_added_2"); assert_submodule_exists(g_repo, "sm_just_added_idx"); assert_submodule_exists(g_repo, "sm_just_added_head"); baseline_tests(); cl_git_rewritefile("submod2/.gitmodules", snap1.ptr); git_buf_free(&snap1); refute_submodule_exists(g_repo, "mismatch_name", GIT_ENOTFOUND); refute_submodule_exists(g_repo, "mismatch_path", GIT_ENOTFOUND); /* note error code change, because add_setup made a repo in the workdir */ refute_submodule_exists(g_repo, "sm_just_added", GIT_EEXISTS); refute_submodule_exists(g_repo, "sm_just_added_2", GIT_EEXISTS); /* these still exist in index and head respectively */ assert_submodule_exists(g_repo, "sm_just_added_idx"); assert_submodule_exists(g_repo, "sm_just_added_head"); baseline_tests(); { git_index *idx; cl_git_pass(git_repository_index(&idx, g_repo)); cl_git_pass(git_index_remove_bypath(idx, "sm_just_added_idx")); cl_git_pass(git_index_remove_bypath(idx, "sm_just_added_head")); cl_git_pass(git_index_write(idx)); git_index_free(idx); } refute_submodule_exists(g_repo, "sm_just_added_idx", GIT_EEXISTS); assert_submodule_exists(g_repo, "sm_just_added_head"); { git_signature *sig; cl_git_pass(git_signature_now(&sig, "resetter", "*****@*****.**")); cl_git_pass(git_reference_create(NULL, g_repo, "refs/heads/master", git_reference_target(original_head), 1, sig, "move head back")); git_signature_free(sig); git_reference_free(original_head); } refute_submodule_exists(g_repo, "sm_just_added_head", GIT_EEXISTS); }
void QGit::stageFiles(QStringList items) { git_repository *repo = nullptr; git_index *index = nullptr; int res = 0; QGitError error; try { if (items.count() == 0) { throw QGitError(); } res = git_repository_open(&repo, m_path.absolutePath().toUtf8().constData()); if (res) { throw QGitError("git_repository_open", res); } res = git_repository_index(&index, repo); if (res) { throw QGitError("git_repository_index", res); } for(const auto &item: items) { res = git_index_add_bypath(index, item.toUtf8().constData()); if (res == GIT_ENOTFOUND) { // FIXME: Properly implement stage add/delete files. res = git_index_remove_bypath(index, item.toUtf8().constData()); if (res) { throw QGitError("git_index_remove_bypath", res); } } if (res) { throw QGitError("git_index_add_bypath", res); } } res = git_index_write(index); if (res) { throw QGitError("git_index_write", res); } } catch(const QGitError &ex) { error = ex; } emit stageFilesReply(error); if (index) { git_index_free(index); index = nullptr; } if (repo) { git_repository_free(repo); repo = nullptr; } }
void test_checkout_tree__case_changing_rename(void) { git_index *index; git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; git_oid master_id, dir_commit_id, tree_id, commit_id; git_commit *master_commit, *dir_commit; git_tree *tree; git_signature *signature; const git_index_entry *index_entry; bool case_sensitive; assert_on_branch(g_repo, "master"); cl_git_pass(git_repository_index(&index, g_repo)); /* Switch branches and perform a case-changing rename */ opts.checkout_strategy = GIT_CHECKOUT_FORCE; cl_git_pass(git_reference_name_to_id(&dir_commit_id, g_repo, "refs/heads/dir")); cl_git_pass(git_commit_lookup(&dir_commit, g_repo, &dir_commit_id)); cl_git_pass(git_checkout_tree(g_repo, (git_object *)dir_commit, &opts)); cl_git_pass(git_repository_set_head(g_repo, "refs/heads/dir")); cl_assert(git_path_isfile("testrepo/README")); case_sensitive = !git_path_isfile("testrepo/readme"); cl_assert(index_entry = git_index_get_bypath(index, "README", 0)); cl_assert_equal_s("README", index_entry->path); cl_git_pass(git_index_remove_bypath(index, "README")); cl_git_pass(p_rename("testrepo/README", "testrepo/__readme__")); cl_git_pass(p_rename("testrepo/__readme__", "testrepo/readme")); cl_git_append2file("testrepo/readme", "An addendum..."); cl_git_pass(git_index_add_bypath(index, "readme")); cl_git_pass(git_index_write(index)); cl_git_pass(git_index_write_tree(&tree_id, index)); cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_id)); cl_git_pass(git_signature_new(&signature, "Renamer", "*****@*****.**", time(NULL), 0)); cl_git_pass(git_commit_create(&commit_id, g_repo, "refs/heads/dir", signature, signature, NULL, "case-changing rename", tree, 1, (const git_commit **)&dir_commit)); cl_assert(git_path_isfile("testrepo/readme")); if (case_sensitive) cl_assert(!git_path_isfile("testrepo/README")); cl_assert(index_entry = git_index_get_bypath(index, "readme", 0)); cl_assert_equal_s("readme", index_entry->path); /* Switching back to master should rename readme -> README */ opts.checkout_strategy = GIT_CHECKOUT_SAFE; cl_git_pass(git_reference_name_to_id(&master_id, g_repo, "refs/heads/master")); cl_git_pass(git_commit_lookup(&master_commit, g_repo, &master_id)); cl_git_pass(git_checkout_tree(g_repo, (git_object *)master_commit, &opts)); cl_git_pass(git_repository_set_head(g_repo, "refs/heads/master")); assert_on_branch(g_repo, "master"); cl_assert(git_path_isfile("testrepo/README")); if (case_sensitive) cl_assert(!git_path_isfile("testrepo/readme")); cl_assert(index_entry = git_index_get_bypath(index, "README", 0)); cl_assert_equal_s("README", index_entry->path); git_index_free(index); git_signature_free(signature); git_tree_free(tree); git_commit_free(dir_commit); git_commit_free(master_commit); }
void Index::remove_path(const char * path) { int res = git_index_remove_bypath(index_.get(), path); assert(res == 0); }
void Index::remove(const std::string& path) { Exception::git2_assert(git_index_remove_bypath(data(),path.c_str())); }
void PmrWorkspace::stageFile(const QString &pPath, bool pStage) { // Un/stage the file, which path is given, and let people know of the // outcome if (isOpen()) { QByteArray relativePathByteArray = QDir(mPath).relativeFilePath(pPath).toUtf8(); const char *relativePath = relativePathByteArray.constData(); bool success = false; git_index *index; if (git_repository_index(&index, mGitRepository) == GIT_OK) { if (pStage) { uint statusFlags = 0; git_status_file(&statusFlags, mGitRepository, relativePath); if ((statusFlags & GIT_STATUS_WT_DELETED) != 0) { success = git_index_remove_bypath(index, relativePath) == GIT_OK; } else { success = git_index_add_bypath(index, relativePath) == GIT_OK; } } else if (git_repository_head_unborn(mGitRepository) == 1) { success = git_index_remove_bypath(index, relativePath) == GIT_OK; } else { // We need to add a "reset stage" to the index, which means // getting the tree for HEAD and tree_entry for the file git_reference *head; if (git_repository_head(&head, mGitRepository) == GIT_OK) { git_tree *headTree; if (git_reference_peel(reinterpret_cast<git_object **>(&headTree), head, GIT_OBJECT_TREE) == GIT_OK) { git_tree_entry *headEntry; if (git_tree_entry_bypath(&headEntry, headTree, relativePath) == GIT_OK) { git_index_entry indexEntry; memset(&indexEntry, '\0', sizeof(git_index_entry)); indexEntry.id = *git_tree_entry_id(headEntry); indexEntry.mode = uint32_t(git_tree_entry_filemode(headEntry)); indexEntry.path = relativePath; git_index_add(index, &indexEntry); git_tree_entry_free(headEntry); success = true; } else { success = git_index_remove_bypath(index, relativePath) == GIT_OK; } git_tree_free(headTree); } git_reference_free(head); } } if (success) { git_index_write(index); } git_index_free(index); } if (!success) { emitGitError(tr("An error occurred while trying to stage %1.").arg(pPath)); } } }
static void test_with_many(int expected_new) { git_index *index; git_tree *tree, *new_tree; git_diff *diff = NULL; diff_expects exp; git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT; git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT; cl_git_pass(git_repository_index(&index, g_repo)); cl_git_pass( git_revparse_single((git_object **)&tree, g_repo, "HEAD^{tree}")); cl_git_pass(p_rename("renames/ikeepsix.txt", "renames/ikeepsix2.txt")); cl_git_pass(git_index_remove_bypath(index, "ikeepsix.txt")); cl_git_pass(git_index_add_bypath(index, "ikeepsix2.txt")); cl_git_pass(git_index_write(index)); cl_git_pass(git_diff_tree_to_index(&diff, g_repo, tree, index, &diffopts)); memset(&exp, 0, sizeof(exp)); cl_git_pass(git_diff_foreach( diff, diff_file_cb, NULL, NULL, NULL, &exp)); cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]); cl_assert_equal_i(expected_new + 1, exp.file_status[GIT_DELTA_ADDED]); cl_assert_equal_i(expected_new + 2, exp.files); opts.flags = GIT_DIFF_FIND_ALL; cl_git_pass(git_diff_find_similar(diff, &opts)); memset(&exp, 0, sizeof(exp)); cl_git_pass(git_diff_foreach( diff, diff_file_cb, NULL, NULL, NULL, &exp)); cl_assert_equal_i(1, exp.file_status[GIT_DELTA_RENAMED]); cl_assert_equal_i(expected_new, exp.file_status[GIT_DELTA_ADDED]); cl_assert_equal_i(expected_new + 1, exp.files); git_diff_free(diff); cl_repo_commit_from_index(NULL, g_repo, NULL, 1372350000, "yoyoyo"); cl_git_pass(git_revparse_single( (git_object **)&new_tree, g_repo, "HEAD^{tree}")); cl_git_pass(git_diff_tree_to_tree( &diff, g_repo, tree, new_tree, &diffopts)); memset(&exp, 0, sizeof(exp)); cl_git_pass(git_diff_foreach( diff, diff_file_cb, NULL, NULL, NULL, &exp)); cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]); cl_assert_equal_i(expected_new + 1, exp.file_status[GIT_DELTA_ADDED]); cl_assert_equal_i(expected_new + 2, exp.files); opts.flags = GIT_DIFF_FIND_ALL; cl_git_pass(git_diff_find_similar(diff, &opts)); memset(&exp, 0, sizeof(exp)); cl_git_pass(git_diff_foreach( diff, diff_file_cb, NULL, NULL, NULL, &exp)); cl_assert_equal_i(1, exp.file_status[GIT_DELTA_RENAMED]); cl_assert_equal_i(expected_new, exp.file_status[GIT_DELTA_ADDED]); cl_assert_equal_i(expected_new + 1, exp.files); git_diff_free(diff); git_tree_free(new_tree); git_tree_free(tree); git_index_free(index); }
void NotesModel::updateGitStatus() { git_repository *repo = NULL; git_index *idx = NULL; git_signature *me = NULL; try { e(git_repository_open(&repo, notesFolder().absolutePath().toUtf8().constData())); /* Each repository owns an index */ e(git_repository_index(&idx, repo)); /* Read index from disk : FIXME Necessary ?*/ e(git_index_read(idx, true)); /* Set Option for git status */ git_status_options opts = { 1, GIT_STATUS_SHOW_INDEX_AND_WORKDIR, GIT_STATUS_OPT_INCLUDE_UNTRACKED | // GIT_STATUS_OPT_INCLUDE_UNMODIFIED | GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS }; //status_data d; int state = git_repository_state(repo); git_status_list *statuses = NULL; e(git_status_list_new(&statuses, repo, &opts)); size_t count = git_status_list_entrycount(statuses); if ((count == 0) && (GIT_REPOSITORY_STATE_MERGE != state)) { return; // No modified file, exit } for (size_t i=0; i<count; ++i) { const git_status_entry *entry = git_status_byindex(statuses, i); /* For each new file add it to the index */ if ((entry->status & GIT_STATUS_WT_MODIFIED) || (entry->status & GIT_STATUS_WT_RENAMED) || (entry->status & GIT_STATUS_WT_TYPECHANGE) || entry->status == GIT_STATUS_WT_NEW) { e(git_index_add_bypath(idx, entry->index_to_workdir->new_file.path)); } else if (entry->status & GIT_STATUS_WT_DELETED) { e(git_index_remove_bypath(idx, entry->index_to_workdir->old_file.path)); } } e(git_index_write(idx)); /* Write the index contents to the ODB as a tree */ git_oid new_tree_id; e(git_index_write_tree(&new_tree_id, idx)); /* Create signature */ e(git_signature_now(&me, "sparkleNotes", "*****@*****.**")); /* Get tree ref */ git_tree *tree; e(git_tree_lookup(&tree, repo, &new_tree_id)); /* Get parent commit */ git_oid parentCommitId; git_commit *parent; int nparents; int err; err = git_reference_name_to_id( &parentCommitId, repo, "HEAD" ); if (err == -3) { nparents = 0; } else { e(git_commit_lookup( &parent, repo, &parentCommitId )); nparents = 1; } const git_commit *parents [1] = { parent }; git_oid new_commit_id; e(git_commit_create( &new_commit_id, repo, "HEAD", /* name of ref to update */ me, /* author */ me, /* committer */ "UTF-8", /* message encoding */ "Modif on notes", /* message */ tree, /* root tree */ nparents, /* parent count */ parents)); /* parents */ if(nparents > 0) git_commit_free (parent); git_checkout_index (repo, idx, NULL); git_signature_free(me); git_index_free(idx); git_repository_free(repo); } catch (int error) { const git_error *err = giterr_last(); if (err != NULL) qDebug() << QString::number(err->klass) + "\t" + QString(err->message); giterr_clear(); git_signature_free(me); git_index_free(idx); git_repository_free(repo); } }