int git_win32__find_system_dirs(git_buf *out, const wchar_t *subdir) { git_buf buf = GIT_BUF_INIT; /* directories where git.exe & git.cmd are found */ if (!win32_find_git_in_path(&buf, L"git.exe", subdir) && buf.size) git_buf_set(out, buf.ptr, buf.size); else git_buf_clear(out); if (!win32_find_git_in_path(&buf, L"git.cmd", subdir) && buf.size) git_buf_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr); /* directories where git is installed according to registry */ if (!win32_find_git_in_registry( &buf, HKEY_CURRENT_USER, REG_MSYSGIT_INSTALL_LOCAL, subdir) && buf.size) git_buf_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr); if (!win32_find_git_in_registry( &buf, HKEY_LOCAL_MACHINE, REG_MSYSGIT_INSTALL, subdir) && buf.size) git_buf_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr); git_buf_free(&buf); return (git_buf_oom(out) ? -1 : 0); }
int git_branch_move( git_reference **out, git_reference *branch, const char *new_branch_name, int force) { git_buf new_reference_name = GIT_BUF_INIT, old_config_section = GIT_BUF_INIT, new_config_section = GIT_BUF_INIT, log_message = GIT_BUF_INIT; int error; assert(branch && new_branch_name); if (!git_reference_is_branch(branch)) return not_a_local_branch(git_reference_name(branch)); if ((error = git_buf_joinpath(&new_reference_name, GIT_REFS_HEADS_DIR, new_branch_name)) < 0) goto done; if ((error = git_buf_printf(&log_message, "branch: renamed %s to %s", git_reference_name(branch), git_buf_cstr(&new_reference_name))) < 0) goto done; /* first update ref then config so failure won't trash config */ error = git_reference_rename( out, branch, git_buf_cstr(&new_reference_name), force, git_buf_cstr(&log_message)); if (error < 0) goto done; git_buf_join(&old_config_section, '.', "branch", git_reference_name(branch) + strlen(GIT_REFS_HEADS_DIR)); git_buf_join(&new_config_section, '.', "branch", new_branch_name); error = git_config_rename_section( git_reference_owner(branch), git_buf_cstr(&old_config_section), git_buf_cstr(&new_config_section)); done: git_buf_free(&new_reference_name); git_buf_free(&old_config_section); git_buf_free(&new_config_section); git_buf_free(&log_message); return error; }
static char *get_filename(const char *in) { char *search_dirname, *search_filename, *filename = NULL; git_buf out = GIT_BUF_INIT; DIR *dir; struct dirent *de; cl_assert(search_dirname = git_path_dirname(in)); cl_assert(search_filename = git_path_basename(in)); cl_assert(dir = opendir(search_dirname)); while ((de = readdir(dir))) { if (strcasecmp(de->d_name, search_filename) == 0) { git_buf_join(&out, '/', search_dirname, de->d_name); filename = git_buf_detach(&out); break; } } closedir(dir); git__free(search_dirname); git__free(search_filename); git_buf_dispose(&out); return filename; }
static char *get_filename(const char *in) { #ifdef GIT_WIN32 HANDLE fh; HMODULE kerneldll; char *filename; typedef DWORD (__stdcall *getfinalpathname)(HANDLE, LPSTR, DWORD, DWORD); getfinalpathname getfinalpathfn; cl_assert(filename = malloc(MAX_PATH)); cl_assert(kerneldll = LoadLibrary("kernel32.dll")); cl_assert(getfinalpathfn = (getfinalpathname)GetProcAddress(kerneldll, "GetFinalPathNameByHandleA")); cl_assert(fh = CreateFileA(in, FILE_READ_ATTRIBUTES | STANDARD_RIGHTS_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL)); cl_win32_pass(getfinalpathfn(fh, filename, MAX_PATH, VOLUME_NAME_DOS)); CloseHandle(fh); git_path_mkposix(filename); return filename; #else char *search_dirname, *search_filename, *filename = NULL; git_buf out = GIT_BUF_INIT; DIR *dir; struct dirent *de; cl_assert(search_dirname = git_path_dirname(in)); cl_assert(search_filename = git_path_basename(in)); cl_assert(dir = opendir(search_dirname)); while ((de = readdir(dir))) { if (strcasecmp(de->d_name, search_filename) == 0) { git_buf_join(&out, '/', search_dirname, de->d_name); filename = git_buf_detach(&out); break; } } closedir(dir); git__free(search_dirname); git__free(search_filename); git_buf_free(&out); return filename; #endif }
static void check_joinbuf_2( const char *a, const char *b, const char *expected) { char sep = '/'; git_buf buf = GIT_BUF_INIT; git_buf_join(&buf, sep, a, b); cl_assert(git_buf_oom(&buf) == 0); cl_assert_equal_s(expected, git_buf_cstr(&buf)); git_buf_free(&buf); }
int git_futils_dirs_set(git_futils_dir_t which, const char *search_path) { const char *expand_path = NULL; git_buf merge = GIT_BUF_INIT; GITERR_CHECK_ERROR(git_futils_check_selector(which)); if (search_path != NULL) expand_path = strstr(search_path, PATH_MAGIC); /* init with default if not yet done and needed (ignoring error) */ if ((!search_path || expand_path) && !git_buf_len(&git_futils__dirs[which])) git_futils__dir_guess[which](&git_futils__dirs[which]); /* if $PATH is not referenced, then just set the path */ if (!expand_path) return git_buf_sets(&git_futils__dirs[which], search_path); /* otherwise set to join(before $PATH, old value, after $PATH) */ if (expand_path > search_path) git_buf_set(&merge, search_path, expand_path - search_path); if (git_buf_len(&git_futils__dirs[which])) git_buf_join(&merge, GIT_PATH_LIST_SEPARATOR, merge.ptr, git_futils__dirs[which].ptr); expand_path += strlen(PATH_MAGIC); if (*expand_path) git_buf_join(&merge, GIT_PATH_LIST_SEPARATOR, merge.ptr, expand_path); git_buf_swap(&git_futils__dirs[which], &merge); git_buf_free(&merge); return git_buf_oom(&git_futils__dirs[which]) ? -1 : 0; }
static void check_joinbuf_overlapped( const char *oldval, int ofs_a, const char *b, const char *expected) { char sep = '/'; git_buf buf = GIT_BUF_INIT; git_buf_sets(&buf, oldval); git_buf_join(&buf, sep, buf.ptr + ofs_a, b); cl_assert(git_buf_oom(&buf) == 0); cl_assert_equal_s(expected, git_buf_cstr(&buf)); git_buf_free(&buf); }
void test_core_buffer__9(void) { git_buf buf = GIT_BUF_INIT; /* just some exhaustive tests of various separator placement */ char *a[] = { "", "-", "a-", "-a", "-a-" }; char *b[] = { "", "-", "b-", "-b", "-b-" }; char sep[] = { 0, '-', '/' }; char *expect_null[] = { "", "-", "a-", "-a", "-a-", "-", "--", "a--", "-a-", "-a--", "b-", "-b-", "a-b-", "-ab-", "-a-b-", "-b", "--b", "a--b", "-a-b", "-a--b", "-b-", "--b-", "a--b-", "-a-b-", "-a--b-" }; char *expect_dash[] = { "", "-", "a-", "-a-", "-a-", "-", "-", "a-", "-a-", "-a-", "b-", "-b-", "a-b-", "-a-b-", "-a-b-", "-b", "-b", "a-b", "-a-b", "-a-b", "-b-", "-b-", "a-b-", "-a-b-", "-a-b-" }; char *expect_slas[] = { "", "-/", "a-/", "-a/", "-a-/", "-", "-/-", "a-/-", "-a/-", "-a-/-", "b-", "-/b-", "a-/b-", "-a/b-", "-a-/b-", "-b", "-/-b", "a-/-b", "-a/-b", "-a-/-b", "-b-", "-/-b-", "a-/-b-", "-a/-b-", "-a-/-b-" }; char **expect_values[] = { expect_null, expect_dash, expect_slas }; char separator, **expect; unsigned int s, i, j; for (s = 0; s < sizeof(sep) / sizeof(char); ++s) { separator = sep[s]; expect = expect_values[s]; for (j = 0; j < sizeof(b) / sizeof(char*); ++j) { for (i = 0; i < sizeof(a) / sizeof(char*); ++i) { git_buf_join(&buf, separator, a[i], b[j]); cl_assert_equal_s(*expect, buf.ptr); expect++; } } } git_buf_free(&buf); }
int git_branch_delete(git_reference *branch) { int is_head; git_buf config_section = GIT_BUF_INIT; int error = -1; assert(branch); if (!git_reference_is_branch(branch) && !git_reference_is_remote(branch)) { giterr_set(GITERR_INVALID, "Reference '%s' is not a valid branch.", git_reference_name(branch)); return GIT_ENOTFOUND; } if ((is_head = git_branch_is_head(branch)) < 0) return is_head; if (is_head) { giterr_set(GITERR_REFERENCE, "Cannot delete branch '%s' as it is " "the current HEAD of the repository.", git_reference_name(branch)); return -1; } if (git_buf_join(&config_section, '.', "branch", git_reference_name(branch) + strlen(GIT_REFS_HEADS_DIR)) < 0) goto on_error; if (git_config_rename_section( git_reference_owner(branch), git_buf_cstr(&config_section), NULL) < 0) goto on_error; error = git_reference_delete(branch); on_error: git_buf_free(&config_section); return error; }
static int win32_find_existing_dirs( git_buf *out, const wchar_t *tmpl[]) { _findfile_path path16; git_buf buf = GIT_BUF_INIT; git_buf_clear(out); for (; *tmpl != NULL; tmpl++) { if (!git_win32__expand_path(&path16, *tmpl) && path16.path[0] != L'%' && !_waccess(path16.path, F_OK)) { win32_path_to_8(&buf, path16.path); if (buf.size) git_buf_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr); } } git_buf_free(&buf); return (git_buf_oom(out) ? -1 : 0); }
static int fetchhead_ref_parse( git_oid *oid, unsigned int *is_merge, git_buf *ref_name, const char **remote_url, char *line, size_t line_num) { char *oid_str, *is_merge_str, *desc, *name = NULL; const char *type = NULL; int error = 0; *remote_url = NULL; if (!*line) { giterr_set(GITERR_FETCHHEAD, "Empty line in FETCH_HEAD line %"PRIuZ, line_num); return -1; } /* Compat with old git clients that wrote FETCH_HEAD like a loose ref. */ if ((oid_str = git__strsep(&line, "\t")) == NULL) { oid_str = line; line += strlen(line); *is_merge = 1; } if (strlen(oid_str) != GIT_OID_HEXSZ) { giterr_set(GITERR_FETCHHEAD, "Invalid object ID in FETCH_HEAD line %"PRIuZ, line_num); return -1; } if (git_oid_fromstr(oid, oid_str) < 0) { const git_error *oid_err = giterr_last(); const char *err_msg = oid_err ? oid_err->message : "Invalid object ID"; giterr_set(GITERR_FETCHHEAD, "%s in FETCH_HEAD line %"PRIuZ, err_msg, line_num); return -1; } /* Parse new data from newer git clients */ if (*line) { if ((is_merge_str = git__strsep(&line, "\t")) == NULL) { giterr_set(GITERR_FETCHHEAD, "Invalid description data in FETCH_HEAD line %"PRIuZ, line_num); return -1; } if (*is_merge_str == '\0') *is_merge = 1; else if (strcmp(is_merge_str, "not-for-merge") == 0) *is_merge = 0; else { giterr_set(GITERR_FETCHHEAD, "Invalid for-merge entry in FETCH_HEAD line %"PRIuZ, line_num); return -1; } if ((desc = line) == NULL) { giterr_set(GITERR_FETCHHEAD, "Invalid description in FETCH_HEAD line %"PRIuZ, line_num); return -1; } if (git__prefixcmp(desc, "branch '") == 0) { type = GIT_REFS_HEADS_DIR; name = desc + 8; } else if (git__prefixcmp(desc, "tag '") == 0) { type = GIT_REFS_TAGS_DIR; name = desc + 5; } else if (git__prefixcmp(desc, "'") == 0) name = desc + 1; if (name) { if ((desc = strstr(name, "' ")) == NULL || git__prefixcmp(desc, "' of ") != 0) { giterr_set(GITERR_FETCHHEAD, "Invalid description in FETCH_HEAD line %"PRIuZ, line_num); return -1; } *desc = '\0'; desc += 5; } *remote_url = desc; } git_buf_clear(ref_name); if (type) git_buf_join(ref_name, '/', type, name); else if(name) git_buf_puts(ref_name, name); return error; }
static int filter_apply( git_filter *self, void **payload, /* may be read and/or set */ git_buf *to, const git_buf *from, const git_filter_source *src) { struct filter_filter *ffs = (struct filter_filter *)self; git_config *config; git_buf configKey = GIT_BUF_INIT; int isRequired = FALSE; int error; const char *cmd = NULL; git_buf cmdBuf = GIT_BUF_INIT; wchar_t *wide_cmd; COMMAND_HANDLE commandHandle = COMMAND_HANDLE_INIT; git_buf errBuf = GIT_BUF_INIT; DWORD exitCode; if (!*payload) return GIT_PASSTHROUGH; if (git_repository_config__weakptr(&config, git_filter_source_repo(src))) return -1; git_buf_join3(&configKey, '.', "filter", *payload, "required"); if (git_buf_oom(&configKey)) { giterr_set_oom(); return -1; } error = git_config_get_bool(&isRequired, config, configKey.ptr); git_buf_free(&configKey); if (error && error != GIT_ENOTFOUND) return -1; git_buf_join(&configKey, '.', "filter", *payload); if (git_filter_source_mode(src) == GIT_FILTER_SMUDGE) { git_buf_puts(&configKey, ".smudge"); } else { git_buf_puts(&configKey, ".clean"); } if (git_buf_oom(&configKey)) { giterr_set_oom(); return -1; } error = git_config_get_string(&cmd, config, configKey.ptr); git_buf_free(&configKey); if (error && error != GIT_ENOTFOUND) return -1; if (error == GIT_ENOTFOUND) { if (isRequired) return -1; return GIT_PASSTHROUGH; } git_buf_puts(&cmdBuf, cmd); if (git_buf_oom(&cmdBuf)) { giterr_set_oom(); return -1; } if (expandPerCentF(&cmdBuf, git_filter_source_path(src))) return -1; if (ffs->shexepath) { // build params for sh.exe git_buf shParams = GIT_BUF_INIT; git_buf_puts(&shParams, " -c \""); git_buf_text_puts_escaped(&shParams, cmdBuf.ptr, "\"\\", "\\"); git_buf_puts(&shParams, "\""); if (git_buf_oom(&shParams)) { git_buf_free(&cmdBuf); giterr_set_oom(); return -1; } git_buf_swap(&shParams, &cmdBuf); git_buf_free(&shParams); } if (git__utf8_to_16_alloc(&wide_cmd, cmdBuf.ptr) < 0) { git_buf_free(&cmdBuf); giterr_set_oom(); return -1; } git_buf_free(&cmdBuf); if (ffs->shexepath) { // build cmd, i.e. shexepath + params size_t len = wcslen(ffs->shexepath) + wcslen(wide_cmd) + 1; wchar_t *tmp = git__calloc(len, sizeof(wchar_t)); if (!tmp) { git__free(wide_cmd); giterr_set_oom(); return -1; } wcscat_s(tmp, len, ffs->shexepath); wcscat_s(tmp, len, wide_cmd); git__free(wide_cmd); wide_cmd = tmp; } commandHandle.errBuf = &errBuf; if (command_start(wide_cmd, &commandHandle, ffs->pEnv)) { git__free(wide_cmd); if (isRequired) return -1; return GIT_PASSTHROUGH; } git__free(wide_cmd); if (commmand_start_stdout_reading_thread(&commandHandle, to)) { command_close(&commandHandle); return -1; } if (command_write_gitbuf(&commandHandle, from)) { DWORD exitCode = command_close(&commandHandle); if (exitCode) setProcessError(exitCode, &errBuf); git_buf_free(&errBuf); if (isRequired) return -1; return GIT_PASSTHROUGH; } command_close_stdin(&commandHandle); if (command_wait_stdout_reading_thread(&commandHandle)) { DWORD exitCode = command_close(&commandHandle); if (exitCode) setProcessError(exitCode, &errBuf); git_buf_free(&errBuf); if (isRequired) return -1; return GIT_PASSTHROUGH; } exitCode = command_close(&commandHandle); if (exitCode) { if (isRequired) { setProcessError(exitCode, &errBuf); git_buf_free(&errBuf); return -1; } git_buf_free(&errBuf); return GIT_PASSTHROUGH; } git_buf_free(&errBuf); return 0; }
static int add_ref(transport_local *t, const char *name) { const char peeled[] = "^{}"; git_remote_head *head; git_object *obj = NULL, *target = NULL; git_transport *transport = (git_transport *) t; git_buf buf = GIT_BUF_INIT; git_pkt_ref *pkt; head = git__malloc(sizeof(git_remote_head)); GITERR_CHECK_ALLOC(head); pkt = git__malloc(sizeof(git_pkt_ref)); GITERR_CHECK_ALLOC(pkt); head->name = git__strdup(name); GITERR_CHECK_ALLOC(head->name); if (git_reference_name_to_oid(&head->oid, t->repo, name) < 0) { git__free(head); git__free(pkt->head.name); git__free(pkt); } pkt->type = GIT_PKT_REF; memcpy(&pkt->head, head, sizeof(git_remote_head)); git__free(head); if (git_vector_insert(&transport->refs, pkt) < 0) { git__free(pkt->head.name); git__free(pkt); return -1; } /* If it's not a tag, we don't need to try to peel it */ if (git__prefixcmp(name, GIT_REFS_TAGS_DIR)) return 0; if (git_object_lookup(&obj, t->repo, &pkt->head.oid, GIT_OBJ_ANY) < 0) return -1; head = NULL; /* If it's not an annotated tag, just get out */ if (git_object_type(obj) != GIT_OBJ_TAG) { git_object_free(obj); return 0; } /* And if it's a tag, peel it, and add it to the list */ head = git__malloc(sizeof(git_remote_head)); GITERR_CHECK_ALLOC(head); if (git_buf_join(&buf, 0, name, peeled) < 0) return -1; head->name = git_buf_detach(&buf); pkt = git__malloc(sizeof(git_pkt_ref)); GITERR_CHECK_ALLOC(pkt); pkt->type = GIT_PKT_REF; if (git_tag_peel(&target, (git_tag *) obj) < 0) goto on_error; git_oid_cpy(&head->oid, git_object_id(target)); git_object_free(obj); git_object_free(target); memcpy(&pkt->head, head, sizeof(git_remote_head)); git__free(head); if (git_vector_insert(&transport->refs, pkt) < 0) return -1; return 0; on_error: git_object_free(obj); git_object_free(target); return -1; }