コード例 #1
0
ファイル: smart_pkt.c プロジェクト: 0CV0/libgit2
static int buffer_want_with_caps(const git_remote_head *head, transport_smart_caps *caps, git_buf *buf)
{
	git_buf str = GIT_BUF_INIT;
	char oid[GIT_OID_HEXSZ +1] = {0};
	unsigned int len;

	/* Prefer side-band-64k if the server supports both */
	if (caps->side_band) {
		if (caps->side_band_64k)
			git_buf_printf(&str, "%s ", GIT_CAP_SIDE_BAND_64K);
		else
			git_buf_printf(&str, "%s ", GIT_CAP_SIDE_BAND);
	}
	if (caps->ofs_delta)
		git_buf_puts(&str, GIT_CAP_OFS_DELTA " ");

	if (caps->multi_ack)
		git_buf_puts(&str, GIT_CAP_MULTI_ACK " ");

	if (caps->include_tag)
		git_buf_puts(&str, GIT_CAP_INCLUDE_TAG " ");

	if (git_buf_oom(&str))
		return -1;

	len = (unsigned int)
		(strlen("XXXXwant ") + GIT_OID_HEXSZ + 1 /* NUL */ +
		 git_buf_len(&str) + 1 /* LF */);
	git_buf_grow(buf, git_buf_len(buf) + len);
	git_oid_fmt(oid, &head->oid);
	git_buf_printf(buf, "%04xwant %s %s\n", len, oid, git_buf_cstr(&str));
	git_buf_free(&str);

	return git_buf_oom(buf);
}
コード例 #2
0
static int buffer_want_with_caps(git_remote_head *head, git_transport_caps *caps, git_buf *buf)
{
	git_buf str = GIT_BUF_INIT;
	char oid[GIT_OID_HEXSZ +1] = {0};
	unsigned int len;

	if (caps->ofs_delta)
		git_buf_puts(&str, GIT_CAP_OFS_DELTA " ");

	if (caps->multi_ack)
		git_buf_puts(&str, GIT_CAP_MULTI_ACK " ");

	if (git_buf_oom(&str))
		return -1;

	len = (unsigned int)
		(strlen("XXXXwant ") + GIT_OID_HEXSZ + 1 /* NUL */ +
		 git_buf_len(&str) + 1 /* LF */);
	git_buf_grow(buf, git_buf_len(buf) + len);
	git_oid_fmt(oid, &head->oid);
	git_buf_printf(buf, "%04xwant %s %s\n", len, oid, git_buf_cstr(&str));
	git_buf_free(&str);

	return git_buf_oom(buf);
}
コード例 #3
0
ファイル: http.c プロジェクト: ileitch/meanie
static int on_body_parse_response(http_parser *parser, const char *str, size_t len)
{
	transport_http *t = (transport_http *) parser->data;
	git_buf *buf = &t->buf;
	git_vector *common = &t->common;
	int error;
	const char *line_end, *ptr;

	if (len == 0) { /* EOF */
		if (git_buf_len(buf) != 0) {
			giterr_set(GITERR_NET, "Unexpected EOF");
			return t->error = -1;
		} else {
			return 0;
		}
	}

	git_buf_put(buf, str, len);
	ptr = buf->ptr;
	while (1) {
		git_pkt *pkt;

		if (git_buf_len(buf) == 0)
			return 0;

		error = git_pkt_parse_line(&pkt, ptr, &line_end, git_buf_len(buf));
		if (error == GIT_EBUFS) {
			return 0; /* Ask for more */
		}
		if (error < 0)
			return t->error = -1;

		git_buf_consume(buf, line_end);

		if (pkt->type == GIT_PKT_PACK) {
			git__free(pkt);
			t->pack_ready = 1;
			return 0;
		}

		if (pkt->type == GIT_PKT_NAK) {
			git__free(pkt);
			return 0;
		}

		if (pkt->type != GIT_PKT_ACK) {
			git__free(pkt);
			continue;
		}

		if (git_vector_insert(common, pkt) < 0)
			return -1;
	}

	return error;

}
コード例 #4
0
int git_path_to_dir(git_buf *path)
{
	if (path->asize > 0 &&
		git_buf_len(path) > 0 &&
		path->ptr[git_buf_len(path) - 1] != '/')
		git_buf_putc(path, '/');

	return git_buf_oom(path) ? -1 : 0;
}
コード例 #5
0
int dircount(void *payload, git_buf *pathbuf)
{
	int *entries = payload;
	size_t len = git_buf_len(pathbuf);

	if (len < 5 || strcmp(pathbuf->ptr + (git_buf_len(pathbuf) - 5), "/.git") != 0)
		(*entries)++;

	return 0;
}
コード例 #6
0
ファイル: git2r_cred.c プロジェクト: krlmlr/git2r
/**
 * Create credential object from S4 class 'cred_env'.
 *
 * @param cred The newly created credential object.
 * @param allowed_types A bitmask stating which cred types are OK to return.
 * @param credentials The S4 class object with credentials.
 * @return 0 on success, else -1.
 */
