void test_stash_save__cannot_stash_when_there_are_no_local_change(void) { git_index *index; git_oid stash_tip_oid; cl_git_pass(git_repository_index(&index, repo)); /* * 'what', 'where' and 'who' are being committed. * 'when' remains untracked. */ cl_git_pass(git_index_add_bypath(index, "what")); cl_git_pass(git_index_add_bypath(index, "where")); cl_git_pass(git_index_add_bypath(index, "who")); cl_repo_commit_from_index(NULL, repo, signature, 0, "Initial commit"); git_index_free(index); cl_assert_equal_i(GIT_ENOTFOUND, git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT)); p_unlink("stash/when"); cl_assert_equal_i(GIT_ENOTFOUND, git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED)); }
static void push_three_states(void) { git_oid oid; git_index *index; cl_git_mkfile("stash/zero.txt", "content\n"); cl_git_pass(git_repository_index(&index, repo)); cl_git_pass(git_index_add_bypath(index, "zero.txt")); commit_staged_files(&oid, index, signature); cl_assert(git_path_exists("stash/zero.txt")); cl_git_mkfile("stash/one.txt", "content\n"); cl_git_pass(git_stash_save(&oid, repo, signature, "First", GIT_STASH_INCLUDE_UNTRACKED)); cl_assert(!git_path_exists("stash/one.txt")); cl_assert(git_path_exists("stash/zero.txt")); cl_git_mkfile("stash/two.txt", "content\n"); cl_git_pass(git_stash_save(&oid, repo, signature, "Second", GIT_STASH_INCLUDE_UNTRACKED)); cl_assert(!git_path_exists("stash/two.txt")); cl_assert(git_path_exists("stash/zero.txt")); cl_git_mkfile("stash/three.txt", "content\n"); cl_git_pass(git_stash_save(&oid, repo, signature, "Third", GIT_STASH_INCLUDE_UNTRACKED)); cl_assert(!git_path_exists("stash/three.txt")); cl_assert(git_path_exists("stash/zero.txt")); git_index_free(index); }
void test_stash_foreach__can_enumerate_a_repository(void) { char *oids_default[] = { "1d91c842a7cdfc25872b3a763e5c31add8816c25", NULL }; char *oids_untracked[] = { "7f89a8b15c878809c5c54d1ff8f8c9674154017b", "1d91c842a7cdfc25872b3a763e5c31add8816c25", NULL }; char *oids_ignored[] = { "c95599a8fef20a7e57582c6727b1a0d02e0a5828", "7f89a8b15c878809c5c54d1ff8f8c9674154017b", "1d91c842a7cdfc25872b3a763e5c31add8816c25", NULL }; cl_git_pass(git_repository_init(&repo, REPO_NAME, 0)); setup_stash(repo, signature); cl_git_pass(git_stash_save( &stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT)); data.oids = oids_default; cl_git_pass(git_stash_foreach(repo, callback_cb, &data)); cl_assert_equal_i(1, data.invokes); data.oids = oids_untracked; data.invokes = 0; cl_git_pass(git_stash_save( &stash_tip_oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED)); cl_git_pass(git_stash_foreach(repo, callback_cb, &data)); cl_assert_equal_i(2, data.invokes); data.oids = oids_ignored; data.invokes = 0; cl_git_pass(git_stash_save( &stash_tip_oid, repo, signature, NULL, GIT_STASH_INCLUDE_IGNORED)); cl_git_pass(git_stash_foreach(repo, callback_cb, &data)); cl_assert_equal_i(3, data.invokes); }
/* * Note: this test was flaky prior to fixing #4101 -- run it several * times to get a failure. The issues is that whether the fast * (stat-only) codepath is used inside stash's diff operation depends * on whether files are "racily clean", and there doesn't seem to be * an easy way to force the exact required state. */ void test_stash_save__untracked_regression(void) { git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; const char *paths[] = {"what", "where", "how", "why"}; git_reference *head; git_commit *head_commit; git_buf untracked_dir; const char* workdir = git_repository_workdir(repo); git_buf_init(&untracked_dir, 0); git_buf_printf(&untracked_dir, "%sz", workdir); cl_assert(!p_mkdir(untracked_dir.ptr, 0777)); cl_git_pass(git_repository_head(&head, repo)); cl_git_pass(git_reference_peel((git_object **)&head_commit, head, GIT_OBJ_COMMIT)); opts.checkout_strategy = GIT_CHECKOUT_FORCE; opts.paths.strings = (char **)paths; opts.paths.count = 4; cl_git_pass(git_checkout_tree(repo, (git_object*)head_commit, &opts)); cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT)); assert_commit_message_contains("refs/stash", "WIP on master"); git_reference_free(head); git_commit_free(head_commit); git_buf_dispose(&untracked_dir); }
void test_stash_save__does_not_keep_index_by_default(void) { /* $ git stash $ git show refs/stash:what see you later $ git show refs/stash:how not so small and $ git show refs/stash:who funky world $ git show refs/stash:when fatal: Path 'when' exists on disk, but not in 'stash'. $ git show refs/stash^2:what goodbye $ git show refs/stash^2:how not so small and $ git show refs/stash^2:who world $ git show refs/stash^2:when fatal: Path 'when' exists on disk, but not in 'stash^2'. $ git status --short ?? when */ unsigned int status; cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT)); cl_git_pass(git_status_file(&status, repo, "when")); assert_blob_oid("refs/stash:what", "bc99dc98b3eba0e9157e94769cd4d49cb49de449"); /* see you later */ assert_blob_oid("refs/stash:how", "e6d64adb2c7f3eb8feb493b556cc8070dca379a3"); /* not so small and */ assert_blob_oid("refs/stash:who", "a0400d4954659306a976567af43125a0b1aa8595"); /* funky world */ assert_blob_oid("refs/stash:when", NULL); assert_blob_oid("refs/stash:why", "88c2533e21f098b89c91a431d8075cbdbe422a51"); /* would anybody use stash? */ assert_blob_oid("refs/stash:where", "e3d6434ec12eb76af8dfa843a64ba6ab91014a0b"); /* .... */ assert_blob_oid("refs/stash:.gitignore", "ac4d88de61733173d9959e4b77c69b9f17a00980"); assert_blob_oid("refs/stash:just.ignore", NULL); assert_blob_oid("refs/stash^2:what", "dd7e1c6f0fefe118f0b63d9f10908c460aa317a6"); /* goodbye */ assert_blob_oid("refs/stash^2:how", "e6d64adb2c7f3eb8feb493b556cc8070dca379a3"); /* not so small and */ assert_blob_oid("refs/stash^2:who", "cc628ccd10742baea8241c5924df992b5c019f71"); /* world */ assert_blob_oid("refs/stash^2:when", NULL); assert_blob_oid("refs/stash^2:why", "88c2533e21f098b89c91a431d8075cbdbe422a51"); /* would anybody use stash? */ assert_blob_oid("refs/stash^2:where", "e08f7fbb9a42a0c5367cf8b349f1f08c3d56bd72"); /* ???? */ assert_blob_oid("refs/stash^2:.gitignore", "ac4d88de61733173d9959e4b77c69b9f17a00980"); assert_blob_oid("refs/stash^2:just.ignore", NULL); assert_blob_oid("refs/stash^3", NULL); cl_assert_equal_i(GIT_STATUS_WT_NEW, status); }
void test_stash_save__can_accept_a_message(void) { cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, MESSAGE, GIT_STASH_DEFAULT)); assert_commit_message_contains("refs/stash^2", "index on master: "); assert_commit_message_contains("refs/stash", "On master: " MESSAGE); }
void test_stash_save__can_stash_against_a_detached_head(void) { git_repository_detach_head(repo); cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT)); assert_commit_message_contains("refs/stash^2", "index on (no branch): "); assert_commit_message_contains("refs/stash", "WIP on (no branch): "); }
void test_stash_save__stashing_updates_the_reflog(void) { assert_object_oid("refs/stash@{0}", NULL, GIT_OBJ_COMMIT); cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT)); assert_object_oid("refs/stash@{0}", git_oid_tostr_s(&stash_tip_oid), GIT_OBJ_COMMIT); assert_object_oid("refs/stash@{1}", NULL, GIT_OBJ_COMMIT); }
void test_stash_save__can_keep_index(void) { cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_KEEP_INDEX)); assert_status("what", GIT_STATUS_INDEX_MODIFIED); assert_status("how", GIT_STATUS_INDEX_MODIFIED); assert_status("who", GIT_STATUS_CURRENT); assert_status("when", GIT_STATUS_WT_NEW); assert_status("just.ignore", GIT_STATUS_IGNORED); }
void test_stash_save__cannot_stash_against_an_unborn_branch(void) { git_reference *head; cl_git_pass(git_reference_symbolic_create(&head, repo, "HEAD", "refs/heads/unborn", 1, NULL)); cl_assert_equal_i(GIT_EUNBORNBRANCH, git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT)); git_reference_free(head); }
void test_stash_save__does_not_keep_index_by_default(void) { /* $ git stash $ git show refs/stash:what see you later $ git show refs/stash:how not so small and $ git show refs/stash:who funky world $ git show refs/stash:when fatal: Path 'when' exists on disk, but not in 'stash'. $ git show refs/stash^2:what goodbye $ git show refs/stash^2:how not so small and $ git show refs/stash^2:who world $ git show refs/stash^2:when fatal: Path 'when' exists on disk, but not in 'stash^2'. $ git status --short ?? when */ unsigned int status; cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT)); cl_git_pass(git_status_file(&status, repo, "when")); assert_blob_oid("refs/stash:what", "bc99dc98b3eba0e9157e94769cd4d49cb49de449"); /* see you later */ assert_blob_oid("refs/stash:how", "e6d64adb2c7f3eb8feb493b556cc8070dca379a3"); /* not so small and */ assert_blob_oid("refs/stash:who", "a0400d4954659306a976567af43125a0b1aa8595"); /* funky world */ assert_blob_oid("refs/stash:when", NULL); assert_blob_oid("refs/stash:just.ignore", NULL); assert_blob_oid("refs/stash^2:what", "dd7e1c6f0fefe118f0b63d9f10908c460aa317a6"); /* goodbye */ assert_blob_oid("refs/stash^2:how", "e6d64adb2c7f3eb8feb493b556cc8070dca379a3"); /* not so small and */ assert_blob_oid("refs/stash^2:who", "cc628ccd10742baea8241c5924df992b5c019f71"); /* world */ assert_blob_oid("refs/stash^2:when", NULL); assert_blob_oid("refs/stash^2:just.ignore", NULL); assert_blob_oid("refs/stash^3", NULL); cl_assert_equal_i(GIT_STATUS_WT_NEW, status); }
void test_stash_save__cannot_stash_against_a_bare_repository(void) { git_repository *local; cl_git_pass(git_repository_init(&local, "sorry-it-is-a-non-bare-only-party", 1)); cl_assert_equal_i(GIT_EBAREREPO, git_stash_save(&stash_tip_oid, local, signature, NULL, GIT_STASH_DEFAULT)); git_repository_free(local); }
void test_stash_save__can_include_untracked_and_ignored_files(void) { cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED | GIT_STASH_INCLUDE_IGNORED)); assert_commit_message_contains("refs/stash^3", "untracked files on master: "); assert_blob_oid("refs/stash^3:what", NULL); assert_blob_oid("refs/stash^3:how", NULL); assert_blob_oid("refs/stash^3:who", NULL); assert_blob_oid("refs/stash^3:when", "b6ed15e81e2593d7bb6265eb4a991d29dc3e628b"); assert_blob_oid("refs/stash^3:just.ignore", "78925fb1236b98b37a35e9723033e627f97aa88b"); }
void test_stash_save__cannot_stash_against_an_unborn_branch(void) { git_reference *head; cl_git_pass(git_reference_lookup(&head, repo, "HEAD")); cl_git_pass(git_reference_set_target(head, "refs/heads/unborn")); cl_assert_equal_i(GIT_EORPHANEDHEAD, git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT)); git_reference_free(head); }
void test_stash_apply__initialize(void) { git_oid oid; repo = cl_git_sandbox_init_new("stash"); cl_git_pass(git_repository_index(&repo_index, repo)); cl_git_pass(git_signature_new(&signature, "nulltoken", "*****@*****.**", 1323847743, 60)); /* Wed Dec 14 08:29:03 2011 +0100 */ cl_git_mkfile("stash/what", "hello\n"); cl_git_mkfile("stash/how", "small\n"); cl_git_mkfile("stash/who", "world\n"); cl_git_mkfile("stash/where", "meh\n"); cl_git_pass(git_index_add_bypath(repo_index, "what")); cl_git_pass(git_index_add_bypath(repo_index, "how")); cl_git_pass(git_index_add_bypath(repo_index, "who")); cl_repo_commit_from_index(NULL, repo, signature, 0, "Initial commit"); cl_git_rewritefile("stash/what", "goodbye\n"); cl_git_rewritefile("stash/who", "funky world\n"); cl_git_mkfile("stash/when", "tomorrow\n"); cl_git_mkfile("stash/why", "would anybody use stash?\n"); cl_git_mkfile("stash/where", "????\n"); cl_git_pass(git_index_add_bypath(repo_index, "who")); cl_git_pass(git_index_add_bypath(repo_index, "why")); cl_git_pass(git_index_add_bypath(repo_index, "where")); git_index_write(repo_index); cl_git_rewritefile("stash/where", "....\n"); /* Pre-stash state */ assert_status(repo, "what", GIT_STATUS_WT_MODIFIED); assert_status(repo, "how", GIT_STATUS_CURRENT); assert_status(repo, "who", GIT_STATUS_INDEX_MODIFIED); assert_status(repo, "when", GIT_STATUS_WT_NEW); assert_status(repo, "why", GIT_STATUS_INDEX_NEW); assert_status(repo, "where", GIT_STATUS_INDEX_NEW|GIT_STATUS_WT_MODIFIED); cl_git_pass(git_stash_save(&oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED)); /* Post-stash state */ assert_status(repo, "what", GIT_STATUS_CURRENT); assert_status(repo, "how", GIT_STATUS_CURRENT); assert_status(repo, "who", GIT_STATUS_CURRENT); assert_status(repo, "when", GIT_ENOTFOUND); assert_status(repo, "why", GIT_ENOTFOUND); assert_status(repo, "where", GIT_ENOTFOUND); }
void test_stash_save__skip_submodules(void) { git_repository *untracked_repo; cl_git_pass(git_repository_init(&untracked_repo, "stash/untracked_repo", false)); cl_git_mkfile("stash/untracked_repo/content", "stuff"); git_repository_free(untracked_repo); assert_status(repo, "untracked_repo/", GIT_STATUS_WT_NEW); cl_git_pass(git_stash_save( &stash_tip_oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED)); assert_status(repo, "untracked_repo/", GIT_STATUS_WT_NEW); }
void test_stash_apply__uses_reflog_like_indices_2(void) { git_oid oid; cl_git_mkfile("stash/untracked", "untracked\n"); cl_git_pass(git_stash_save(&oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED)); assert_status(repo, "untracked", GIT_ENOTFOUND); // stash@{0} is the newest stash we made immediately above cl_git_pass(git_stash_apply(repo, 0, NULL)); cl_assert_equal_i(git_index_has_conflicts(repo_index), 0); assert_status(repo, "untracked", GIT_STATUS_WT_NEW); }
void test_stash_save__including_untracked_without_any_untracked_file_creates_an_empty_tree(void) { cl_git_pass(p_unlink("stash/when")); assert_status("what", GIT_STATUS_WT_MODIFIED | GIT_STATUS_INDEX_MODIFIED); assert_status("how", GIT_STATUS_INDEX_MODIFIED); assert_status("who", GIT_STATUS_WT_MODIFIED); assert_status("when", GIT_ENOTFOUND); assert_status("just.ignore", GIT_STATUS_IGNORED); cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED)); assert_object_oid("stash^3^{tree}", EMPTY_TREE, GIT_OBJ_TREE); }
void test_stash_save__cannot_stash_when_there_are_no_local_change(void) { git_index *index; git_oid commit_oid, stash_tip_oid; cl_git_pass(git_repository_index(&index, repo)); /* * 'what' and 'who' are being committed. * 'when' remain untracked. */ cl_git_pass(git_index_add_from_workdir(index, "what")); cl_git_pass(git_index_add_from_workdir(index, "who")); cl_git_pass(git_index_write(index)); commit_staged_files(&commit_oid, index, signature); git_index_free(index); cl_assert_equal_i(GIT_ENOTFOUND, git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT)); p_unlink("stash/when"); cl_assert_equal_i(GIT_ENOTFOUND, git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED)); }
void test_stash_save__stashing_updates_the_reflog(void) { char *sha; assert_object_oid("refs/stash@{0}", NULL, GIT_OBJ_COMMIT); cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT)); sha = git_oid_allocfmt(&stash_tip_oid); assert_object_oid("refs/stash@{0}", sha, GIT_OBJ_COMMIT); assert_object_oid("refs/stash@{1}", NULL, GIT_OBJ_COMMIT); git__free(sha); }
void test_stash_save__ignored_directory(void) { cl_git_pass(p_mkdir("stash/ignored_directory", 0777)); cl_git_pass(p_mkdir("stash/ignored_directory/sub", 0777)); cl_git_mkfile("stash/ignored_directory/sub/some_file", "stuff"); assert_status(repo, "ignored_directory/sub/some_file", GIT_STATUS_WT_NEW); cl_git_pass(git_ignore_add_rule(repo, "ignored_directory/")); assert_status(repo, "ignored_directory/sub/some_file", GIT_STATUS_IGNORED); cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED | GIT_STASH_INCLUDE_IGNORED)); cl_assert(!git_path_exists("stash/ignored_directory/sub/some_file")); cl_assert(!git_path_exists("stash/ignored_directory/sub")); cl_assert(!git_path_exists("stash/ignored_directory")); }
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_stash_apply__uses_reflog_like_indices_1(void) { git_oid oid; cl_git_mkfile("stash/untracked", "untracked\n"); cl_git_pass(git_stash_save(&oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED)); assert_status(repo, "untracked", GIT_ENOTFOUND); // stash@{1} is the oldest (first) stash we made cl_git_pass(git_stash_apply(repo, 1, NULL)); cl_assert_equal_i(git_index_has_conflicts(repo_index), 0); assert_status(repo, "what", GIT_STATUS_WT_MODIFIED); assert_status(repo, "how", GIT_STATUS_CURRENT); assert_status(repo, "who", GIT_STATUS_WT_MODIFIED); assert_status(repo, "when", GIT_STATUS_WT_NEW); assert_status(repo, "why", GIT_STATUS_INDEX_NEW); assert_status(repo, "where", GIT_STATUS_INDEX_NEW); }
void test_stash_save__untracked_skips_ignored(void) { cl_git_append2file("stash/.gitignore", "bundle/vendor/\n"); cl_must_pass(p_mkdir("stash/bundle", 0777)); cl_must_pass(p_mkdir("stash/bundle/vendor", 0777)); cl_git_mkfile("stash/bundle/vendor/blah", "contents\n"); cl_assert(git_path_exists("stash/when")); /* untracked */ cl_assert(git_path_exists("stash/just.ignore")); /* ignored */ cl_assert(git_path_exists("stash/bundle/vendor/blah")); /* ignored */ cl_git_pass(git_stash_save( &stash_tip_oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED)); cl_assert(!git_path_exists("stash/when")); cl_assert(git_path_exists("stash/bundle/vendor/blah")); cl_assert(git_path_exists("stash/just.ignore")); }
void QGit::stashSave(QString name) { git_repository *repo = nullptr; git_reference *head = nullptr; //git_commit *commit = nullptr; git_signature *me = nullptr; //git_index *index = nullptr; git_oid *oid = nullptr; QStringList stashes; int res = 0; QGitError error; try { res = git_repository_open(&repo, m_path.absolutePath().toUtf8().constData()); if (res) { throw QGitError("git_repository_open", res); } res = git_signature_default(&me, repo); if (res) { throw QGitError("git_signature_default", res); } res = git_repository_head(&head, repo); if (res) { throw QGitError("git_repository_head", res); } // TODO: Check if we have memory leak here! oid = const_cast<git_oid *>(git_reference_target(head)); if (!oid) { throw QGitError("git_reference_target returned NULL", 0); } res = git_stash_save(oid, repo, me, name.toUtf8().constData(), 0); if (res) { throw QGitError("git_stash_save", res); } } catch(const QGitError &ex) { error = ex; } emit stashSaveReply(error); if (oid) { // TODO: Check if we need to free memory here! //git_oid_shorten_free(); oid = nullptr; } if (head) { git_reference_delete(head); head = nullptr; } if (me) { git_signature_free(me); me = nullptr; } if (repo) { git_repository_free(repo); repo = nullptr; } }
/** * Stash * * @param repo The repository * @param message Optional description * @param index All changes already added to the index are left * intact in the working directory. Default is FALSE * @param untracked All untracked files are also stashed and then * cleaned up from the working directory. Default is FALSE * @param ignored All ignored files are also stashed and then cleaned * up from the working directory. Default is FALSE * @param stasher Signature with stasher and time of stash * @return S3 class git_stash */ SEXP git2r_stash_save( SEXP repo, SEXP message, SEXP index, SEXP untracked, SEXP ignored, SEXP stasher) { int error, nprotect = 0; SEXP result = R_NilValue, class; git_oid oid; git_stash_flags flags = GIT_STASH_DEFAULT; git_commit *commit = NULL; git_repository *repository = NULL; git_signature *c_stasher = NULL; if (git2r_arg_check_logical(index)) git2r_error(__func__, NULL, "'index'", git2r_err_logical_arg); if (git2r_arg_check_logical(untracked)) git2r_error(__func__, NULL, "'untracked'", git2r_err_logical_arg); if (git2r_arg_check_logical(ignored)) git2r_error(__func__, NULL, "'ignored'", git2r_err_logical_arg); if (git2r_arg_check_signature(stasher)) git2r_error(__func__, NULL, "'stasher'", git2r_err_signature_arg); repository = git2r_repository_open(repo); if (!repository) git2r_error(__func__, NULL, git2r_err_invalid_repository, NULL); if (LOGICAL(index)[0]) flags |= GIT_STASH_KEEP_INDEX; if (LOGICAL(untracked)[0]) flags |= GIT_STASH_INCLUDE_UNTRACKED; if (LOGICAL(ignored)[0]) flags |= GIT_STASH_INCLUDE_IGNORED; error = git2r_signature_from_arg(&c_stasher, stasher); if (error) goto cleanup; error = git_stash_save( &oid, repository, c_stasher, CHAR(STRING_ELT(message, 0)), flags); if (error) { if (GIT_ENOTFOUND == error) error = GIT_OK; goto cleanup; } PROTECT(result = Rf_mkNamed(VECSXP, git2r_S3_items__git_commit)); nprotect++; Rf_setAttrib(result, R_ClassSymbol, class = Rf_allocVector(STRSXP, 2)); SET_STRING_ELT(class, 0, Rf_mkChar("git_stash")); SET_STRING_ELT(class, 1, Rf_mkChar("git_commit")); error = git2r_stash_init(&oid, repository, repo, result); cleanup: git_commit_free(commit); git_signature_free(c_stasher); git_repository_free(repository); if (nprotect) UNPROTECT(nprotect); if (error) git2r_error(__func__, GIT2R_ERROR_LAST(), NULL, NULL); return result; }
void test_stash_save__can_stage_normal_then_stage_untracked(void) { /* * $ git ls-tree stash@{1}^0 * 100644 blob ac4d88de61733173d9959e4b77c69b9f17a00980 .gitignore * 100644 blob e6d64adb2c7f3eb8feb493b556cc8070dca379a3 how * 100644 blob bc99dc98b3eba0e9157e94769cd4d49cb49de449 what * 100644 blob a0400d4954659306a976567af43125a0b1aa8595 who * * $ git ls-tree stash@{1}^1 * 100644 blob ac4d88de61733173d9959e4b77c69b9f17a00980 .gitignore * 100644 blob ac790413e2d7a26c3767e78c57bb28716686eebc how * 100644 blob ce013625030ba8dba906f756967f9e9ca394464a what * 100644 blob cc628ccd10742baea8241c5924df992b5c019f71 who * * $ git ls-tree stash@{1}^2 * 100644 blob ac4d88de61733173d9959e4b77c69b9f17a00980 .gitignore * 100644 blob e6d64adb2c7f3eb8feb493b556cc8070dca379a3 how * 100644 blob dd7e1c6f0fefe118f0b63d9f10908c460aa317a6 what * 100644 blob cc628ccd10742baea8241c5924df992b5c019f71 who * * $ git ls-tree stash@{1}^3 * fatal: Not a valid object name stash@{1}^3 * * $ git ls-tree stash@{0}^0 * 100644 blob ac4d88de61733173d9959e4b77c69b9f17a00980 .gitignore * 100644 blob ac790413e2d7a26c3767e78c57bb28716686eebc how * 100644 blob ce013625030ba8dba906f756967f9e9ca394464a what * 100644 blob cc628ccd10742baea8241c5924df992b5c019f71 who * * $ git ls-tree stash@{0}^1 * 100644 blob ac4d88de61733173d9959e4b77c69b9f17a00980 .gitignore * 100644 blob ac790413e2d7a26c3767e78c57bb28716686eebc how * 100644 blob ce013625030ba8dba906f756967f9e9ca394464a what * 100644 blob cc628ccd10742baea8241c5924df992b5c019f71 who * * $ git ls-tree stash@{0}^2 * 100644 blob ac4d88de61733173d9959e4b77c69b9f17a00980 .gitignore * 100644 blob ac790413e2d7a26c3767e78c57bb28716686eebc how * 100644 blob ce013625030ba8dba906f756967f9e9ca394464a what * 100644 blob cc628ccd10742baea8241c5924df992b5c019f71 who * * $ git ls-tree stash@{0}^3 * 100644 blob b6ed15e81e2593d7bb6265eb4a991d29dc3e628b when */ assert_status("what", GIT_STATUS_WT_MODIFIED | GIT_STATUS_INDEX_MODIFIED); assert_status("how", GIT_STATUS_INDEX_MODIFIED); assert_status("who", GIT_STATUS_WT_MODIFIED); assert_status("when", GIT_STATUS_WT_NEW); assert_status("just.ignore", GIT_STATUS_IGNORED); cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT)); assert_status("what", GIT_STATUS_CURRENT); assert_status("how", GIT_STATUS_CURRENT); assert_status("who", GIT_STATUS_CURRENT); assert_status("when", GIT_STATUS_WT_NEW); assert_status("just.ignore", GIT_STATUS_IGNORED); cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED)); assert_status("what", GIT_STATUS_CURRENT); assert_status("how", GIT_STATUS_CURRENT); assert_status("who", GIT_STATUS_CURRENT); assert_status("when", GIT_ENOTFOUND); assert_status("just.ignore", GIT_STATUS_IGNORED); assert_blob_oid("stash@{1}^0:what", "bc99dc98b3eba0e9157e94769cd4d49cb49de449"); /* see you later */ assert_blob_oid("stash@{1}^0:how", "e6d64adb2c7f3eb8feb493b556cc8070dca379a3"); /* not so small and */ assert_blob_oid("stash@{1}^0:who", "a0400d4954659306a976567af43125a0b1aa8595"); /* funky world */ assert_blob_oid("stash@{1}^0:when", NULL); assert_blob_oid("stash@{1}^2:what", "dd7e1c6f0fefe118f0b63d9f10908c460aa317a6"); /* goodbye */ assert_blob_oid("stash@{1}^2:how", "e6d64adb2c7f3eb8feb493b556cc8070dca379a3"); /* not so small and */ assert_blob_oid("stash@{1}^2:who", "cc628ccd10742baea8241c5924df992b5c019f71"); /* world */ assert_blob_oid("stash@{1}^2:when", NULL); assert_object_oid("stash@{1}^3", NULL, GIT_OBJ_COMMIT); assert_blob_oid("stash@{0}^0:what", "ce013625030ba8dba906f756967f9e9ca394464a"); /* hello */ assert_blob_oid("stash@{0}^0:how", "ac790413e2d7a26c3767e78c57bb28716686eebc"); /* small */ assert_blob_oid("stash@{0}^0:who", "cc628ccd10742baea8241c5924df992b5c019f71"); /* world */ assert_blob_oid("stash@{0}^0:when", NULL); assert_blob_oid("stash@{0}^2:what", "ce013625030ba8dba906f756967f9e9ca394464a"); /* hello */ assert_blob_oid("stash@{0}^2:how", "ac790413e2d7a26c3767e78c57bb28716686eebc"); /* small */ assert_blob_oid("stash@{0}^2:who", "cc628ccd10742baea8241c5924df992b5c019f71"); /* world */ assert_blob_oid("stash@{0}^2:when", NULL); assert_blob_oid("stash@{0}^3:when", "b6ed15e81e2593d7bb6265eb4a991d29dc3e628b"); /* now */ }