Initial commit

This commit is contained in:
jiapengyu
2026-07-27 13:37:48 +08:00
commit ecba71e2a5
39123 changed files with 5989154 additions and 0 deletions
+449
View File
@@ -0,0 +1,449 @@
#include "clar_libgit2.h"
#include "futils.h"
#include "stash_helpers.h"
static git_signature *signature;
static git_repository *repo;
static git_index *repo_index;
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", "emeric.fermas@gmail.com", 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"));
cl_git_pass(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_apply__cleanup(void)
{
git_signature_free(signature);
signature = NULL;
git_index_free(repo_index);
repo_index = NULL;
cl_git_sandbox_cleanup();
}
void test_stash_apply__with_default(void)
{
git_buf where = GIT_BUF_INIT;
cl_git_pass(git_stash_apply(repo, 0, 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);
cl_git_pass(git_futils_readbuffer(&where, "stash/where"));
cl_assert_equal_s("....\n", where.ptr);
git_buf_dispose(&where);
}
void test_stash_apply__with_existing_file(void)
{
cl_git_mkfile("stash/where", "oops!\n");
cl_git_fail(git_stash_apply(repo, 0, NULL));
}
void test_stash_apply__merges_new_file(void)
{
const git_index_entry *ancestor, *our, *their;
cl_git_mkfile("stash/where", "committed before stash\n");
cl_git_pass(git_index_add_bypath(repo_index, "where"));
cl_repo_commit_from_index(NULL, repo, signature, 0, "Other commit");
cl_git_pass(git_stash_apply(repo, 0, NULL));
cl_assert_equal_i(1, git_index_has_conflicts(repo_index));
assert_status(repo, "what", GIT_STATUS_INDEX_MODIFIED);
cl_git_pass(git_index_conflict_get(&ancestor, &our, &their, repo_index, "where")); /* unmerged */
assert_status(repo, "who", GIT_STATUS_INDEX_MODIFIED);
assert_status(repo, "when", GIT_STATUS_WT_NEW);
assert_status(repo, "why", GIT_STATUS_INDEX_NEW);
}
void test_stash_apply__with_reinstate_index(void)
{
git_buf where = GIT_BUF_INIT;
git_stash_apply_options opts = GIT_STASH_APPLY_OPTIONS_INIT;
opts.flags = GIT_STASH_APPLY_REINSTATE_INDEX;
cl_git_pass(git_stash_apply(repo, 0, &opts));
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_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_futils_readbuffer(&where, "stash/where"));
cl_assert_equal_s("....\n", where.ptr);
git_buf_dispose(&where);
}
void test_stash_apply__conflict_index_with_default(void)
{
const git_index_entry *ancestor;
const git_index_entry *our;
const git_index_entry *their;
cl_git_rewritefile("stash/who", "nothing\n");
cl_git_pass(git_index_add_bypath(repo_index, "who"));
cl_git_pass(git_index_write(repo_index));
cl_repo_commit_from_index(NULL, repo, signature, 0, "Other commit");
cl_git_pass(git_stash_apply(repo, 0, NULL));
cl_assert_equal_i(git_index_has_conflicts(repo_index), 1);
assert_status(repo, "what", GIT_STATUS_INDEX_MODIFIED);
assert_status(repo, "how", GIT_STATUS_CURRENT);
cl_git_pass(git_index_conflict_get(&ancestor, &our, &their, repo_index, "who")); /* unmerged */
assert_status(repo, "when", GIT_STATUS_WT_NEW);
assert_status(repo, "why", GIT_STATUS_INDEX_NEW);
}
void test_stash_apply__conflict_index_with_reinstate_index(void)
{
git_stash_apply_options opts = GIT_STASH_APPLY_OPTIONS_INIT;
opts.flags = GIT_STASH_APPLY_REINSTATE_INDEX;
cl_git_rewritefile("stash/who", "nothing\n");
cl_git_pass(git_index_add_bypath(repo_index, "who"));
cl_git_pass(git_index_write(repo_index));
cl_repo_commit_from_index(NULL, repo, signature, 0, "Other commit");
cl_git_fail_with(git_stash_apply(repo, 0, &opts), GIT_ECONFLICT);
cl_assert_equal_i(git_index_has_conflicts(repo_index), 0);
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);
}
void test_stash_apply__conflict_untracked_with_default(void)
{
git_stash_apply_options opts = GIT_STASH_APPLY_OPTIONS_INIT;
cl_git_mkfile("stash/when", "nothing\n");
cl_git_fail_with(git_stash_apply(repo, 0, &opts), GIT_ECONFLICT);
cl_assert_equal_i(git_index_has_conflicts(repo_index), 0);
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_STATUS_WT_NEW);
assert_status(repo, "why", GIT_ENOTFOUND);
}
void test_stash_apply__conflict_untracked_with_reinstate_index(void)
{
git_stash_apply_options opts = GIT_STASH_APPLY_OPTIONS_INIT;
opts.flags = GIT_STASH_APPLY_REINSTATE_INDEX;
cl_git_mkfile("stash/when", "nothing\n");
cl_git_fail_with(git_stash_apply(repo, 0, &opts), GIT_ECONFLICT);
cl_assert_equal_i(git_index_has_conflicts(repo_index), 0);
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_STATUS_WT_NEW);
assert_status(repo, "why", GIT_ENOTFOUND);
}
void test_stash_apply__conflict_workdir_with_default(void)
{
cl_git_rewritefile("stash/what", "ciao\n");
cl_git_fail_with(git_stash_apply(repo, 0, NULL), GIT_ECONFLICT);
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_CURRENT);
assert_status(repo, "when", GIT_STATUS_WT_NEW);
assert_status(repo, "why", GIT_ENOTFOUND);
}
void test_stash_apply__conflict_workdir_with_reinstate_index(void)
{
git_stash_apply_options opts = GIT_STASH_APPLY_OPTIONS_INIT;
opts.flags = GIT_STASH_APPLY_REINSTATE_INDEX;
cl_git_rewritefile("stash/what", "ciao\n");
cl_git_fail_with(git_stash_apply(repo, 0, &opts), GIT_ECONFLICT);
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_CURRENT);
assert_status(repo, "when", GIT_STATUS_WT_NEW);
assert_status(repo, "why", GIT_ENOTFOUND);
}
void test_stash_apply__conflict_commit_with_default(void)
{
const git_index_entry *ancestor;
const git_index_entry *our;
const git_index_entry *their;
cl_git_rewritefile("stash/what", "ciao\n");
cl_git_pass(git_index_add_bypath(repo_index, "what"));
cl_repo_commit_from_index(NULL, repo, signature, 0, "Other commit");
cl_git_pass(git_stash_apply(repo, 0, NULL));
cl_assert_equal_i(git_index_has_conflicts(repo_index), 1);
cl_git_pass(git_index_conflict_get(&ancestor, &our, &their, repo_index, "what")); /* unmerged */
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);
}
void test_stash_apply__conflict_commit_with_reinstate_index(void)
{
git_stash_apply_options opts = GIT_STASH_APPLY_OPTIONS_INIT;
const git_index_entry *ancestor;
const git_index_entry *our;
const git_index_entry *their;
opts.flags = GIT_STASH_APPLY_REINSTATE_INDEX;
cl_git_rewritefile("stash/what", "ciao\n");
cl_git_pass(git_index_add_bypath(repo_index, "what"));
cl_repo_commit_from_index(NULL, repo, signature, 0, "Other commit");
cl_git_pass(git_stash_apply(repo, 0, &opts));
cl_assert_equal_i(git_index_has_conflicts(repo_index), 1);
cl_git_pass(git_index_conflict_get(&ancestor, &our, &their, repo_index, "what")); /* unmerged */
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);
}
void test_stash_apply__fails_with_uncommitted_changes_in_index(void)
{
cl_git_rewritefile("stash/who", "nothing\n");
cl_git_pass(git_index_add_bypath(repo_index, "who"));
cl_git_pass(git_index_write(repo_index));
cl_git_fail_with(git_stash_apply(repo, 0, NULL), GIT_EUNCOMMITTED);
cl_assert_equal_i(git_index_has_conflicts(repo_index), 0);
assert_status(repo, "what", GIT_STATUS_CURRENT);
assert_status(repo, "how", GIT_STATUS_CURRENT);
assert_status(repo, "who", GIT_STATUS_INDEX_MODIFIED);
assert_status(repo, "when", GIT_ENOTFOUND);
assert_status(repo, "why", GIT_ENOTFOUND);
}
void test_stash_apply__pop(void)
{
cl_git_pass(git_stash_pop(repo, 0, NULL));
cl_git_fail_with(git_stash_pop(repo, 0, NULL), GIT_ENOTFOUND);
}
struct seen_paths {
bool what;
bool how;
bool who;
bool when;
};
int checkout_notify(
git_checkout_notify_t why,
const char *path,
const git_diff_file *baseline,
const git_diff_file *target,
const git_diff_file *workdir,
void *payload)
{
struct seen_paths *seen_paths = (struct seen_paths *)payload;
GIT_UNUSED(why);
GIT_UNUSED(baseline);
GIT_UNUSED(target);
GIT_UNUSED(workdir);
if (strcmp(path, "what") == 0)
seen_paths->what = 1;
else if (strcmp(path, "how") == 0)
seen_paths->how = 1;
else if (strcmp(path, "who") == 0)
seen_paths->who = 1;
else if (strcmp(path, "when") == 0)
seen_paths->when = 1;
return 0;
}
void test_stash_apply__executes_notify_cb(void)
{
git_stash_apply_options opts = GIT_STASH_APPLY_OPTIONS_INIT;
struct seen_paths seen_paths = {0};
opts.checkout_options.notify_cb = checkout_notify;
opts.checkout_options.notify_flags = GIT_CHECKOUT_NOTIFY_ALL;
opts.checkout_options.notify_payload = &seen_paths;
cl_git_pass(git_stash_apply(repo, 0, &opts));
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);
cl_assert_equal_b(true, seen_paths.what);
cl_assert_equal_b(false, seen_paths.how);
cl_assert_equal_b(true, seen_paths.who);
cl_assert_equal_b(true, seen_paths.when);
}
int progress_cb(
git_stash_apply_progress_t progress,
void *payload)
{
git_stash_apply_progress_t *p = (git_stash_apply_progress_t *)payload;
cl_assert_equal_i((*p)+1, progress);
*p = progress;
return 0;
}
void test_stash_apply__calls_progress_cb(void)
{
git_stash_apply_options opts = GIT_STASH_APPLY_OPTIONS_INIT;
git_stash_apply_progress_t progress = GIT_STASH_APPLY_PROGRESS_NONE;
opts.progress_cb = progress_cb;
opts.progress_payload = &progress;
cl_git_pass(git_stash_apply(repo, 0, &opts));
cl_assert_equal_i(progress, GIT_STASH_APPLY_PROGRESS_DONE);
}
int aborting_progress_cb(
git_stash_apply_progress_t progress,
void *payload)
{
GIT_UNUSED(payload);
if (progress == GIT_STASH_APPLY_PROGRESS_ANALYZE_MODIFIED)
return -44;
return 0;
}
void test_stash_apply__progress_cb_can_abort(void)
{
git_stash_apply_options opts = GIT_STASH_APPLY_OPTIONS_INIT;
opts.progress_cb = aborting_progress_cb;
cl_git_fail_with(-44, git_stash_apply(repo, 0, &opts));
}
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_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);
}
+174
View File
@@ -0,0 +1,174 @@
#include "clar_libgit2.h"
#include "futils.h"
#include "stash_helpers.h"
#include "refs.h"
static git_repository *repo;
static git_signature *signature;
void test_stash_drop__initialize(void)
{
cl_git_pass(git_repository_init(&repo, "stash", 0));
cl_git_pass(git_signature_new(&signature, "nulltoken", "emeric.fermas@gmail.com", 1323847743, 60)); /* Wed Dec 14 08:29:03 2011 +0100 */
}
void test_stash_drop__cleanup(void)
{
git_signature_free(signature);
signature = NULL;
git_repository_free(repo);
repo = NULL;
cl_git_pass(git_futils_rmdir_r("stash", NULL, GIT_RMDIR_REMOVE_FILES));
}
void test_stash_drop__cannot_drop_from_an_empty_stash(void)
{
cl_git_fail_with(git_stash_drop(repo, 0), GIT_ENOTFOUND);
}
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"));
cl_repo_commit_from_index(NULL, repo, signature, 0, "Initial commit");
cl_assert(git_path_exists("stash/zero.txt"));
git_index_free(index);
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"));
}
void test_stash_drop__cannot_drop_a_non_existing_stashed_state(void)
{
push_three_states();
cl_git_fail_with(git_stash_drop(repo, 666), GIT_ENOTFOUND);
cl_git_fail_with(git_stash_drop(repo, 42), GIT_ENOTFOUND);
cl_git_fail_with(git_stash_drop(repo, 3), GIT_ENOTFOUND);
}
void test_stash_drop__can_purge_the_stash_from_the_top(void)
{
push_three_states();
cl_git_pass(git_stash_drop(repo, 0));
cl_git_pass(git_stash_drop(repo, 0));
cl_git_pass(git_stash_drop(repo, 0));
cl_git_fail_with(git_stash_drop(repo, 0), GIT_ENOTFOUND);
}
void test_stash_drop__can_purge_the_stash_from_the_bottom(void)
{
push_three_states();
cl_git_pass(git_stash_drop(repo, 2));
cl_git_pass(git_stash_drop(repo, 1));
cl_git_pass(git_stash_drop(repo, 0));
cl_git_fail_with(git_stash_drop(repo, 0), GIT_ENOTFOUND);
}
void test_stash_drop__dropping_an_entry_rewrites_reflog_history(void)
{
git_reference *stash;
git_reflog *reflog;
const git_reflog_entry *entry;
git_oid oid;
size_t count;
push_three_states();
cl_git_pass(git_reference_lookup(&stash, repo, GIT_REFS_STASH_FILE));
cl_git_pass(git_reflog_read(&reflog, repo, GIT_REFS_STASH_FILE));
entry = git_reflog_entry_byindex(reflog, 1);
git_oid_cpy(&oid, git_reflog_entry_id_old(entry));
count = git_reflog_entrycount(reflog);
git_reflog_free(reflog);
cl_git_pass(git_stash_drop(repo, 1));
cl_git_pass(git_reflog_read(&reflog, repo, GIT_REFS_STASH_FILE));
entry = git_reflog_entry_byindex(reflog, 0);
cl_assert_equal_oid(&oid, git_reflog_entry_id_old(entry));
cl_assert_equal_sz(count - 1, git_reflog_entrycount(reflog));
git_reflog_free(reflog);
git_reference_free(stash);
}
void test_stash_drop__dropping_the_last_entry_removes_the_stash(void)
{
git_reference *stash;
push_three_states();
cl_git_pass(git_reference_lookup(&stash, repo, GIT_REFS_STASH_FILE));
git_reference_free(stash);
cl_git_pass(git_stash_drop(repo, 0));
cl_git_pass(git_stash_drop(repo, 0));
cl_git_pass(git_stash_drop(repo, 0));
cl_git_fail_with(
git_reference_lookup(&stash, repo, GIT_REFS_STASH_FILE), GIT_ENOTFOUND);
}
void retrieve_top_stash_id(git_oid *out)
{
git_object *top_stash;
cl_git_pass(git_revparse_single(&top_stash, repo, "stash@{0}"));
cl_git_pass(git_reference_name_to_id(out, repo, GIT_REFS_STASH_FILE));
cl_assert_equal_oid(out, git_object_id(top_stash));
git_object_free(top_stash);
}
void test_stash_drop__dropping_the_top_stash_updates_the_stash_reference(void)
{
git_object *next_top_stash;
git_oid oid;
push_three_states();
retrieve_top_stash_id(&oid);
cl_git_pass(git_revparse_single(&next_top_stash, repo, "stash@{1}"));
cl_assert(git_oid_cmp(&oid, git_object_id(next_top_stash)));
cl_git_pass(git_stash_drop(repo, 0));
retrieve_top_stash_id(&oid);
cl_assert_equal_oid(&oid, git_object_id(next_top_stash));
git_object_free(next_top_stash);
}
+126
View File
@@ -0,0 +1,126 @@
#include "clar_libgit2.h"
#include "futils.h"
#include "stash_helpers.h"
struct callback_data
{
char **oids;
int invokes;
};
static git_repository *repo;
static git_signature *signature;
static git_oid stash_tip_oid;
struct callback_data data;
#define REPO_NAME "stash"
void test_stash_foreach__initialize(void)
{
cl_git_pass(git_signature_new(
&signature,
"nulltoken",
"emeric.fermas@gmail.com",
1323847743, 60)); /* Wed Dec 14 08:29:03 2011 +0100 */
memset(&data, 0, sizeof(struct callback_data));
}
void test_stash_foreach__cleanup(void)
{
git_signature_free(signature);
signature = NULL;
git_repository_free(repo);
repo = NULL;
cl_git_pass(git_futils_rmdir_r(REPO_NAME, NULL, GIT_RMDIR_REMOVE_FILES));
}
static int callback_cb(
size_t index,
const char* message,
const git_oid *stash_oid,
void *payload)
{
struct callback_data *data = (struct callback_data *)payload;
GIT_UNUSED(index);
GIT_UNUSED(message);
cl_assert_equal_i(0, git_oid_streq(stash_oid, data->oids[data->invokes++]));
return 0;
}
void test_stash_foreach__enumerating_a_empty_repository_doesnt_fail(void)
{
char *oids[] = { NULL };
data.oids = oids;
cl_git_pass(git_repository_init(&repo, REPO_NAME, 0));
cl_git_pass(git_stash_foreach(repo, callback_cb, &data));
cl_assert_equal_i(0, data.invokes);
}
void test_stash_foreach__can_enumerate_a_repository(void)
{
char *oids_default[] = {
"493568b7a2681187aaac8a58d3f1eab1527cba84", NULL };
char *oids_untracked[] = {
"7f89a8b15c878809c5c54d1ff8f8c9674154017b",
"493568b7a2681187aaac8a58d3f1eab1527cba84", NULL };
char *oids_ignored[] = {
"c95599a8fef20a7e57582c6727b1a0d02e0a5828",
"7f89a8b15c878809c5c54d1ff8f8c9674154017b",
"493568b7a2681187aaac8a58d3f1eab1527cba84", 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);
/* ensure stash_foreach operates with INCLUDE_UNTRACKED */
cl_git_pass(git_stash_save(
&stash_tip_oid,
repo,
signature,
NULL,
GIT_STASH_INCLUDE_UNTRACKED));
data.oids = oids_untracked;
data.invokes = 0;
cl_git_pass(git_stash_foreach(repo, callback_cb, &data));
cl_assert_equal_i(2, data.invokes);
/* ensure stash_foreach operates with INCLUDE_IGNORED */
cl_git_pass(git_stash_save(
&stash_tip_oid,
repo,
signature,
NULL,
GIT_STASH_INCLUDE_IGNORED));
data.oids = oids_ignored;
data.invokes = 0;
cl_git_pass(git_stash_foreach(repo, callback_cb, &data));
cl_assert_equal_i(3, data.invokes);
}
+490
View File
@@ -0,0 +1,490 @@
#include "clar_libgit2.h"
#include "futils.h"
#include "stash_helpers.h"
static git_repository *repo;
static git_signature *signature;
static git_oid stash_tip_oid;
/*
* Friendly reminder, in order to ease the reading of the following tests:
*
* "stash" points to the worktree commit
* "stash^1" points to the base commit (HEAD when the stash was created)
* "stash^2" points to the index commit
* "stash^3" points to the untracked commit
*/
void test_stash_save__initialize(void)
{
cl_git_pass(git_repository_init(&repo, "stash", 0));
cl_git_pass(git_signature_new(&signature, "nulltoken", "emeric.fermas@gmail.com", 1323847743, 60)); /* Wed Dec 14 08:29:03 2011 +0100 */
setup_stash(repo, signature);
}
void test_stash_save__cleanup(void)
{
git_signature_free(signature);
signature = NULL;
git_repository_free(repo);
repo = NULL;
cl_git_pass(git_futils_rmdir_r("stash", NULL, GIT_RMDIR_REMOVE_FILES));
cl_fixture_cleanup("sorry-it-is-a-non-bare-only-party");
}
static void assert_object_oid(const char* revision, const char* expected_oid, git_object_t type)
{
int result;
git_object *obj;
result = git_revparse_single(&obj, repo, revision);
if (!expected_oid) {
cl_assert_equal_i(GIT_ENOTFOUND, result);
return;
} else
cl_assert_equal_i(0, result);
cl_git_pass(git_oid_streq(git_object_id(obj), expected_oid));
cl_assert_equal_i(type, git_object_type(obj));
git_object_free(obj);
}
static void assert_blob_oid(const char* revision, const char* expected_oid)
{
assert_object_oid(revision, expected_oid, GIT_OBJECT_BLOB);
}
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_keep_index(void)
{
cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_KEEP_INDEX));
assert_status(repo, "what", GIT_STATUS_INDEX_MODIFIED);
assert_status(repo, "how", GIT_STATUS_INDEX_MODIFIED);
assert_status(repo, "who", GIT_STATUS_CURRENT);
assert_status(repo, "when", GIT_STATUS_WT_NEW);
assert_status(repo, "just.ignore", GIT_STATUS_IGNORED);
}
static void assert_commit_message_contains(const char *revision, const char *fragment)
{
git_commit *commit;
cl_git_pass(git_revparse_single((git_object**)&commit, repo, revision));
cl_assert(strstr(git_commit_message(commit), fragment) != NULL);
git_commit_free(commit);
}
void test_stash_save__can_include_untracked_files(void)
{
cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED));
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", NULL);
}
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 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");
cl_assert(!git_path_exists("stash/just.ignore"));
}
/*
* 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_OBJECT_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);
}
#define MESSAGE "Look Ma! I'm on TV!"
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__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__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_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_OBJECT_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_OBJECT_COMMIT);
assert_object_oid("refs/stash@{1}", NULL, GIT_OBJECT_COMMIT);
}
void test_stash_save__multiline_message(void)
{
const char *msg = "This\n\nis a multiline message\n";
const git_reflog_entry *entry;
git_reflog *reflog;
assert_object_oid("refs/stash@{0}", NULL, GIT_OBJECT_COMMIT);
cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, msg, GIT_STASH_DEFAULT));
cl_git_pass(git_reflog_read(&reflog, repo, "refs/stash"));
cl_assert(entry = git_reflog_entry_byindex(reflog, 0));
cl_assert_equal_s(git_reflog_entry_message(entry), "On master: This is a multiline message");
assert_object_oid("refs/stash@{0}", git_oid_tostr_s(&stash_tip_oid), GIT_OBJECT_COMMIT);
assert_commit_message_contains("refs/stash@{0}", msg);
git_reflog_free(reflog);
}
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));
}
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(repo, "what", GIT_STATUS_WT_MODIFIED | GIT_STATUS_INDEX_MODIFIED);
assert_status(repo, "how", GIT_STATUS_INDEX_MODIFIED);
assert_status(repo, "who", GIT_STATUS_WT_MODIFIED);
assert_status(repo, "when", GIT_STATUS_WT_NEW);
assert_status(repo, "just.ignore", GIT_STATUS_IGNORED);
cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT));
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_STATUS_WT_NEW);
assert_status(repo, "just.ignore", GIT_STATUS_IGNORED);
cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED));
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, "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_OBJECT_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 */
}
#define EMPTY_TREE "4b825dc642cb6eb9a060e54bf8d69288fbee4904"
void test_stash_save__including_untracked_without_any_untracked_file_creates_an_empty_tree(void)
{
cl_must_pass(p_unlink("stash/when"));
assert_status(repo, "what", GIT_STATUS_WT_MODIFIED | GIT_STATUS_INDEX_MODIFIED);
assert_status(repo, "how", GIT_STATUS_INDEX_MODIFIED);
assert_status(repo, "who", GIT_STATUS_WT_MODIFIED);
assert_status(repo, "when", GIT_ENOTFOUND);
assert_status(repo, "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_OBJECT_TREE);
}
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__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_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);
}
+57
View File
@@ -0,0 +1,57 @@
#include "clar_libgit2.h"
#include "futils.h"
#include "stash_helpers.h"
void setup_stash(git_repository *repo, git_signature *signature)
{
git_index *index;
cl_git_pass(git_repository_index(&index, repo));
cl_git_mkfile("stash/what", "hello\n"); /* ce013625030ba8dba906f756967f9e9ca394464a */
cl_git_mkfile("stash/how", "small\n"); /* ac790413e2d7a26c3767e78c57bb28716686eebc */
cl_git_mkfile("stash/who", "world\n"); /* cc628ccd10742baea8241c5924df992b5c019f71 */
cl_git_mkfile("stash/when", "now\n"); /* b6ed15e81e2593d7bb6265eb4a991d29dc3e628b */
cl_git_mkfile("stash/just.ignore", "me\n"); /* 78925fb1236b98b37a35e9723033e627f97aa88b */
cl_git_mkfile("stash/.gitignore", "*.ignore\n");
cl_git_pass(git_index_add_bypath(index, "what"));
cl_git_pass(git_index_add_bypath(index, "how"));
cl_git_pass(git_index_add_bypath(index, "who"));
cl_git_pass(git_index_add_bypath(index, ".gitignore"));
cl_repo_commit_from_index(NULL, repo, signature, 0, "Initial commit");
cl_git_rewritefile("stash/what", "goodbye\n"); /* dd7e1c6f0fefe118f0b63d9f10908c460aa317a6 */
cl_git_rewritefile("stash/how", "not so small and\n"); /* e6d64adb2c7f3eb8feb493b556cc8070dca379a3 */
cl_git_rewritefile("stash/who", "funky world\n"); /* a0400d4954659306a976567af43125a0b1aa8595 */
cl_git_mkfile("stash/why", "would anybody use stash?\n"); /* 88c2533e21f098b89c91a431d8075cbde422a51 */
cl_git_mkfile("stash/where", "????\n"); /* e08f7fbb9a42a0c5367cf8b349f1f08c3d56bd72 */
cl_git_pass(git_index_add_bypath(index, "what"));
cl_git_pass(git_index_add_bypath(index, "how"));
cl_git_pass(git_index_add_bypath(index, "why"));
cl_git_pass(git_index_add_bypath(index, "where"));
cl_git_pass(git_index_write(index));
cl_git_rewritefile("stash/what", "see you later\n"); /* bc99dc98b3eba0e9157e94769cd4d49cb49de449 */
cl_git_mkfile("stash/where", "....\n"); /* e3d6434ec12eb76af8dfa843a64ba6ab91014a0b */
git_index_free(index);
}
void assert_status(
git_repository *repo,
const char *path,
int status_flags)
{
unsigned int status;
if (status_flags < 0)
cl_assert_equal_i(status_flags, git_status_file(&status, repo, path));
else {
cl_git_pass(git_status_file(&status, repo, path));
cl_assert_equal_i((unsigned int)status_flags, status);
}
}
+8
View File
@@ -0,0 +1,8 @@
void setup_stash(
git_repository *repo,
git_signature *signature);
void assert_status(
git_repository *repo,
const char *path,
int status_flags);
+83
View File
@@ -0,0 +1,83 @@
#include "clar_libgit2.h"
#include "stash_helpers.h"
#include "../submodule/submodule_helpers.h"
static git_repository *repo;
static git_signature *signature;
static git_oid stash_tip_oid;
static git_submodule *sm;
void test_stash_submodules__initialize(void)
{
cl_git_pass(git_signature_new(&signature, "nulltoken", "emeric.fermas@gmail.com", 1323847743, 60)); /* Wed Dec 14 08:29:03 2011 +0100 */
repo = setup_fixture_submodules();
cl_git_pass(git_submodule_lookup(&sm, repo, "testrepo"));
}
void test_stash_submodules__cleanup(void)
{
git_submodule_free(sm);
sm = NULL;
git_signature_free(signature);
signature = NULL;
}
void test_stash_submodules__does_not_stash_modified_submodules(void)
{
static git_index *smindex;
static git_repository *smrepo;
assert_status(repo, "modified", GIT_STATUS_WT_MODIFIED);
/* modify file in submodule */
cl_git_rewritefile("submodules/testrepo/README", "heyheyhey");
assert_status(repo, "testrepo", GIT_STATUS_WT_MODIFIED);
/* add file to index in submodule */
cl_git_pass(git_submodule_open(&smrepo, sm));
cl_git_pass(git_repository_index(&smindex, smrepo));
cl_git_pass(git_index_add_bypath(smindex, "README"));
/* commit changed index of submodule */
cl_repo_commit_from_index(NULL, smrepo, NULL, 1372350000, "Modify it");
assert_status(repo, "testrepo", GIT_STATUS_WT_MODIFIED);
cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT));
assert_status(repo, "testrepo", GIT_STATUS_WT_MODIFIED);
assert_status(repo, "modified", GIT_STATUS_CURRENT);
git_index_free(smindex);
git_repository_free(smrepo);
}
void test_stash_submodules__stash_is_empty_with_modified_submodules(void)
{
static git_index *smindex;
static git_repository *smrepo;
cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT));
assert_status(repo, "modified", GIT_STATUS_CURRENT);
/* modify file in submodule */
cl_git_rewritefile("submodules/testrepo/README", "heyheyhey");
assert_status(repo, "testrepo", GIT_STATUS_WT_MODIFIED);
/* add file to index in submodule */
cl_git_pass(git_submodule_open(&smrepo, sm));
cl_git_pass(git_repository_index(&smindex, smrepo));
cl_git_pass(git_index_add_bypath(smindex, "README"));
/* commit changed index of submodule */
cl_repo_commit_from_index(NULL, smrepo, NULL, 1372350000, "Modify it");
assert_status(repo, "testrepo", GIT_STATUS_WT_MODIFIED);
cl_git_fail_with(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT), GIT_ENOTFOUND);
git_index_free(smindex);
git_repository_free(smrepo);
}