Exemple #1
0
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);
}
Exemple #2
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;
}
Exemple #3
0
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;
}
Exemple #4
0
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
}
Exemple #5
0
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);
}
Exemple #6
0
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;
}
Exemple #7
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);
}
Exemple #8
0
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);
}
Exemple #9
0
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;
}
Exemple #10
0
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);
}
Exemple #11
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;
}
Exemple #12
0
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;
}