int git_reader_for_workdir( git_reader **out, git_repository *repo, bool validate_index) { workdir_reader *reader; int error; assert(out && repo); reader = git__calloc(1, sizeof(workdir_reader)); GITERR_CHECK_ALLOC(reader); reader->reader.read = workdir_reader_read; reader->repo = repo; if (validate_index && (error = git_repository_index__weakptr(&reader->index, repo)) < 0) { git__free(reader); return error; } *out = (git_reader *)reader; return 0; }
int git_reader_for_index( git_reader **out, git_repository *repo, git_index *index) { index_reader *reader; int error; assert(out && repo); reader = git__calloc(1, sizeof(index_reader)); GITERR_CHECK_ALLOC(reader); reader->reader.read = index_reader_read; reader->repo = repo; if (index) { reader->index = index; } else if ((error = git_repository_index__weakptr(&reader->index, repo)) < 0) { git__free(reader); return error; } *out = (git_reader *)reader; return 0; }
static int iterator__update_ignore_case( git_iterator *iter, git_iterator_flag_t flags) { int error = 0, ignore_case = -1; if ((flags & GIT_ITERATOR_IGNORE_CASE) != 0) ignore_case = true; else if ((flags & GIT_ITERATOR_DONT_IGNORE_CASE) != 0) ignore_case = false; else { git_index *index; if (!(error = git_repository_index__weakptr(&index, iter->repo))) ignore_case = (index->ignore_case != false); } if (ignore_case > 0) iter->flags = (iter->flags | GIT_ITERATOR_IGNORE_CASE); else if (ignore_case == 0) iter->flags = (iter->flags & ~GIT_ITERATOR_IGNORE_CASE); iter->prefixcomp = iterator__ignore_case(iter) ? git__prefixcmp_icase : git__prefixcmp; return error; }
static void setup_race(void) { git_buf path = GIT_BUF_INIT; git_index *index; git_index_entry *entry; struct stat st; /* Make sure we do have a timestamp */ cl_git_pass(git_repository_index__weakptr(&index, g_repo)); cl_git_pass(git_index_write(index)); cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), "A")); cl_git_mkfile(path.ptr, "A"); cl_git_pass(git_index_add_bypath(index, "A")); cl_git_mkfile(path.ptr, "B"); cl_git_pass(git_index_write(index)); cl_git_mkfile(path.ptr, ""); cl_git_pass(p_stat(path.ptr, &st)); cl_assert(entry = (git_index_entry *)git_index_get_bypath(index, "A", 0)); /* force a race */ entry->mtime.seconds = (int32_t)st.st_mtime; entry->mtime.nanoseconds = (int32_t)st.st_mtime_nsec; git_buf_dispose(&path); }
static void commit_and_tag( git_time_t *time, const char *commit_msg, const char *tag_name) { git_index *index; git_oid commit_id; git_reference *ref; cl_git_pass(git_repository_index__weakptr(&index, repo)); cl_git_append2file("describe/file", "\n"); cl_git_pass(git_index_add_bypath(index, "file")); cl_git_pass(git_index_write(index)); *time += 10; cl_repo_commit_from_index(&commit_id, repo, NULL, *time, commit_msg); if (tag_name == NULL) return; cl_git_pass(git_reference_create(&ref, repo, tag_name, &commit_id, 0, NULL)); git_reference_free(ref); }
int git_repository_index(git_index **out, git_repository *repo) { if (git_repository_index__weakptr(out, repo) < 0) return -1; GIT_REFCOUNT_INC(*out); return 0; }
void test_diff_binary__blob_to_blob(void) { git_index *index; git_diff_options opts = GIT_DIFF_OPTIONS_INIT; git_blob *old_blob, *new_blob; git_oid old_id, new_id; struct diff_data diff_data = {0}; opts.flags = GIT_DIFF_SHOW_BINARY | GIT_DIFF_FORCE_BINARY; opts.id_abbrev = GIT_OID_HEXSZ; repo = cl_git_sandbox_init("renames"); cl_git_pass(git_repository_index__weakptr(&index, repo)); cl_git_append2file("renames/untimely.txt", "Oh that crazy Kipling!\r\n"); cl_git_pass(git_index_add_bypath(index, "untimely.txt")); cl_git_pass(git_index_write(index)); git_oid_fromstr(&old_id, "9a69d960ae94b060f56c2a8702545e2bb1abb935"); git_oid_fromstr(&new_id, "1111d4f11f4b35bf6759e0fb714fe09731ef0840"); cl_git_pass(git_blob_lookup(&old_blob, repo, &old_id)); cl_git_pass(git_blob_lookup(&new_blob, repo, &new_id)); cl_git_pass(git_diff_blobs(old_blob, "untimely.txt", new_blob, "untimely.txt", &opts, file_cb, binary_cb, hunk_cb, line_cb, &diff_data)); cl_assert_equal_s("untimely.txt", diff_data.old_path); cl_assert_equal_oid(&old_id, &diff_data.old_id); cl_assert_equal_i(GIT_DIFF_BINARY_DELTA, diff_data.old_binary_type); cl_assert_equal_i(7, diff_data.old_binary_inflatedlen); cl_assert_equal_s("c%18D`@*{63ljhg(E~C7", diff_data.old_binary_base85.ptr); cl_assert_equal_s("untimely.txt", diff_data.new_path); cl_assert_equal_oid(&new_id, &diff_data.new_id); cl_assert_equal_i(GIT_DIFF_BINARY_DELTA, diff_data.new_binary_type); cl_assert_equal_i(32, diff_data.new_binary_inflatedlen); cl_assert_equal_s("c%1vf+QYWt3zLL@hC)e3Vu?a>QDRl4f_G*?PG(-ZA}<#J$+QbW", diff_data.new_binary_base85.ptr); git_blob_free(old_blob); git_blob_free(new_blob); git__free(diff_data.old_path); git__free(diff_data.new_path); git_buf_dispose(&diff_data.old_binary_base85); git_buf_dispose(&diff_data.new_binary_base85); }
void test_index_racy__detects_diff_of_change_in_identical_timestamp(void) { git_index *index; git_diff *diff; cl_git_pass(git_repository_index__weakptr(&index, g_repo)); setup_race(); cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, index, NULL)); cl_assert_equal_i(1, git_diff_num_deltas(diff)); git_diff_free(diff); }
static int attr_file_oid_from_index( git_oid *oid, git_repository *repo, const char *path) { int error; git_index *idx; size_t pos; const git_index_entry *entry; if ((error = git_repository_index__weakptr(&idx, repo)) < 0 || (error = git_index__find_pos(&pos, idx, path, 0, 0)) < 0) return error; if (!(entry = git_index_get_byindex(idx, pos))) return GIT_ENOTFOUND; *oid = entry->id; return 0; }
void test_status_worktree__update_stat_cache_0(void) { git_repository *repo = cl_git_sandbox_init("status"); git_status_options opts = GIT_STATUS_OPTIONS_INIT; git_status_list *status; git_diff_perfdata perf = GIT_DIFF_PERFDATA_INIT; git_index *index; opts.flags = GIT_STATUS_OPT_DEFAULTS; cl_git_pass(git_status_list_new(&status, repo, &opts)); check_status0(status); cl_git_pass(git_status_list_get_perfdata(&perf, status)); cl_assert_equal_sz(13 + 3, perf.stat_calls); cl_assert_equal_sz(5, perf.oid_calculations); git_status_list_free(status); /* tick the index so we avoid recalculating racily-clean entries */ cl_git_pass(git_repository_index__weakptr(&index, repo)); tick_index(index); opts.flags |= GIT_STATUS_OPT_UPDATE_INDEX; cl_git_pass(git_status_list_new(&status, repo, &opts)); check_status0(status); cl_git_pass(git_status_list_get_perfdata(&perf, status)); cl_assert_equal_sz(13 + 3, perf.stat_calls); cl_assert_equal_sz(5, perf.oid_calculations); git_status_list_free(status); opts.flags &= ~GIT_STATUS_OPT_UPDATE_INDEX; /* tick again as the index updating from the previous diff might have reset the timestamp */ tick_index(index); cl_git_pass(git_status_list_new(&status, repo, &opts)); check_status0(status); cl_git_pass(git_status_list_get_perfdata(&perf, status)); cl_assert_equal_sz(13 + 3, perf.stat_calls); cl_assert_equal_sz(0, perf.oid_calculations); git_status_list_free(status); }
void test_index_racy__smudges_index_entry_on_save(void) { git_index *index; const git_index_entry *entry; setup_race(); /* write the index, which will smudge anything that had the same timestamp * as the index when the index was loaded. that way future loads of the * index (with the new timestamp) will know that these files were not * clean. */ cl_git_pass(git_repository_index__weakptr(&index, g_repo)); cl_git_pass(git_index_write(index)); cl_assert(entry = git_index_get_bypath(index, "A", 0)); cl_assert_equal_i(0, entry->file_size); }
static int has_cr_in_index(const git_filter_source *src) { git_repository *repo = git_filter_source_repo(src); const char *path = git_filter_source_path(src); git_index *index; const git_index_entry *entry; git_blob *blob; const void *blobcontent; git_off_t blobsize; bool found_cr; if (!path) return false; if (git_repository_index__weakptr(&index, repo) < 0) { giterr_clear(); return false; } if (!(entry = git_index_get_bypath(index, path, 0)) && !(entry = git_index_get_bypath(index, path, 1))) return false; if (!S_ISREG(entry->mode)) /* don't crlf filter non-blobs */ return true; if (git_blob_lookup(&blob, repo, &entry->id) < 0) return false; blobcontent = git_blob_rawcontent(blob); blobsize = git_blob_rawsize(blob); if (!git__is_sizet(blobsize)) blobsize = (size_t)-1; found_cr = (blobcontent != NULL && blobsize > 0 && memchr(blobcontent, '\r', (size_t)blobsize) != NULL); git_blob_free(blob); return found_cr; }
void test_index_bypath__initialize(void) { g_repo = setup_fixture_submod2(); cl_git_pass(git_repository_index__weakptr(&g_idx, g_repo)); }