static int git2r_cred_env(
    git_cred **cred,
    unsigned int allowed_types,
    SEXP credentials)
{
    if (GIT_CREDTYPE_USERPASS_PLAINTEXT & allowed_types) {
        int err;
        git_buf username = GIT_BUF_INIT;
        git_buf password = GIT_BUF_INIT;

        /* Read value of the username environment variable */
        err = git__getenv(&username,
                          CHAR(STRING_ELT(
                                   GET_SLOT(credentials,
                                            Rf_install("username")), 0)));
        if (err)
            goto cleanup;

        if (!git_buf_len(&username)) {
            err = -1;
            goto cleanup;
        }

        /* Read value of the password environment variable */
        err = git__getenv(&password,
                          CHAR(STRING_ELT(
                                   GET_SLOT(credentials,
                                            Rf_install("password")), 0)));
        if (err)
            goto cleanup;

        if (!git_buf_len(&password)) {
            err = -1;
            goto cleanup;
        }

        err = git_cred_userpass_plaintext_new(
            cred,
            git_buf_cstr(&username),
            git_buf_cstr(&password));

    cleanup:
        git_buf_free(&username);
        git_buf_free(&password);

        if (err)
            return -1;

        return 0;
    }

    return -1;
}
コード例 #7
0
ファイル: path.c プロジェクト: b-k-schneider/sonic-pi
int git_path_walk_up(
	git_buf *path,
	const char *ceiling,
	int (*cb)(void *data, git_buf *),
	void *data)
{
	int error = 0;
	git_buf iter;
	ssize_t stop = 0, scan;
	char oldc = '\0';

	assert(path && cb);

	if (ceiling != NULL) {
		if (git__prefixcmp(path->ptr, ceiling) == 0)
			stop = (ssize_t)strlen(ceiling);
		else
			stop = git_buf_len(path);
	}
	scan = git_buf_len(path);

	iter.ptr = path->ptr;
	iter.size = git_buf_len(path);
	iter.asize = path->asize;

	while (scan >= stop) {
		error = cb(data, &iter);
		iter.ptr[scan] = oldc;

		if (error) {
			giterr_set_after_callback(error);
			break;
		}

		scan = git_buf_rfind_next(&iter, '/');
		if (scan >= 0) {
			scan++;
			oldc = iter.ptr[scan];
			iter.size = scan;
			iter.ptr[scan] = '\0';
		}
	}

	if (scan >= 0)
		iter.ptr[scan] = oldc;

	return error;
}
コード例 #8
0
static int buffer_to_file(
	git_buf *buffer,
	const char *path,
	mode_t dir_mode,
	int file_open_flags,
	mode_t file_mode)
{
	int fd, error, error_close;

	if ((error = git_futils_mkpath2file(path, dir_mode)) < 0)
		return error;

	if ((fd = p_open(path, file_open_flags, file_mode)) < 0)
		return fd;

	error = p_write(fd, git_buf_cstr(buffer), git_buf_len(buffer));

	error_close = p_close(fd);

	if (!error)
		error = error_close;

	if (!error &&
		(file_mode & 0100) != 0 &&
		(error = p_chmod(path, file_mode)) < 0)
		giterr_set(GITERR_OS, "Failed to set permissions on '%s'", path);

	return error;
}
コード例 #9
0
ファイル: stash.c プロジェクト: aep/libgit2
static int prepare_worktree_commit_message(
	git_buf* msg,
	const char *user_message)
{
	git_buf buf = GIT_BUF_INIT;
	int error;

	if ((error = git_buf_set(&buf, git_buf_cstr(msg), git_buf_len(msg))) < 0)
		return error;

	git_buf_clear(msg);

	if (!user_message)
		git_buf_printf(msg, "WIP on %s", git_buf_cstr(&buf));
	else {
		const char *colon;

		if ((colon = strchr(git_buf_cstr(&buf), ':')) == NULL)
			goto cleanup;

		git_buf_puts(msg, "On ");
		git_buf_put(msg, git_buf_cstr(&buf), colon - buf.ptr);
		git_buf_printf(msg, ": %s\n", user_message);
	}

	error = (git_buf_oom(msg) || git_buf_oom(&buf)) ? -1 : 0;

cleanup:
	git_buf_free(&buf);

	return error;
}
コード例 #10
0
ファイル: diff_print.c プロジェクト: 0CV0/libgit2
static int diff_print_patch_line(
	const git_diff_delta *delta,
	const git_diff_range *range,
	char line_origin, /* GIT_DIFF_LINE value from above */
	const char *content,
	size_t content_len,
	void *data)
{
	diff_print_info *pi = data;

	if (S_ISDIR(delta->new_file.mode))
		return 0;

	git_buf_clear(pi->buf);

	if (line_origin == GIT_DIFF_LINE_ADDITION ||
		line_origin == GIT_DIFF_LINE_DELETION ||
		line_origin == GIT_DIFF_LINE_CONTEXT)
		git_buf_printf(pi->buf, "%c%.*s", line_origin, (int)content_len, content);
	else if (content_len > 0)
		git_buf_printf(pi->buf, "%.*s", (int)content_len, content);

	if (git_buf_oom(pi->buf))
		return -1;

	if (pi->print_cb(delta, range, line_origin,
			git_buf_cstr(pi->buf), git_buf_len(pi->buf), pi->payload))
		return callback_error();

	return 0;
}
コード例 #11
0
ファイル: fileops.c プロジェクト: 0CV0/libgit2
static int futils__rmdir_empty_parent(void *opaque, git_buf *path)
{
	futils__rmdir_data *data = opaque;
	int error;

	if (git_buf_len(path) <= data->baselen)
		return GIT_ITEROVER;

	error = p_rmdir(git_buf_cstr(path));

	if (error) {
		int en = errno;

		if (en == ENOENT || en == ENOTDIR) {
			giterr_clear();
			error = 0;
		} else if (en == ENOTEMPTY || en == EEXIST || en == EBUSY) {
			giterr_clear();
			error = GIT_ITEROVER;
		} else {
			futils__error_cannot_rmdir(git_buf_cstr(path), NULL);
		}
	}

	return error;
}
コード例 #12
0
ファイル: clar_libgit2.c プロジェクト: ethomson/libgit2
const char *cl_git_sandbox_path(int is_dir, ...)
{
	const char *path = NULL;
	static char _temp[GIT_PATH_MAX];
	git_buf buf = GIT_BUF_INIT;
	va_list arg;

	cl_git_pass(git_buf_sets(&buf, clar_sandbox_path()));

	va_start(arg, is_dir);

	while ((path = va_arg(arg, const char *)) != NULL) {
		cl_git_pass(git_buf_joinpath(&buf, buf.ptr, path));
	}
	va_end(arg);

	cl_git_pass(git_path_prettify(&buf, buf.ptr, NULL));
	if (is_dir)
		git_path_to_dir(&buf);

	/* make sure we won't truncate */
	cl_assert(git_buf_len(&buf) < sizeof(_temp));
	git_buf_copy_cstr(_temp, sizeof(_temp), &buf);

	git_buf_dispose(&buf);

	return _temp;
}
コード例 #13
0
/*
 * Read the contents of `file_path` and set `path_out` to the repo dir that
 * it points to.  Before calling, set `path_out` to the base directory that
 * should be used if the contents of `file_path` are a relative path.
 */
