void test_refs_pack__symbolic(void) { /* create a packfile from loose refs skipping symbolic refs */ int i; git_oid head; git_reference *ref; char name[128]; cl_git_pass(git_reference_name_to_id(&head, g_repo, "HEAD")); /* make a bunch of references */ for (i = 0; i < 100; ++i) { p_snprintf(name, sizeof(name), "refs/heads/symbolic-%03d", i); cl_git_pass(git_reference_symbolic_create( &ref, g_repo, name, "refs/heads/master", 0, NULL)); git_reference_free(ref); p_snprintf(name, sizeof(name), "refs/heads/direct-%03d", i); cl_git_pass(git_reference_create(&ref, g_repo, name, &head, 0, NULL)); git_reference_free(ref); } packall(); }
void test_stress_diff__rename_many_files(void) { git_index *index; char tmp[64]; int i; git_buf b = GIT_BUF_INIT; g_repo = cl_git_sandbox_init("renames"); cl_git_pass(git_repository_index(&index, g_repo)); git_buf_printf(&b, "%08d\n" ANOTHER_POEM "%08d\n" ANOTHER_POEM ANOTHER_POEM, 0, 0); for (i = 0; i < 2500; i += 1) { p_snprintf(tmp, sizeof(tmp), "renames/newfile%03d", i); p_snprintf(b.ptr, 9, "%08d", i); b.ptr[8] = '\n'; cl_git_mkfile(tmp, b.ptr); } git_buf_dispose(&b); for (i = 0; i < 2500; i += 1) { p_snprintf(tmp, sizeof(tmp), "renames/newfile%03d", i); cl_git_pass(git_index_add_bypath(index, tmp + strlen("renames/"))); } git_index_free(index); test_with_many(2500); }
void test_stress_diff__rename_big_files(void) { git_index *index; char tmp[64]; int i, j; git_buf b = GIT_BUF_INIT; g_repo = cl_git_sandbox_init("renames"); cl_git_pass(git_repository_index(&index, g_repo)); for (i = 0; i < 100; i += 1) { p_snprintf(tmp, sizeof(tmp), "renames/newfile%03d", i); for (j = i * 256; j > 0; --j) git_buf_printf(&b, "more content %d\n", i); cl_git_mkfile(tmp, b.ptr); } for (i = 0; i < 100; i += 1) { p_snprintf(tmp, sizeof(tmp), "renames/newfile%03d", i); cl_git_pass(git_index_add_bypath(index, tmp + strlen("renames/"))); } git_buf_dispose(&b); git_index_free(index); test_with_many(100); }
void clar__assert_equal( const char *file, int line, const char *err, int should_abort, const char *fmt, ...) { va_list args; char buf[4096]; int is_equal = 1; va_start(args, fmt); if (!strcmp("%s", fmt)) { const char *s1 = va_arg(args, const char *); const char *s2 = va_arg(args, const char *); is_equal = (!s1 || !s2) ? (s1 == s2) : !strcmp(s1, s2); if (!is_equal) { if (s1 && s2) { int pos; for (pos = 0; s1[pos] == s2[pos] && s1[pos] && s2[pos]; ++pos) /* find differing byte offset */; p_snprintf(buf, sizeof(buf), "'%s' != '%s' (at byte %d)", s1, s2, pos); } else { p_snprintf(buf, sizeof(buf), "'%s' != '%s'", s1, s2); } } } else if (!strcmp("%"PRIuZ, fmt) || !strcmp("%"PRIxZ, fmt)) {
int git_odb__format_object_header(char *hdr, size_t n, size_t obj_len, git_otype obj_type) { const char *type_str = git_object_type2string(obj_type); int len = p_snprintf(hdr, n, "%s %"PRIuZ, type_str, obj_len); assert(len > 0 && len <= (int)n); return len+1; }
static void *delete_refs(void *arg) { int *id = arg, i; git_reference *ref; char name[128]; for (i = 0; i < 10; ++i) { p_snprintf( name, sizeof(name), "refs/heads/thread-%03d-%02d", (*id) & ~0x3, i); if (!git_reference_lookup(&ref, g_repo, name)) { cl_git_pass(git_reference_delete(ref)); git_reference_free(ref); } if (i == 5) { git_refdb *refdb; cl_git_pass(git_repository_refdb(&refdb, g_repo)); cl_git_pass(git_refdb_compress(refdb)); git_refdb_free(refdb); } } giterr_clear(); return arg; }
static void *create_refs(void *arg) { int *id = arg, i; git_oid head; char name[128]; git_reference *ref[10]; cl_git_pass(git_reference_name_to_id(&head, g_repo, "HEAD")); for (i = 0; i < 10; ++i) { p_snprintf(name, sizeof(name), "refs/heads/thread-%03d-%02d", *id, i); cl_git_pass(git_reference_create(&ref[i], g_repo, name, &head, 0, NULL)); if (i == 5) { git_refdb *refdb; cl_git_pass(git_repository_refdb(&refdb, g_repo)); cl_git_pass(git_refdb_compress(refdb)); git_refdb_free(refdb); } } for (i = 0; i < 10; ++i) git_reference_free(ref[i]); giterr_clear(); return arg; }
void cl_git_report_failure( int error, int expected, const char *file, int line, const char *fncall) { char msg[4096]; const git_error *last = git_error_last(); if (expected) p_snprintf(msg, 4096, "error %d (expected %d) - %s", error, expected, last ? last->message : "<no message>"); else if (error || last) p_snprintf(msg, 4096, "error %d - %s", error, last ? last->message : "<no message>"); else p_snprintf(msg, 4096, "no error, expected non-zero return"); clar__assert(0, file, line, fncall, msg, 1); }
void cl_git_report_failure( int error, const char *file, int line, const char *fncall) { char msg[4096]; const git_error *last = giterr_last(); p_snprintf(msg, 4096, "error %d - %s", error, last ? last->message : "<no message>"); clar__assert(0, file, line, fncall, msg, 1); }
void test_threads_refdb__iterator(void) { int r, t; git_thread th[THREADS]; int id[THREADS]; git_oid head; git_reference *ref; char name[128]; git_refdb *refdb; 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 < 200; ++r) { p_snprintf(name, sizeof(name), "refs/heads/direct-%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 = 206; for (r = 0; r < REPEAT; ++r) { g_repo = cl_git_sandbox_reopen(); /* reopen to flush caches */ for (t = 0; t < THREADS; ++t) { id[t] = t; #ifdef GIT_THREADS cl_git_pass(git_thread_create(&th[t], iterate_refs, &id[t])); #else th[t] = t; iterate_refs(&id[t]); #endif } #ifdef GIT_THREADS for (t = 0; t < THREADS; ++t) { cl_git_pass(git_thread_join(&th[t], NULL)); } #endif memset(th, 0, sizeof(th)); } }
void clar__assert_equal_file( const char *expected_data, size_t expected_bytes, int ignore_cr, const char *path, const char *file, int line) { char buf[4000]; ssize_t bytes, total_bytes = 0; int fd = p_open(path, O_RDONLY | O_BINARY); cl_assert(fd >= 0); if (expected_data && !expected_bytes) expected_bytes = strlen(expected_data); while ((bytes = p_read(fd, buf, sizeof(buf))) != 0) { clar__assert( bytes > 0, file, line, "error reading from file", path, 1); if (ignore_cr) bytes = strip_cr_from_buf(buf, bytes); if (memcmp(expected_data, buf, bytes) != 0) { int pos; for (pos = 0; pos < bytes && expected_data[pos] == buf[pos]; ++pos) /* find differing byte offset */; p_snprintf( buf, sizeof(buf), "file content mismatch at byte %"PRIdZ, (ssize_t)(total_bytes + pos)); p_close(fd); clar__fail(file, line, path, buf, 1); } expected_data += bytes; total_bytes += bytes; } p_close(fd); clar__assert(!bytes, file, line, "error reading from file", path, 1); clar__assert_equal(file, line, "mismatched file length", 1, "%"PRIuZ, (size_t)expected_bytes, (size_t)total_bytes); }
static void *create_refs(void *arg) { int i, error; struct th_data *data = (struct th_data *) arg; git_oid head; char name[128]; git_reference *ref[NREFS]; git_repository *repo; cl_git_thread_pass(data, git_repository_open(&repo, data->path)); do { error = git_reference_name_to_id(&head, repo, "HEAD"); } while (error == GIT_ELOCKED); cl_git_thread_pass(data, error); for (i = 0; i < NREFS; ++i) { p_snprintf(name, sizeof(name), "refs/heads/thread-%03d-%02d", data->id, i); do { error = git_reference_create(&ref[i], repo, name, &head, 0, NULL); } while (error == GIT_ELOCKED); cl_git_thread_pass(data, error); if (concurrent_compress && i == NREFS/2) { git_refdb *refdb; cl_git_thread_pass(data, git_repository_refdb(&refdb, repo)); do { error = git_refdb_compress(refdb); } while (error == GIT_ELOCKED); cl_git_thread_pass(data, error); git_refdb_free(refdb); } } for (i = 0; i < NREFS; ++i) git_reference_free(ref[i]); git_repository_free(repo); git_error_clear(); return arg; }
static void *delete_refs(void *arg) { int i, error; struct th_data *data = (struct th_data *) arg; git_reference *ref; char name[128]; git_repository *repo; cl_git_thread_pass(data, git_repository_open(&repo, data->path)); for (i = 0; i < NREFS; ++i) { p_snprintf( name, sizeof(name), "refs/heads/thread-%03d-%02d", (data->id) & ~0x3, i); if (!git_reference_lookup(&ref, repo, name)) { do { error = git_reference_delete(ref); } while (error == GIT_ELOCKED); /* Sometimes we race with other deleter threads */ if (error == GIT_ENOTFOUND) error = 0; cl_git_thread_pass(data, error); git_reference_free(ref); } if (concurrent_compress && i == NREFS/2) { git_refdb *refdb; cl_git_thread_pass(data, git_repository_refdb(&refdb, repo)); do { error = git_refdb_compress(refdb); } while (error == GIT_ELOCKED); cl_git_thread_pass(data, error); git_refdb_free(refdb); } } git_repository_free(repo); git_error_clear(); return arg; }
static void build_workdir_tree(const char *root, int dirs, int subs) { int i, j; char buf[64], sub[80]; for (i = 0; i < dirs; ++i) { if (i % 2 == 0) { p_snprintf(buf, sizeof(buf), "%s/dir%02d", root, i); cl_git_pass(git_futils_mkdir(buf, 0775, GIT_MKDIR_PATH)); p_snprintf(buf, sizeof(buf), "%s/dir%02d/file", root, i); cl_git_mkfile(buf, buf); buf[strlen(buf) - 5] = '\0'; } else { p_snprintf(buf, sizeof(buf), "%s/DIR%02d", root, i); cl_git_pass(git_futils_mkdir(buf, 0775, GIT_MKDIR_PATH)); } for (j = 0; j < subs; ++j) { switch (j % 4) { case 0: p_snprintf(sub, sizeof(sub), "%s/sub%02d", buf, j); break; case 1: p_snprintf(sub, sizeof(sub), "%s/sUB%02d", buf, j); break; case 2: p_snprintf(sub, sizeof(sub), "%s/Sub%02d", buf, j); break; case 3: p_snprintf(sub, sizeof(sub), "%s/SUB%02d", buf, j); break; } cl_git_pass(git_futils_mkdir(sub, 0775, GIT_MKDIR_PATH)); if (j % 2 == 0) { size_t sublen = strlen(sub); memcpy(&sub[sublen], "/file", sizeof("/file")); cl_git_mkfile(sub, sub); sub[sublen] = '\0'; } } } }
static void aux_cb_lookup__1(unsigned int aux_id, char *aux_msg, unsigned int aux_msg_len) { p_snprintf(aux_msg, aux_msg_len, "\tQQ%08x\n", aux_id); }
static int winhttp_stream_read( git_smart_subtransport_stream *stream, char *buffer, size_t buf_size, size_t *bytes_read) { winhttp_stream *s = (winhttp_stream *)stream; winhttp_subtransport *t = OWNING_SUBTRANSPORT(s); DWORD dw_bytes_read; char replay_count = 0; int error; replay: /* Enforce a reasonable cap on the number of replays */ if (++replay_count >= 7) { giterr_set(GITERR_NET, "Too many redirects or authentication replays"); return -1; } /* Connect if necessary */ if (!s->request && winhttp_stream_connect(s) < 0) return -1; if (!s->received_response) { DWORD status_code, status_code_length, content_type_length, bytes_written; char expected_content_type_8[MAX_CONTENT_TYPE_LEN]; wchar_t expected_content_type[MAX_CONTENT_TYPE_LEN], content_type[MAX_CONTENT_TYPE_LEN]; if (!s->sent_request) { if ((error = send_request(s, s->post_body_len, 0)) < 0) return error; s->sent_request = 1; } if (s->chunked) { assert(s->verb == post_verb); /* Flush, if necessary */ if (s->chunk_buffer_len > 0 && write_chunk(s->request, s->chunk_buffer, s->chunk_buffer_len) < 0) return -1; s->chunk_buffer_len = 0; /* Write the final chunk. */ if (!WinHttpWriteData(s->request, "0\r\n\r\n", 5, &bytes_written)) { giterr_set(GITERR_OS, "Failed to write final chunk"); return -1; } } else if (s->post_body) { char *buffer; DWORD len = s->post_body_len, bytes_read; if (INVALID_SET_FILE_POINTER == SetFilePointer(s->post_body, 0, 0, FILE_BEGIN) && NO_ERROR != GetLastError()) { giterr_set(GITERR_OS, "Failed to reset file pointer"); return -1; } buffer = git__malloc(CACHED_POST_BODY_BUF_SIZE); while (len > 0) { DWORD bytes_written; if (!ReadFile(s->post_body, buffer, min(CACHED_POST_BODY_BUF_SIZE, len), &bytes_read, NULL) || !bytes_read) { git__free(buffer); giterr_set(GITERR_OS, "Failed to read from temp file"); return -1; } if (!WinHttpWriteData(s->request, buffer, bytes_read, &bytes_written)) { git__free(buffer); giterr_set(GITERR_OS, "Failed to write data"); return -1; } len -= bytes_read; assert(bytes_read == bytes_written); } git__free(buffer); /* Eagerly close the temp file */ CloseHandle(s->post_body); s->post_body = NULL; } if (!WinHttpReceiveResponse(s->request, 0)) { giterr_set(GITERR_OS, "Failed to receive response"); return -1; } /* Verify that we got a 200 back */ status_code_length = sizeof(status_code); if (!WinHttpQueryHeaders(s->request, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, WINHTTP_HEADER_NAME_BY_INDEX, &status_code, &status_code_length, WINHTTP_NO_HEADER_INDEX)) { giterr_set(GITERR_OS, "Failed to retrieve status code"); return -1; } /* The implementation of WinHTTP prior to Windows 7 will not * redirect to an identical URI. Some Git hosters use self-redirects * as part of their DoS mitigation strategy. Check first to see if we * have a redirect status code, and that we haven't already streamed * a post body. (We can't replay a streamed POST.) */ if (!s->chunked && (HTTP_STATUS_MOVED == status_code || HTTP_STATUS_REDIRECT == status_code || (HTTP_STATUS_REDIRECT_METHOD == status_code && get_verb == s->verb) || HTTP_STATUS_REDIRECT_KEEP_VERB == status_code)) { /* Check for Windows 7. This workaround is only necessary on * Windows Vista and earlier. Windows 7 is version 6.1. */ wchar_t *location; DWORD location_length; char *location8; /* OK, fetch the Location header from the redirect. */ if (WinHttpQueryHeaders(s->request, WINHTTP_QUERY_LOCATION, WINHTTP_HEADER_NAME_BY_INDEX, WINHTTP_NO_OUTPUT_BUFFER, &location_length, WINHTTP_NO_HEADER_INDEX) || GetLastError() != ERROR_INSUFFICIENT_BUFFER) { giterr_set(GITERR_OS, "Failed to read Location header"); return -1; } location = git__malloc(location_length); GITERR_CHECK_ALLOC(location); if (!WinHttpQueryHeaders(s->request, WINHTTP_QUERY_LOCATION, WINHTTP_HEADER_NAME_BY_INDEX, location, &location_length, WINHTTP_NO_HEADER_INDEX)) { giterr_set(GITERR_OS, "Failed to read Location header"); git__free(location); return -1; } /* Convert the Location header to UTF-8 */ if (git__utf16_to_8_alloc(&location8, location) < 0) { giterr_set(GITERR_OS, "Failed to convert Location header to UTF-8"); git__free(location); return -1; } git__free(location); /* Replay the request */ winhttp_stream_close(s); if (!git__prefixcmp_icase(location8, prefix_https)) { /* Upgrade to secure connection; disconnect and start over */ if (gitno_connection_data_from_url(&t->connection_data, location8, s->service_url) < 0) { git__free(location8); return -1; } winhttp_close_connection(t); if (winhttp_connect(t) < 0) return -1; } git__free(location8); goto replay; } /* Handle authentication failures */ if (HTTP_STATUS_DENIED == status_code && get_verb == s->verb) { int allowed_types; if (parse_unauthorized_response(s->request, &allowed_types, &t->auth_mechanism) < 0) return -1; if (allowed_types && (!t->cred || 0 == (t->cred->credtype & allowed_types))) { int cred_error = 1; /* Start with the user-supplied credential callback, if present */ if (t->owner->cred_acquire_cb) { cred_error = t->owner->cred_acquire_cb(&t->cred, t->owner->url, t->connection_data.user, allowed_types, t->owner->cred_acquire_payload); if (cred_error < 0) return cred_error; } /* Invoke the fallback credentials acquisition callback if necessary */ if (cred_error > 0) { cred_error = fallback_cred_acquire_cb(&t->cred, t->owner->url, t->connection_data.user, allowed_types, NULL); if (cred_error < 0) return cred_error; } if (!cred_error) { assert(t->cred); winhttp_stream_close(s); /* Successfully acquired a credential */ goto replay; } } } if (HTTP_STATUS_OK != status_code) { giterr_set(GITERR_NET, "Request failed with status code: %d", status_code); return -1; } /* Verify that we got the correct content-type back */ if (post_verb == s->verb) p_snprintf(expected_content_type_8, MAX_CONTENT_TYPE_LEN, "application/x-git-%s-result", s->service); else p_snprintf(expected_content_type_8, MAX_CONTENT_TYPE_LEN, "application/x-git-%s-advertisement", s->service); if (git__utf8_to_16(expected_content_type, MAX_CONTENT_TYPE_LEN, expected_content_type_8) < 0) { giterr_set(GITERR_OS, "Failed to convert expected content-type to wide characters"); return -1; } content_type_length = sizeof(content_type); if (!WinHttpQueryHeaders(s->request, WINHTTP_QUERY_CONTENT_TYPE, WINHTTP_HEADER_NAME_BY_INDEX, &content_type, &content_type_length, WINHTTP_NO_HEADER_INDEX)) { giterr_set(GITERR_OS, "Failed to retrieve response content-type"); return -1; } if (wcscmp(expected_content_type, content_type)) { giterr_set(GITERR_NET, "Received unexpected content-type"); return -1; } s->received_response = 1; } if (!WinHttpReadData(s->request, (LPVOID)buffer, (DWORD)buf_size, &dw_bytes_read)) { giterr_set(GITERR_OS, "Failed to read data"); return -1; } *bytes_read = dw_bytes_read; return 0; }
static int add_ref(const char *name, git_repository *repo, git_vector *vec) { const char peeled[] = "^{}"; git_remote_head *head; git_reference *ref; git_object *obj = NULL; int error = GIT_SUCCESS, peel_len, ret; head = git__malloc(sizeof(git_remote_head)); if (head == NULL) return GIT_ENOMEM; head->name = git__strdup(name); if (head->name == NULL) { error = GIT_ENOMEM; goto out; } error = git_reference_lookup(&ref, repo, name); if (error < GIT_SUCCESS) goto out; error = git_reference_resolve(&ref, ref); if (error < GIT_SUCCESS) goto out; git_oid_cpy(&head->oid, git_reference_oid(ref)); error = git_vector_insert(vec, head); if (error < GIT_SUCCESS) goto out; /* If it's not a tag, we don't need to try to peel it */ if (git__prefixcmp(name, GIT_REFS_TAGS_DIR)) goto out; error = git_object_lookup(&obj, repo, &head->oid, GIT_OBJ_ANY); if (error < GIT_SUCCESS) { git__rethrow(error, "Failed to lookup object"); } /* If it's not an annotated tag, just get out */ if (git_object_type(obj) != GIT_OBJ_TAG) goto out; /* And if it's a tag, peel it, and add it to the list */ head = git__malloc(sizeof(git_remote_head)); peel_len = strlen(name) + strlen(peeled); head->name = git__malloc(peel_len + 1); ret = p_snprintf(head->name, peel_len + 1, "%s%s", name, peeled); if (ret >= peel_len + 1) { error = git__throw(GIT_ERROR, "The string is magically to long"); } git_oid_cpy(&head->oid, git_tag_target_oid((git_tag *) obj)); error = git_vector_insert(vec, head); if (error < GIT_SUCCESS) goto out; out: git_object_close(obj); if (error < GIT_SUCCESS) { free(head->name); free(head); } return error; }
void test_refs_normalize__jgit_suite(void) { /* tests borrowed from JGit */ /* EmptyString */ ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, ""); ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "/"); /* MustHaveTwoComponents */ ensure_refname_invalid( GIT_REFERENCE_FORMAT_NORMAL, "master"); ensure_refname_normalized( GIT_REFERENCE_FORMAT_NORMAL, "heads/master", "heads/master"); /* ValidHead */ ensure_refname_normalized( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/master", "refs/heads/master"); ensure_refname_normalized( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/pu", "refs/heads/pu"); ensure_refname_normalized( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/z", "refs/heads/z"); ensure_refname_normalized( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/FoO", "refs/heads/FoO"); /* ValidTag */ ensure_refname_normalized( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/tags/v1.0", "refs/tags/v1.0"); /* NoLockSuffix */ ensure_refname_invalid(GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/master.lock"); /* NoDirectorySuffix */ ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/master/"); /* NoSpace */ ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/i haz space"); /* NoAsciiControlCharacters */ { char c; char buffer[GIT_REFNAME_MAX]; for (c = '\1'; c < ' '; c++) { p_snprintf(buffer, sizeof(buffer), "refs/heads/mast%cer", c); ensure_refname_invalid(GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, buffer); } } /* NoBareDot */ ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/."); ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/.."); ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/./master"); ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/../master"); /* NoLeadingOrTrailingDot */ ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "."); ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/.bar"); ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/..bar"); ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/bar."); /* ContainsDot */ ensure_refname_normalized( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/m.a.s.t.e.r", "refs/heads/m.a.s.t.e.r"); ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/master..pu"); /* NoMagicRefCharacters */ ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/master^"); ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/^master"); ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "^refs/heads/master"); ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/master~"); ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/~master"); ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "~refs/heads/master"); ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/master:"); ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/:master"); ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, ":refs/heads/master"); /* ShellGlob */ ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/master?"); ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/?master"); ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "?refs/heads/master"); ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/master["); ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/[master"); ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "[refs/heads/master"); ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/master*"); ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/*master"); ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "*refs/heads/master"); /* ValidSpecialCharacters */ ensure_refname_normalized (GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/!", "refs/heads/!"); ensure_refname_normalized( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/\"", "refs/heads/\""); ensure_refname_normalized( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/#", "refs/heads/#"); ensure_refname_normalized( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/$", "refs/heads/$"); ensure_refname_normalized( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/%", "refs/heads/%"); ensure_refname_normalized( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/&", "refs/heads/&"); ensure_refname_normalized( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/'", "refs/heads/'"); ensure_refname_normalized( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/(", "refs/heads/("); ensure_refname_normalized( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/)", "refs/heads/)"); ensure_refname_normalized( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/+", "refs/heads/+"); ensure_refname_normalized( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/,", "refs/heads/,"); ensure_refname_normalized( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/-", "refs/heads/-"); ensure_refname_normalized( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/;", "refs/heads/;"); ensure_refname_normalized( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/<", "refs/heads/<"); ensure_refname_normalized( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/=", "refs/heads/="); ensure_refname_normalized( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/>", "refs/heads/>"); ensure_refname_normalized( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/@", "refs/heads/@"); ensure_refname_normalized( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/]", "refs/heads/]"); ensure_refname_normalized( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/_", "refs/heads/_"); ensure_refname_normalized( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/`", "refs/heads/`"); ensure_refname_normalized( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/{", "refs/heads/{"); ensure_refname_normalized( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/|", "refs/heads/|"); ensure_refname_normalized( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/}", "refs/heads/}"); /* * This is valid on UNIX, but not on Windows * hence we make in invalid due to non-portability */ ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/\\"); /* UnicodeNames */ /* * Currently this fails. * ensure_refname_normalized(GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/\u00e5ngstr\u00f6m", "refs/heads/\u00e5ngstr\u00f6m"); */ /* RefLogQueryIsValidRef */ ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/master@{1}"); ensure_refname_invalid( GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL, "refs/heads/master@{1.hour.ago}"); }
void test_threads_refdb__edit_while_iterate(void) { int r, t; int id[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; } id[t] = t; /* It appears with all reflog writing changes, etc., that this * test has started to fail quite frequently, so let's disable it * for now by just running on a single thread... */ /* #ifdef GIT_THREADS */ /* cl_git_pass(git_thread_create(&th[t], fn, &id[t])); */ /* #else */ fn(&id[t]); /* #endif */ } #ifdef GIT_THREADS /* for (t = 0; t < THREADS; ++t) { */ /* cl_git_pass(git_thread_join(th[t], NULL)); */ /* } */ memset(th, 0, sizeof(th)); for (t = 0; t < THREADS; ++t) { id[t] = t; cl_git_pass(git_thread_create(&th[t], iterate_refs, &id[t])); } for (t = 0; t < THREADS; ++t) { cl_git_pass(git_thread_join(&th[t], NULL)); } #endif }
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 }
int git_config_set_int64(git_config *cfg, const char *name, int64_t value) { char str_value[32]; /* All numbers should fit in here */ p_snprintf(str_value, sizeof(str_value), "%" PRId64, value); return git_config_set_string(cfg, name, str_value); }