void test_refs_rename__packed_doesnt_pack_others(void) { // renaming a packed reference does not pack another reference which happens to be in both loose and pack state git_reference *looked_up_ref, *another_looked_up_ref, *renamed_ref; git_buf temp_path = GIT_BUF_INIT; const char *brand_new_name = "refs/heads/brand_new_name"; /* Ensure the other reference exists on the file system */ cl_git_pass(git_buf_joinpath(&temp_path, git_repository_path(g_repo), packed_test_head_name)); cl_assert(git_path_exists(temp_path.ptr)); /* Lookup the other reference */ cl_git_pass(git_reference_lookup(&another_looked_up_ref, g_repo, packed_test_head_name)); /* Ensure it's loose */ cl_assert(reference_is_packed(another_looked_up_ref) == 0); git_reference_free(another_looked_up_ref); /* Lookup the reference to rename */ cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_head_name)); /* Ensure it's packed */ cl_assert(reference_is_packed(looked_up_ref) != 0); /* Now that the reference is renamed... */ cl_git_pass(git_reference_rename(&renamed_ref, looked_up_ref, brand_new_name, 0, NULL)); git_reference_free(looked_up_ref); /* Lookup the other reference */ cl_git_pass(git_reference_lookup(&another_looked_up_ref, g_repo, packed_test_head_name)); /* Ensure it's loose */ cl_assert(reference_is_packed(another_looked_up_ref) == 0); /* Ensure the other ref still exists on the file system */ cl_assert(git_path_exists(temp_path.ptr)); git_reference_free(renamed_ref); git_reference_free(another_looked_up_ref); git_buf_free(&temp_path); }
static void assert_ignore_case( bool should_ignore_case, int expected_lower_cased_file_status, int expected_camel_cased_file_status) { unsigned int status; git_buf lower_case_path = GIT_BUF_INIT, camel_case_path = GIT_BUF_INIT; git_repository *repo, *repo2; repo = cl_git_sandbox_init("empty_standard_repo"); cl_git_remove_placeholders(git_repository_path(repo), "dummy-marker.txt"); cl_repo_set_bool(repo, "core.ignorecase", should_ignore_case); cl_git_pass(git_buf_joinpath(&lower_case_path, git_repository_workdir(repo), "plop")); cl_git_mkfile(git_buf_cstr(&lower_case_path), ""); stage_and_commit(repo, "plop"); cl_git_pass(git_repository_open(&repo2, "./empty_standard_repo")); cl_git_pass(git_status_file(&status, repo2, "plop")); cl_assert_equal_i(GIT_STATUS_CURRENT, status); cl_git_pass(git_buf_joinpath(&camel_case_path, git_repository_workdir(repo), "Plop")); cl_git_pass(p_rename(git_buf_cstr(&lower_case_path), git_buf_cstr(&camel_case_path))); cl_git_pass(git_status_file(&status, repo2, "plop")); cl_assert_equal_i(expected_lower_cased_file_status, status); cl_git_pass(git_status_file(&status, repo2, "Plop")); cl_assert_equal_i(expected_camel_cased_file_status, status); git_repository_free(repo2); git_buf_free(&lower_case_path); git_buf_free(&camel_case_path); }
void test_repo_open__open_with_discover(void) { static const char *variants[] = { "attr", "attr/", "attr/.git", "attr/.git/", "attr/sub", "attr/sub/", "attr/sub/sub", "attr/sub/sub/", NULL }; git_repository *repo; const char **scan; cl_fixture_sandbox("attr"); cl_git_pass(p_rename("attr/.gitted", "attr/.git")); for (scan = variants; *scan != NULL; scan++) { cl_git_pass(git_repository_open_ext(&repo, *scan, 0, NULL)); cl_assert(git__suffixcmp(git_repository_path(repo), "attr/.git/") == 0); cl_assert(git__suffixcmp(git_repository_workdir(repo), "attr/") == 0); git_repository_free(repo); } cl_fixture_cleanup("attr"); }
isvn_dir_getpath(char **path_out, const char *fmt, ...) { const char *gitrepo; char *dstr, *fstr; va_list ap; int rc; gitrepo = git_repository_path(g_git_repo); xasprintf(&dstr, "%s/isvn", gitrepo); rc = mkdir(dstr, 0777); if (rc < 0 && errno != EEXIST) die_errno("mkdir"); va_start(ap, fmt); xvasprintf(&fstr, fmt, ap); va_end(ap); xasprintf(path_out, "%s/%s", dstr, fstr); free(fstr); free(dstr); }
void test_odb_foreach__files_in_objects_dir(void) { git_repository *repo; git_odb *odb; git_buf buf = GIT_BUF_INIT; int nobj = 0; cl_fixture_sandbox("testrepo.git"); cl_git_pass(git_repository_open(&repo, "testrepo.git")); cl_git_pass(git_buf_printf(&buf, "%s/objects/somefile", git_repository_path(repo))); cl_git_mkfile(buf.ptr, ""); git_buf_dispose(&buf); cl_git_pass(git_repository_odb(&odb, repo)); cl_git_pass(git_odb_foreach(odb, foreach_cb, &nobj)); cl_assert_equal_i(60 + 1640, nobj); /* count + in-pack */ git_odb_free(odb); git_repository_free(repo); cl_fixture_cleanup("testrepo.git"); }
int git_blob_create_fromstream(git_writestream **out, git_repository *repo, const char *hintpath) { int error; git_buf path = GIT_BUF_INIT; blob_writestream *stream; assert(out && repo); stream = git__calloc(1, sizeof(blob_writestream)); GITERR_CHECK_ALLOC(stream); if (hintpath) { stream->hintpath = git__strdup(hintpath); GITERR_CHECK_ALLOC(stream->hintpath); } stream->repo = repo; stream->parent.write = blob_writestream_write; stream->parent.close = blob_writestream_close; stream->parent.free = blob_writestream_free; if ((error = git_buf_joinpath(&path, git_repository_path(repo), GIT_OBJECTS_DIR "streamed")) < 0) goto cleanup; if ((error = git_filebuf_open_withsize(&stream->fbuf, git_buf_cstr(&path), GIT_FILEBUF_TEMPORARY, 0666, 2 * 1024 * 1024)) < 0) goto cleanup; *out = (git_writestream *) stream; cleanup: if (error < 0) blob_writestream_free((git_writestream *) stream); git_buf_free(&path); return error; }
void test_refs_branches_create__can_create_branch_with_unicode(void) { const char *nfc = "\xC3\x85\x73\x74\x72\xC3\xB6\x6D"; const char *nfd = "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D"; const char *emoji = "\xF0\x9F\x8D\xB7"; const char *names[] = { nfc, nfd, emoji }; const char *alt[] = { nfd, nfc, NULL }; const char *expected[] = { nfc, nfd, emoji }; unsigned int i; bool fs_decompose_unicode = git_path_does_fs_decompose_unicode(git_repository_path(repo)); retrieve_known_commit(&target, repo); if (cl_repo_get_bool(repo, "core.precomposeunicode")) expected[1] = nfc; /* test decomp. because not all Mac filesystems decompose unicode */ else if (fs_decompose_unicode) expected[0] = nfd; for (i = 0; i < ARRAY_SIZE(names); ++i) { const char *name; cl_git_pass(git_branch_create( &branch, repo, names[i], target, 0, NULL, NULL)); cl_git_pass(git_oid_cmp( git_reference_target(branch), git_commit_id(target))); cl_git_pass(git_branch_name(&name, branch)); cl_assert_equal_s(expected[i], name); assert_branch_matches_name(expected[i], names[i]); if (fs_decompose_unicode && alt[i]) assert_branch_matches_name(expected[i], alt[i]); cl_git_pass(git_branch_delete(branch)); git_reference_free(branch); branch = NULL; } }
void test_repo_init__relative_gitdir_2(void) { git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT; git_buf dot_git_content = GIT_BUF_INIT; git_buf full_path = GIT_BUF_INIT; cl_git_pass(git_path_prettify(&full_path, ".", NULL)); cl_git_pass(git_buf_joinpath(&full_path, full_path.ptr, "root/b/c_wd")); opts.workdir_path = full_path.ptr; opts.flags = GIT_REPOSITORY_INIT_MKPATH | GIT_REPOSITORY_INIT_RELATIVE_GITLINK | GIT_REPOSITORY_INIT_NO_DOTGIT_DIR; /* make the directory first, then it should succeed */ cl_git_pass(git_repository_init_ext(&_repo, "root/b/my_repository", &opts)); git_buf_free(&full_path); cl_assert(!git__suffixcmp(git_repository_workdir(_repo), "root/b/c_wd/")); cl_assert(!git__suffixcmp(git_repository_path(_repo), "root/b/my_repository/")); cl_assert(!git_repository_is_bare(_repo)); cl_assert(git_repository_is_empty(_repo)); /* Verify that the gitlink and worktree entries are relative */ /* Verify worktree */ assert_config_entry_value(_repo, "core.worktree", "../c_wd/"); /* Verify gitlink */ cl_git_pass(git_futils_readbuffer(&dot_git_content, "root/b/c_wd/.git")); cl_assert_equal_s("gitdir: ../my_repository/", dot_git_content.ptr); git_buf_free(&dot_git_content); cleanup_repository("root"); }
void test_refs_reflog_reflog__renaming_the_reference_moves_the_reflog(void) { git_reference *master, *new_master; git_buf master_log_path = GIT_BUF_INIT, moved_log_path = GIT_BUF_INIT; git_buf_joinpath(&master_log_path, git_repository_path(g_repo), GIT_REFLOG_DIR); git_buf_puts(&moved_log_path, git_buf_cstr(&master_log_path)); git_buf_joinpath(&master_log_path, git_buf_cstr(&master_log_path), "refs/heads/master"); git_buf_joinpath(&moved_log_path, git_buf_cstr(&moved_log_path), "refs/moved"); cl_assert_equal_i(true, git_path_isfile(git_buf_cstr(&master_log_path))); cl_assert_equal_i(false, git_path_isfile(git_buf_cstr(&moved_log_path))); cl_git_pass(git_reference_lookup(&master, g_repo, "refs/heads/master")); cl_git_pass(git_reference_rename(&new_master, master, "refs/moved", 0, NULL)); git_reference_free(master); cl_assert_equal_i(false, git_path_isfile(git_buf_cstr(&master_log_path))); cl_assert_equal_i(true, git_path_isfile(git_buf_cstr(&moved_log_path))); git_reference_free(new_master); git_buf_dispose(&moved_log_path); git_buf_dispose(&master_log_path); }
void test_reset_soft__fails_when_index_contains_conflicts_independently_of_MERGE_HEAD_file_existence(void) { git_index *index; git_reference *head; git_buf merge_head_path = GIT_BUF_INIT; cl_git_sandbox_cleanup(); repo = cl_git_sandbox_init("mergedrepo"); cl_git_pass(git_buf_joinpath(&merge_head_path, git_repository_path(repo), "MERGE_HEAD")); cl_git_pass(p_unlink(git_buf_cstr(&merge_head_path))); git_buf_free(&merge_head_path); cl_git_pass(git_repository_index(&index, repo)); cl_assert_equal_i(true, git_index_has_conflicts(index)); git_index_free(index); cl_git_pass(git_repository_head(&head, repo)); cl_git_pass(git_reference_peel(&target, head, GIT_OBJ_COMMIT)); git_reference_free(head); cl_assert_equal_i(GIT_EUNMERGED, git_reset(repo, target, GIT_RESET_SOFT)); }
static int clone_local_into(git_repository *repo, git_remote *remote, const git_fetch_options *fetch_opts, const git_checkout_options *co_opts, const char *branch, int link) { int error, flags; git_repository *src; git_buf src_odb = GIT_BUF_INIT, dst_odb = GIT_BUF_INIT, src_path = GIT_BUF_INIT; git_buf reflog_message = GIT_BUF_INIT; assert(repo && remote); if (!git_repository_is_empty(repo)) { git_error_set(GIT_ERROR_INVALID, "the repository is not empty"); return -1; } /* * Let's figure out what path we should use for the source * repo, if it's not rooted, the path should be relative to * the repository's worktree/gitdir. */ if ((error = git_path_from_url_or_path(&src_path, git_remote_url(remote))) < 0) return error; /* Copy .git/objects/ from the source to the target */ if ((error = git_repository_open(&src, git_buf_cstr(&src_path))) < 0) { git_buf_dispose(&src_path); return error; } if (git_repository_item_path(&src_odb, src, GIT_REPOSITORY_ITEM_OBJECTS) < 0 || git_repository_item_path(&dst_odb, repo, GIT_REPOSITORY_ITEM_OBJECTS) < 0) { error = -1; goto cleanup; } flags = 0; if (can_link(git_repository_path(src), git_repository_path(repo), link)) flags |= GIT_CPDIR_LINK_FILES; error = git_futils_cp_r(git_buf_cstr(&src_odb), git_buf_cstr(&dst_odb), flags, GIT_OBJECT_DIR_MODE); /* * can_link() doesn't catch all variations, so if we hit an * error and did want to link, let's try again without trying * to link. */ if (error < 0 && link) { flags &= ~GIT_CPDIR_LINK_FILES; error = git_futils_cp_r(git_buf_cstr(&src_odb), git_buf_cstr(&dst_odb), flags, GIT_OBJECT_DIR_MODE); } if (error < 0) goto cleanup; git_buf_printf(&reflog_message, "clone: from %s", git_remote_url(remote)); if ((error = git_remote_fetch(remote, NULL, fetch_opts, git_buf_cstr(&reflog_message))) != 0) goto cleanup; error = checkout_branch(repo, remote, co_opts, branch, git_buf_cstr(&reflog_message)); cleanup: git_buf_dispose(&reflog_message); git_buf_dispose(&src_path); git_buf_dispose(&src_odb); git_buf_dispose(&dst_odb); git_repository_free(src); return error; }
/* * As the server is probably using Transfer-Encoding: chunked, we have * to use the HTTP parser to download the pack instead of giving it to * the simple downloader. Furthermore, we're using keep-alive * connections, so the simple downloader would just hang. */ static int http_download_pack(git_transport *transport, git_repository *repo, git_off_t *bytes, git_indexer_stats *stats) { transport_http *t = (transport_http *) transport; git_buf *oldbuf = &t->buf; int recvd; http_parser_settings settings; char buffer[1024]; gitno_buffer buf; git_buf path = GIT_BUF_INIT; git_indexer_stream *idx = NULL; download_pack_cbdata data; gitno_buffer_setup(transport, &buf, buffer, sizeof(buffer)); if (memcmp(oldbuf->ptr, "PACK", strlen("PACK"))) { giterr_set(GITERR_NET, "The pack doesn't start with a pack signature"); return -1; } if (git_buf_joinpath(&path, git_repository_path(repo), "objects/pack") < 0) return -1; if (git_indexer_stream_new(&idx, git_buf_cstr(&path)) < 0) return -1; /* * This is part of the previous response, so we don't want to * re-init the parser, just set these two callbacks. */ memset(stats, 0, sizeof(git_indexer_stats)); data.stats = stats; data.idx = idx; data.transport = t; t->parser.data = &data; t->transfer_finished = 0; memset(&settings, 0x0, sizeof(settings)); settings.on_message_complete = on_message_complete_download_pack; settings.on_body = on_body_download_pack; *bytes = git_buf_len(oldbuf); if (git_indexer_stream_add(idx, git_buf_cstr(oldbuf), git_buf_len(oldbuf), stats) < 0) goto on_error; gitno_buffer_setup(transport, &buf, buffer, sizeof(buffer)); do { size_t parsed; if ((recvd = gitno_recv(&buf)) < 0) goto on_error; parsed = http_parser_execute(&t->parser, &settings, buf.data, buf.offset); if (parsed != buf.offset || t->error < 0) goto on_error; *bytes += recvd; gitno_consume_n(&buf, parsed); } while (recvd > 0 && !t->transfer_finished); if (git_indexer_stream_finalize(idx, stats) < 0) goto on_error; git_indexer_stream_free(idx); return 0; on_error: git_indexer_stream_free(idx); git_buf_free(&path); return -1; }
must_pass(chdir(current_workdir)); rmdir_recurs(TEMP_REPO_FOLDER); END_TEST #define EMPTY_BARE_REPOSITORY_NAME "empty_bare.git" #define EMPTY_BARE_REPOSITORY_FOLDER TEST_RESOURCES "/" EMPTY_BARE_REPOSITORY_NAME "/" BEGIN_TEST(open0, "Open a bare repository that has just been initialized by git") git_repository *repo; must_pass(copydir_recurs(EMPTY_BARE_REPOSITORY_FOLDER, TEMP_REPO_FOLDER)); must_pass(remove_placeholders(TEMP_REPO_FOLDER, "dummy-marker.txt")); must_pass(git_repository_open(&repo, TEMP_REPO_FOLDER)); must_be_true(git_repository_path(repo) != NULL); must_be_true(git_repository_workdir(repo) == NULL); git_repository_free(repo); must_pass(rmdir_recurs(TEMP_REPO_FOLDER)); END_TEST #define SOURCE_EMPTY_REPOSITORY_NAME "empty_standard_repo/.gitted" #define EMPTY_REPOSITORY_NAME "empty_standard_repo/.git" #define EMPTY_REPOSITORY_FOLDER TEST_RESOURCES "/" SOURCE_EMPTY_REPOSITORY_NAME "/" #define DEST_REPOSITORY_FOLDER TEMP_REPO_FOLDER DOT_GIT "/" BEGIN_TEST(open1, "Open a standard repository that has just been initialized by git") git_repository *repo; must_pass(copydir_recurs(EMPTY_REPOSITORY_FOLDER, DEST_REPOSITORY_FOLDER));
std::string Repository::Path() const { // TODO: Check for memory leak! const char* psPath = git_repository_path(m_pRepository); return std::string(psPath); }
static void setup_simple_state(const char *filename) { cl_git_pass(git_buf_joinpath(&_path, git_repository_path(_repo), filename)); git_futils_mkpath2file(git_buf_cstr(&_path), 0777); cl_git_mkfile(git_buf_cstr(&_path), "dummy"); }
/** Entry point for this command */ int fetch(git_repository *repo, int argc, char **argv) { int err = GIT_OK; int rc = EXIT_FAILURE; git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; const git_transfer_progress *stats; git_remote *remote = NULL; if (argc < 2) { fprintf(stderr, "usage: %s fetch <repo>\n", argv[-1]); return EXIT_FAILURE; } // Figure out whether it's a named remote or a URL printf("Fetching %s for repo at %s\n", argv[1], git_repository_path(repo)); if (git_remote_lookup(&remote, repo, argv[1]) < 0) { if ((err = git_remote_create_anonymous(&remote, repo, argv[1], NULL)) < 0) goto out; } // Set up the callbacks (only update_tips for now) callbacks.update_tips = &update_cb; callbacks.sideband_progress = &progress_cb; callbacks.credentials = cred_acquire_cb; callbacks.certificate_check = certificate_check; git_remote_set_callbacks(remote, &callbacks); stats = git_remote_stats(remote); if ((err = git_remote_connect(remote, GIT_DIRECTION_FETCH) < 0)) goto out; // Download the packfile and index it. This function updates the // amount of received data and the indexer stats which lets you // inform the user about progress. if ((err = git_remote_download(remote, NULL) < 0)) goto out; /** * If there are local objects (we got a thin pack), then tell * the user how many objects we saved from having to cross the * network. */ if (stats->local_objects > 0) { printf("\rReceived %d/%d objects in %zu bytes (used %d local objects)\n", stats->indexed_objects, stats->total_objects, stats->received_bytes, stats->local_objects); } else{ printf("\rReceived %d/%d objects in %zu bytes\n", stats->indexed_objects, stats->total_objects, stats->received_bytes); } // Disconnect the underlying connection to prevent from idling. git_remote_disconnect(remote); // Update the references in the remote's namespace to point to the // right commits. This may be needed even if there was no packfile // to download, which can happen e.g. when the branches have been // changed but all the needed objects are available locally. if ((err = git_remote_update_tips(remote, NULL, NULL)) < 0) goto out; rc = EXIT_SUCCESS; out: if (err != GIT_OK) libgit_error(); if (remote) git_remote_free(remote); return rc; }
void test_repo_open__from_git_new_workdir(void) { /* The git-new-workdir script that ships with git sets up a bunch of * symlinks to create a second workdir that shares the object db with * another checkout. Libgit2 can open a repo that has been configured * this way. */ cl_git_sandbox_init("empty_standard_repo"); #ifndef GIT_WIN32 git_repository *repo2; git_buf link_tgt = GIT_BUF_INIT, link = GIT_BUF_INIT, body = GIT_BUF_INIT; const char **scan; int link_fd; static const char *links[] = { "config", "refs", "logs/refs", "objects", "info", "hooks", "packed-refs", "remotes", "rr-cache", "svn", NULL }; static const char *copies[] = { "HEAD", NULL }; cl_git_pass(p_mkdir("alternate", 0777)); cl_git_pass(p_mkdir("alternate/.git", 0777)); for (scan = links; *scan != NULL; scan++) { git_buf_joinpath(&link_tgt, "empty_standard_repo/.git", *scan); if (git_path_exists(link_tgt.ptr)) { git_buf_joinpath(&link_tgt, "../../empty_standard_repo/.git", *scan); git_buf_joinpath(&link, "alternate/.git", *scan); if (strchr(*scan, '/')) git_futils_mkpath2file(link.ptr, 0777); cl_assert_(symlink(link_tgt.ptr, link.ptr) == 0, strerror(errno)); } } for (scan = copies; *scan != NULL; scan++) { git_buf_joinpath(&link_tgt, "empty_standard_repo/.git", *scan); if (git_path_exists(link_tgt.ptr)) { git_buf_joinpath(&link, "alternate/.git", *scan); cl_git_pass(git_futils_readbuffer(&body, link_tgt.ptr)); cl_assert((link_fd = git_futils_creat_withpath(link.ptr, 0777, 0666)) >= 0); cl_must_pass(p_write(link_fd, body.ptr, body.size)); p_close(link_fd); } } git_buf_free(&link_tgt); git_buf_free(&link); git_buf_free(&body); cl_git_pass(git_repository_open(&repo2, "alternate")); cl_assert(git_repository_path(repo2) != NULL); cl_assert_(git__suffixcmp(git_repository_path(repo2), "alternate/.git/") == 0, git_repository_path(repo2)); cl_assert(git_repository_workdir(repo2) != NULL); cl_assert_(git__suffixcmp(git_repository_workdir(repo2), "alternate/") == 0, git_repository_workdir(repo2)); git_repository_free(repo2); #endif }
const char * Repository::path() const { return git_repository_path(repo_); }
void test_network_remote_defaultbranch__initialize(void) { g_repo_a = cl_git_sandbox_init("testrepo.git"); cl_git_pass(git_repository_init(&g_repo_b, "repo-b.git", true)); cl_git_pass(git_remote_create(&g_remote, g_repo_b, "origin", git_repository_path(g_repo_a))); }
void test_threads_refdb__edit_while_iterate(void) { int r, t; struct th_data th_data[THREADS]; git_oid head; git_reference *ref; char name[128]; git_refdb *refdb; #ifdef GIT_THREADS git_thread th[THREADS]; #endif g_repo = cl_git_sandbox_init("testrepo2"); cl_git_pass(git_reference_name_to_id(&head, g_repo, "HEAD")); /* make a bunch of references */ for (r = 0; r < 50; ++r) { p_snprintf(name, sizeof(name), "refs/heads/starter-%03d", r); cl_git_pass(git_reference_create(&ref, g_repo, name, &head, 0, NULL)); git_reference_free(ref); } cl_git_pass(git_repository_refdb(&refdb, g_repo)); cl_git_pass(git_refdb_compress(refdb)); git_refdb_free(refdb); g_expected = -1; g_repo = cl_git_sandbox_reopen(); /* reopen to flush caches */ for (t = 0; t < THREADS; ++t) { void *(*fn)(void *arg); switch (t & 0x3) { case 0: fn = create_refs; break; case 1: fn = delete_refs; break; default: fn = iterate_refs; break; } th_data[t].id = t; th_data[t].path = git_repository_path(g_repo); #ifdef GIT_THREADS cl_git_pass(git_thread_create(&th[t], fn, &th_data[t])); #else fn(&th_data[t]); #endif } #ifdef GIT_THREADS for (t = 0; t < THREADS; ++t) { cl_git_pass(git_thread_join(&th[t], NULL)); cl_git_thread_check(&th_data[t]); } memset(th, 0, sizeof(th)); for (t = 0; t < THREADS; ++t) { th_data[t].id = t; cl_git_pass(git_thread_create(&th[t], iterate_refs, &th_data[t])); } for (t = 0; t < THREADS; ++t) { cl_git_pass(git_thread_join(&th[t], NULL)); cl_git_thread_check(&th_data[t]); } #endif }
void test_network_fetchlocal__prune(void) { git_repository *repo; git_remote *origin; int callcount = 0; git_strarray refnames = {0}; git_reference *ref; git_repository *remote_repo = cl_git_sandbox_init("testrepo.git"); const char *url = cl_git_path_url(git_repository_path(remote_repo)); git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; callbacks.transfer_progress = transfer_cb; callbacks.payload = &callcount; cl_set_cleanup(&cleanup_local_repo, "foo"); cl_git_pass(git_repository_init(&repo, "foo", true)); cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url)); git_remote_set_callbacks(origin, &callbacks); cl_git_pass(git_remote_fetch(origin, NULL, NULL, NULL)); cl_git_pass(git_reference_list(&refnames, repo)); cl_assert_equal_i(19, (int)refnames.count); cl_assert(callcount > 0); git_strarray_free(&refnames); git_remote_free(origin); cl_git_pass(git_reference_lookup(&ref, remote_repo, "refs/heads/br2")); cl_git_pass(git_reference_delete(ref)); git_reference_free(ref); cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN)); git_remote_set_callbacks(origin, &callbacks); cl_git_pass(git_remote_connect(origin, GIT_DIRECTION_FETCH)); cl_git_pass(git_remote_download(origin, NULL)); cl_git_pass(git_remote_prune(origin)); cl_git_pass(git_remote_update_tips(origin, NULL, NULL)); cl_git_pass(git_reference_list(&refnames, repo)); cl_assert_equal_i(18, (int)refnames.count); git_strarray_free(&refnames); git_remote_free(origin); cl_git_pass(git_reference_lookup(&ref, remote_repo, "refs/heads/packed")); cl_git_pass(git_reference_delete(ref)); git_reference_free(ref); cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN)); git_remote_set_callbacks(origin, &callbacks); cl_git_pass(git_remote_connect(origin, GIT_DIRECTION_FETCH)); cl_git_pass(git_remote_download(origin, NULL)); cl_git_pass(git_remote_prune(origin)); cl_git_pass(git_remote_update_tips(origin, NULL, NULL)); cl_git_pass(git_reference_list(&refnames, repo)); cl_assert_equal_i(17, (int)refnames.count); git_strarray_free(&refnames); git_remote_free(origin); git_repository_free(repo); }
void test_clone_local__hardlinks(void) { git_repository *repo; git_clone_options opts = GIT_CLONE_OPTIONS_INIT; git_buf buf = GIT_BUF_INIT; struct stat st; /* * In this first clone, we just copy over, since the temp dir * will often be in a different filesystem, so we cannot * link. It also allows us to control the number of links */ opts.bare = true; opts.local = GIT_CLONE_LOCAL_NO_LINKS; cl_git_pass(git_clone(&repo, cl_fixture("testrepo.git"), "./clone.git", &opts)); git_repository_free(repo); /* This second clone is in the same filesystem, so we can hardlink */ opts.local = GIT_CLONE_LOCAL; cl_git_pass(git_clone(&repo, cl_git_path_url("clone.git"), "./clone2.git", &opts)); #ifndef GIT_WIN32 git_buf_clear(&buf); cl_git_pass(git_buf_join_n(&buf, '/', 4, git_repository_path(repo), "objects", "08", "b041783f40edfe12bb406c9c9a8a040177c125")); cl_git_pass(p_stat(buf.ptr, &st)); cl_assert_equal_i(2, st.st_nlink); #endif git_repository_free(repo); git_buf_clear(&buf); opts.local = GIT_CLONE_LOCAL_NO_LINKS; cl_git_pass(git_clone(&repo, cl_git_path_url("clone.git"), "./clone3.git", &opts)); git_buf_clear(&buf); cl_git_pass(git_buf_join_n(&buf, '/', 4, git_repository_path(repo), "objects", "08", "b041783f40edfe12bb406c9c9a8a040177c125")); cl_git_pass(p_stat(buf.ptr, &st)); cl_assert_equal_i(1, st.st_nlink); git_repository_free(repo); /* this one should automatically use links */ cl_git_pass(git_clone(&repo, "./clone.git", "./clone4.git", NULL)); #ifndef GIT_WIN32 git_buf_clear(&buf); cl_git_pass(git_buf_join_n(&buf, '/', 4, git_repository_path(repo), "objects", "08", "b041783f40edfe12bb406c9c9a8a040177c125")); cl_git_pass(p_stat(buf.ptr, &st)); cl_assert_equal_i(3, st.st_nlink); #endif git_buf_free(&buf); git_repository_free(repo); cl_git_pass(git_futils_rmdir_r("./clone.git", NULL, GIT_RMDIR_REMOVE_FILES)); cl_git_pass(git_futils_rmdir_r("./clone2.git", NULL, GIT_RMDIR_REMOVE_FILES)); cl_git_pass(git_futils_rmdir_r("./clone3.git", NULL, GIT_RMDIR_REMOVE_FILES)); cl_git_pass(git_futils_rmdir_r("./clone4.git", NULL, GIT_RMDIR_REMOVE_FILES)); }
PyObject * Repository_path__get__(Repository *self, void *closure) { return to_path(git_repository_path(self->repo)); }
static void *run_index_diffs(void *arg) { int thread = *(int *)arg; git_repository *repo; git_diff_options opts = GIT_DIFF_OPTIONS_INIT; git_diff *diff = NULL; size_t i; int exp[4] = { 0, 0, 0, 0 }; cl_git_pass(git_repository_open(&repo, git_repository_path(_repo))); switch (thread & 0x03) { case 0: /* diff index to workdir */; cl_git_pass(git_diff_index_to_workdir(&diff, repo, NULL, &opts)); break; case 1: /* diff tree 'a' to index */; cl_git_pass(git_diff_tree_to_index(&diff, repo, _a, NULL, &opts)); break; case 2: /* diff tree 'b' to index */; cl_git_pass(git_diff_tree_to_index(&diff, repo, _b, NULL, &opts)); break; case 3: /* diff index to workdir (explicit index) */; { git_index *idx; cl_git_pass(git_repository_index(&idx, repo)); cl_git_pass(git_diff_index_to_workdir(&diff, repo, idx, &opts)); git_index_free(idx); break; } } /* keep some diff stats to make sure results are as expected */ i = git_diff_num_deltas(diff); git_atomic_add(&_counts[0], (int32_t)i); exp[0] = (int)i; while (i > 0) { switch (git_diff_get_delta(diff, --i)->status) { case GIT_DELTA_MODIFIED: exp[1]++; git_atomic_inc(&_counts[1]); break; case GIT_DELTA_ADDED: exp[2]++; git_atomic_inc(&_counts[2]); break; case GIT_DELTA_DELETED: exp[3]++; git_atomic_inc(&_counts[3]); break; default: break; } } switch (thread & 0x03) { case 0: case 3: cl_assert_equal_i(8, exp[0]); cl_assert_equal_i(4, exp[1]); cl_assert_equal_i(0, exp[2]); cl_assert_equal_i(4, exp[3]); break; case 1: cl_assert_equal_i(12, exp[0]); cl_assert_equal_i(3, exp[1]); cl_assert_equal_i(7, exp[2]); cl_assert_equal_i(2, exp[3]); break; case 2: cl_assert_equal_i(8, exp[0]); cl_assert_equal_i(3, exp[1]); cl_assert_equal_i(3, exp[2]); cl_assert_equal_i(2, exp[3]); break; } git_diff_free(diff); git_repository_free(repo); git_error_clear(); return arg; }