static int read_gitfile(git_buf *path_out, const char *file_path)
{
	int     error = 0;
	git_buf file = GIT_BUF_INIT;
	size_t  prefix_len = strlen(GIT_FILE_CONTENT_PREFIX);

	assert(path_out && file_path);

	if (git_futils_readbuffer(&file, file_path) < 0)
		return -1;

	git_buf_rtrim(&file);
	/* apparently on Windows, some people use backslashes in paths */
	git_path_mkposix(file.ptr);

	if (git_buf_len(&file) <= prefix_len ||
		memcmp(git_buf_cstr(&file), GIT_FILE_CONTENT_PREFIX, prefix_len) != 0)
	{
		giterr_set(GITERR_REPOSITORY,
			"The `.git` file at '%s' is malformed", file_path);
		error = -1;
	}
	else if ((error = git_path_dirname_r(path_out, file_path)) >= 0) {
		const char *gitlink = git_buf_cstr(&file) + prefix_len;
		while (*gitlink && git__isspace(*gitlink)) gitlink++;

		error = git_path_prettify_dir(
			path_out, gitlink, git_buf_cstr(path_out));
	}

	git_buf_free(&file);
	return error;
}
コード例 #14
0
ファイル: odb_pack.c プロジェクト: Darthholi/WDX_GitCommander
static int packfile_load__cb(void *data, git_buf *path)
{
	struct pack_backend *backend = (pack_backend*) data;
	struct git_pack_file *pack;
	const char *path_str = git_buf_cstr(path);
	size_t i, cmp_len = git_buf_len(path);
	int error;

	if (cmp_len <= strlen(".idx") || git__suffixcmp(path_str, ".idx") != 0)
		return 0; /* not an index */

	cmp_len -= strlen(".idx");

	for (i = 0; i < backend->packs.length; ++i) {
		struct git_pack_file *p = (git_pack_file*) git_vector_get(&backend->packs, i);

		if (memcmp(p->pack_name, path_str, cmp_len) == 0)
			return 0;
	}

	error = git_mwindow_get_pack(&pack, path->ptr);

	/* ignore missing .pack file as git does */
	if (error == GIT_ENOTFOUND) {
		giterr_clear();
		return 0;
	}

	if (!error)
		error = git_vector_insert(&backend->packs, pack);

	return error;

}
コード例 #15
0
static bool _check_dir_contents(
	git_buf *dir,
	const char *sub,
	bool (*predicate)(const char *))
{
	bool result;
	size_t dir_size = git_buf_len(dir);
	size_t sub_size = strlen(sub);
	size_t alloc_size;

	/* leave base valid even if we could not make space for subdir */
	if (GIT_ADD_SIZET_OVERFLOW(&alloc_size, dir_size, sub_size) ||
		GIT_ADD_SIZET_OVERFLOW(&alloc_size, alloc_size, 2) ||
		git_buf_try_grow(dir, alloc_size, false, false) < 0)
		return false;

	/* save excursion */
	git_buf_joinpath(dir, dir->ptr, sub);

	result = predicate(dir->ptr);

	/* restore path */
	git_buf_truncate(dir, dir_size);
	return result;
}
コード例 #16
0
ファイル: filter-filter.c プロジェクト: bodyno/TortoiseGit
static void setProcessError(DWORD exitCode, git_buf *errBuf)
{
	if (!git_buf_oom(errBuf) && git_buf_len(errBuf))
		giterr_set(GITERR_FILTER, "External filter application exited non-zero (%ld) and reported:\n%s", exitCode, errBuf->ptr);
	else
		giterr_set(GITERR_FILTER, "External filter application exited non-zero: %ld", exitCode);
}
コード例 #17
0
ファイル: fileops.c プロジェクト: KindDragon/libgit2
int git_futils_writebuffer(
	const git_buf *buf,	const char *path, int flags, mode_t mode)
{
	int fd, error = 0;

	if (flags <= 0)
		flags = O_CREAT | O_TRUNC | O_WRONLY;
	if (!mode)
		mode = GIT_FILEMODE_BLOB;

	if ((fd = p_open(path, flags, mode)) < 0) {
		giterr_set(GITERR_OS, "Could not open '%s' for writing", path);
		return fd;
	}

	if ((error = p_write(fd, git_buf_cstr(buf), git_buf_len(buf))) < 0) {
		giterr_set(GITERR_OS, "Could not write to '%s'", path);
		(void)p_close(fd);
		return error;
	}

	if ((error = p_close(fd)) < 0)
		giterr_set(GITERR_OS, "Error while closing '%s'", path);

	return error;
}
コード例 #18
0
ファイル: patch.c プロジェクト: whavinga/libgit2
size_t git_patch_size(
	git_patch *patch,
	int include_context,
	int include_hunk_headers,
	int include_file_headers)
{
	size_t out;

	assert(patch);

	out = patch->content_size;

	if (!include_context)
		out -= patch->context_size;

	if (include_hunk_headers)
		out += patch->header_size;

	if (include_file_headers) {
		git_buf file_header = GIT_BUF_INIT;

		if (git_diff_delta__format_file_header(
			&file_header, patch->delta, NULL, NULL, 0) < 0)
			giterr_clear();
		else
			out += git_buf_len(&file_header);

		git_buf_free(&file_header);
	}

	return out;
}
コード例 #19
0
ファイル: refs.c プロジェクト: DavidMolinari/sonic-pi
int git_reference_normalize_name(
	char *buffer_out,
	size_t buffer_size,
	const char *name,
	unsigned int flags)
{
	git_buf buf = GIT_BUF_INIT;
	int error;

	if ((error = git_reference__normalize_name(&buf, name, flags)) < 0)
		goto cleanup;

	if (git_buf_len(&buf) > buffer_size - 1) {
		giterr_set(
		GITERR_REFERENCE,
		"The provided buffer is too short to hold the normalization of '%s'", name);
		error = GIT_EBUFS;
		goto cleanup;
	}

	git_buf_copy_cstr(buffer_out, buffer_size, &buf);

	error = 0;

cleanup:
	git_buf_free(&buf);
	return error;
}
コード例 #20
0
ファイル: odb_loose.c プロジェクト: csware/libgit2
static int loose_backend__foreach(git_odb_backend *_backend, git_odb_foreach_cb cb, void *data)
{
	char *objects_dir;
	int error;
	git_buf buf = GIT_BUF_INIT;
	struct foreach_state state;
	loose_backend *backend = (loose_backend *) _backend;

	assert(backend && cb);

	objects_dir = backend->objects_dir;

	git_buf_sets(&buf, objects_dir);
	git_path_to_dir(&buf);
	if (git_buf_oom(&buf))
		return -1;

	memset(&state, 0, sizeof(state));
	state.cb = cb;
	state.data = data;
	state.dir_len = git_buf_len(&buf);

	error = git_path_direach(&buf, 0, foreach_cb, &state);

	git_buf_dispose(&buf);

	return error;
}
コード例 #21
0
ファイル: odb_loose.c プロジェクト: csware/libgit2
/* Explore an entry of a directory and see if it matches a short oid */
static int fn_locate_object_short_oid(void *state, git_buf *pathbuf) {
	loose_locate_object_state *sstate = (loose_locate_object_state *)state;

	if (git_buf_len(pathbuf) - sstate->dir_len != GIT_OID_HEXSZ - 2) {
		/* Entry cannot be an object. Continue to next entry */
		return 0;
	}

	if (git_path_isdir(pathbuf->ptr) == false) {
		/* We are already in the directory matching the 2 first hex characters,
		 * compare the first ncmp characters of the oids */
		if (!memcmp(sstate->short_oid + 2,
			(unsigned char *)pathbuf->ptr + sstate->dir_len,
			sstate->short_oid_len - 2)) {

			if (!sstate->found) {
				sstate->res_oid[0] = sstate->short_oid[0];
				sstate->res_oid[1] = sstate->short_oid[1];
				memcpy(sstate->res_oid+2, pathbuf->ptr+sstate->dir_len, GIT_OID_HEXSZ-2);
			}
			sstate->found++;
		}
	}

	if (sstate->found > 1)
		return GIT_EAMBIGUOUS;

	return 0;
}
コード例 #22
0
ファイル: diff_file.c プロジェクト: 0CV0/libgit2
static int diff_file_content_load_workdir_file(
	git_diff_file_content *fc, git_buf *path)
{
	int error = 0;
	git_vector filters = GIT_VECTOR_INIT;
	git_buf raw = GIT_BUF_INIT, filtered = GIT_BUF_INIT;
	git_file fd = git_futils_open_ro(git_buf_cstr(path));

	if (fd < 0)
		return fd;

	if (!fc->file->size &&
		!(fc->file->size = git_futils_filesize(fd)))
		goto cleanup;

	if (diff_file_content_binary_by_size(fc))
		goto cleanup;

	if ((error = git_filters_load(
			&filters, fc->repo, fc->file->path, GIT_FILTER_TO_ODB)) < 0)
		goto cleanup;
	/* error >= is a filter count */

	if (error == 0) {
		if (!(error = git_futils_mmap_ro(
				&fc->map, fd, 0, (size_t)fc->file->size)))
			fc->flags |= GIT_DIFF_FLAG__UNMAP_DATA;
		else /* fall through to try readbuffer below */
			giterr_clear();
	}

	if (error != 0) {
		error = git_futils_readbuffer_fd(&raw, fd, (size_t)fc->file->size);
		if (error < 0)
			goto cleanup;

		if (!filters.length)
			git_buf_swap(&filtered, &raw);
		else
			error = git_filters_apply(&filtered, &raw, &filters);

		if (!error) {
			fc->map.len  = git_buf_len(&filtered);
			fc->map.data = git_buf_detach(&filtered);
			fc->flags |= GIT_DIFF_FLAG__FREE_DATA;
		}

		git_buf_free(&raw);
		git_buf_free(&filtered);
	}

cleanup:
	git_filters_free(&filters);
	p_close(fd);

	return error;
}
コード例 #23
0
ファイル: fetchhead.c プロジェクト: Angeldude/sonic-pi
int git_repository_fetchhead_foreach(git_repository *repo,
	git_repository_fetchhead_foreach_cb cb,
	void *payload)
{
	git_buf path = GIT_BUF_INIT, file = GIT_BUF_INIT, name = GIT_BUF_INIT;
	const char *ref_name;
	git_oid oid;
	const char *remote_url;
	unsigned int is_merge = 0;
	char *buffer, *line;
	size_t line_num = 0;
	int error = 0;

	assert(repo && cb);

	if (git_buf_joinpath(&path, repo->path_repository, GIT_FETCH_HEAD_FILE) < 0)
		return -1;

	if ((error = git_futils_readbuffer(&file, git_buf_cstr(&path))) < 0)
		goto done;

	buffer = file.ptr;

	while ((line = git__strsep(&buffer, "\n")) != NULL) {
		++line_num;

		if ((error = fetchhead_ref_parse(
				&oid, &is_merge, &name, &remote_url, line, line_num)) < 0)
			goto done;

		if (git_buf_len(&name) > 0)
			ref_name = git_buf_cstr(&name);
		else
			ref_name = NULL;

		error = cb(ref_name, remote_url, &oid, is_merge, payload);
		if (error) {
			giterr_set_after_callback(error);
			goto done;
		}
	}

	if (*buffer) {
		giterr_set(GITERR_FETCHHEAD, "No EOL at line %"PRIuZ, line_num+1);
		error = -1;
		goto done;
	}

done:
	git_buf_free(&file);
	git_buf_free(&path);
	git_buf_free(&name);

	return error;
}
コード例 #24
0
ファイル: notes.c プロジェクト: ralpheav/PM_GIT
static int process_entry_path(
	const char* entry_path,
	const git_oid *note_oid,
	int (*note_cb)(git_note_data *note_data, void *payload),
	void *payload)
{
	int error = -1;
	size_t i = 0, j = 0, len;
	git_buf buf = GIT_BUF_INIT;
	git_note_data note_data;

	if ((error = git_buf_puts(&buf, entry_path)) < 0)
		goto cleanup;

	len = git_buf_len(&buf);

	while (i < len) {
		if (buf.ptr[i] == '/') {
			i++;
			continue;
		}

		if (git__fromhex(buf.ptr[i]) < 0) {
			/* This is not a note entry */
			goto cleanup;
		}

		if (i != j)
			buf.ptr[j] = buf.ptr[i];

		i++;
		j++;
	}

	buf.ptr[j] = '\0';
	buf.size = j;

	if (j != GIT_OID_HEXSZ) {
		/* This is not a note entry */
		goto cleanup;
	}

	if ((error = git_oid_fromstr(
			&note_data.annotated_object_oid, buf.ptr)) < 0)
		goto cleanup;

	git_oid_cpy(&note_data.blob_oid, note_oid);

	if (note_cb(&note_data, payload))
		error = GIT_EUSER;

cleanup:
	git_buf_free(&buf);
	return error;
}
コード例 #25
0
ファイル: branch.c プロジェクト: ANNAVARAMVENKATESH/libgit2
int git_branch_upstream__name(
	git_buf *tracking_name,
	git_repository *repo,
	const char *canonical_branch_name)
{
	const char *remote_name, *merge_name;
	git_buf buf = GIT_BUF_INIT;
	int error = -1;
	git_remote *remote = NULL;
	const git_refspec *refspec;

	assert(tracking_name && canonical_branch_name);

	if (!git_reference__is_branch(canonical_branch_name))
		return not_a_local_branch(canonical_branch_name);

	if ((error = retrieve_upstream_configuration(
		&remote_name, repo, canonical_branch_name, "branch.%s.remote")) < 0)
			goto cleanup;

	if ((error = retrieve_upstream_configuration(
		&merge_name, repo, canonical_branch_name, "branch.%s.merge")) < 0)
			goto cleanup;

	if (!*remote_name || !*merge_name) {
		giterr_set(GITERR_REFERENCE,
			"branch '%s' does not have an upstream", canonical_branch_name);
		error = GIT_ENOTFOUND;
		goto cleanup;
	}

	if (strcmp(".", remote_name) != 0) {
		if ((error = git_remote_load(&remote, repo, remote_name)) < 0)
			goto cleanup;

		refspec = git_remote__matching_refspec(remote, merge_name);
		if (!refspec) {
			error = GIT_ENOTFOUND;
			goto cleanup;
		}

		if (git_refspec_transform_r(&buf, refspec, merge_name) < 0)
			goto cleanup;
	} else
		if (git_buf_sets(&buf, merge_name) < 0)
			goto cleanup;

	error = git_buf_set(tracking_name, git_buf_cstr(&buf), git_buf_len(&buf));

cleanup:
	git_remote_free(remote);
	git_buf_free(&buf);
	return error;
}
コード例 #26
0
ファイル: quote.c プロジェクト: CodeSmithyIDE/libgit2
static void expect_unquote_pass(const char *expected, const char *quoted)
{
	git_buf buf = GIT_BUF_INIT;

	cl_git_pass(git_buf_puts(&buf, quoted));
	cl_git_pass(git_buf_unquote(&buf));

	cl_assert_equal_s(expected, git_buf_cstr(&buf));
	cl_assert_equal_i(strlen(expected), git_buf_len(&buf));

	git_buf_dispose(&buf);
}
コード例 #27
0
ファイル: indexer.c プロジェクト: Arhzi/libgit2
void test_pack_indexer__no_tmp_files(void)
{
	git_indexer *idx = NULL;
	git_buf path = GIT_BUF_INIT;
	git_buf first_tmp_file = GIT_BUF_INIT;

	/* Precondition: there are no temporary files. */
	cl_git_pass(git_buf_sets(&path, clar_sandbox_path()));
	cl_git_pass(find_tmp_file_recurs(&first_tmp_file, &path));
	git_buf_free(&path);
	cl_assert(git_buf_len(&first_tmp_file) == 0);

	cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL, NULL));
	git_indexer_free(idx);

	cl_git_pass(git_buf_sets(&path, clar_sandbox_path()));
	cl_git_pass(find_tmp_file_recurs(&first_tmp_file, &path));
	git_buf_free(&path);
	cl_assert(git_buf_len(&first_tmp_file) == 0);
	git_buf_free(&first_tmp_file);
}
コード例 #28
0
ファイル: diff_file.c プロジェクト: CodeSmithyIDE/libgit2
static int diff_file_content_commit_to_str(
	git_diff_file_content *fc, bool check_status)
{
	char oid[GIT_OID_HEXSZ+1];
	git_buf content = GIT_BUF_INIT;
	const char *status = "";

	if (check_status) {
		int error = 0;
		git_submodule *sm = NULL;
		unsigned int sm_status = 0;
		const git_oid *sm_head;

		if ((error = git_submodule_lookup(&sm, fc->repo, fc->file->path)) < 0) {
			/* GIT_EEXISTS means a "submodule" that has not been git added */
			if (error == GIT_EEXISTS) {
				giterr_clear();
				error = 0;
			}
			return error;
		}

		if ((error = git_submodule_status(&sm_status, fc->repo, fc->file->path, GIT_SUBMODULE_IGNORE_UNSPECIFIED)) < 0) {
			git_submodule_free(sm);
			return error;
		}

		/* update OID if we didn't have it previously */
		if ((fc->file->flags & GIT_DIFF_FLAG_VALID_ID) == 0 &&
			((sm_head = git_submodule_wd_id(sm)) != NULL ||
			 (sm_head = git_submodule_head_id(sm)) != NULL))
		{
			git_oid_cpy(&fc->file->id, sm_head);
			fc->file->flags |= GIT_DIFF_FLAG_VALID_ID;
		}

		if (GIT_SUBMODULE_STATUS_IS_WD_DIRTY(sm_status))
			status = "-dirty";

		git_submodule_free(sm);
	}

	git_oid_tostr(oid, sizeof(oid), &fc->file->id);
	if (git_buf_printf(&content, "Subproject commit %s%s\n", oid, status) < 0)
		return -1;

	fc->map.len  = git_buf_len(&content);
	fc->map.data = git_buf_detach(&content);
	fc->flags |= GIT_DIFF_FLAG__FREE_DATA;

	return 0;
}
コード例 #29
0
ファイル: path.c プロジェクト: Asquera/libgit2
int git_path_direach(
	git_buf *path,
	int (*fn)(void *, git_buf *),
	void *arg)
{
	ssize_t wd_len;
	DIR *dir;
	struct dirent *de, *de_buf;

	if (git_path_to_dir(path) < 0)
		return -1;

	wd_len = git_buf_len(path);

	if ((dir = opendir(path->ptr)) == NULL) {
		giterr_set(GITERR_OS, "Failed to open directory '%s'", path->ptr);
		return -1;
	}

#ifdef __sun
	de_buf = git__malloc(sizeof(struct dirent) + FILENAME_MAX + 1);
#else
	de_buf = git__malloc(sizeof(struct dirent));
#endif

	while (p_readdir_r(dir, de_buf, &de) == 0 && de != NULL) {
		int result;

		if (is_dot_or_dotdot(de->d_name))
			continue;

		if (git_buf_puts(path, de->d_name) < 0) {
			closedir(dir);
			git__free(de_buf);
			return -1;
		}

		result = fn(arg, path);

		git_buf_truncate(path, wd_len); /* restore path */

		if (result < 0) {
			closedir(dir);
			git__free(de_buf);
			return -1;
		}
	}

	closedir(dir);
	git__free(de_buf);
	return 0;
}
コード例 #30
0
ファイル: smart_pkt.c プロジェクト: nelhage/libgit2
static int buffer_want_with_caps(const git_remote_head *head, transport_smart_caps *caps, git_buf *buf)
{
	git_buf str = GIT_BUF_INIT;
	char oid[GIT_OID_HEXSZ +1] = {0};
	size_t len;

	/* Prefer multi_ack_detailed */
	if (caps->multi_ack_detailed)
		git_buf_puts(&str, GIT_CAP_MULTI_ACK_DETAILED " ");
	else if (caps->multi_ack)
		git_buf_puts(&str, GIT_CAP_MULTI_ACK " ");

	/* Prefer side-band-64k if the server supports both */
	if (caps->side_band_64k)
		git_buf_printf(&str, "%s ", GIT_CAP_SIDE_BAND_64K);
	else if (caps->side_band)
		git_buf_printf(&str, "%s ", GIT_CAP_SIDE_BAND);

	if (caps->include_tag)
		git_buf_puts(&str, GIT_CAP_INCLUDE_TAG " ");

	if (caps->thin_pack)
		git_buf_puts(&str, GIT_CAP_THIN_PACK " ");

	if (caps->ofs_delta)
		git_buf_puts(&str, GIT_CAP_OFS_DELTA " ");

	if (git_buf_oom(&str))
		return -1;

	len = strlen("XXXXwant ") + GIT_OID_HEXSZ + 1 /* NUL */ +
		 git_buf_len(&str) + 1 /* LF */;

	if (len > 0xffff) {
		giterr_set(GITERR_NET,
			"tried to produce packet with invalid length %" PRIuZ, len);
		return -1;
	}

	git_buf_grow_by(buf, len);
	git_oid_fmt(oid, &head->oid);
	git_buf_printf(buf,
		"%04xwant %s %s\n", (unsigned int)len, oid, git_buf_cstr(&str));
	git_buf_dispose(&str);

	GITERR_CHECK_ALLOC_BUF(buf);

	return 0;
}