Beispiel #1
0
static void adjust_git_path(struct strbuf *buf, int git_dir_len)
{
	const char *base = buf->buf + git_dir_len;
	if (git_graft_env && is_dir_file(base, "info", "grafts"))
		strbuf_splice(buf, 0, buf->len,
			      get_graft_file(), strlen(get_graft_file()));
	else if (git_index_env && !strcmp(base, "index"))
		strbuf_splice(buf, 0, buf->len,
			      get_index_file(), strlen(get_index_file()));
	else if (git_db_env && dir_prefix(base, "objects"))
		replace_dir(buf, git_dir_len + 7, get_object_directory());
	else if (git_common_dir_env)
		update_common_dir(buf, git_dir_len);
}
Beispiel #2
0
static char *replace_encoding_header(char *buf, const char *encoding)
{
	struct strbuf tmp = STRBUF_INIT;
	size_t start, len;
	char *cp = buf;

	/* guess if there is an encoding header before a \n\n */
	while (strncmp(cp, "encoding ", strlen("encoding "))) {
		cp = strchr(cp, '\n');
		if (!cp || *++cp == '\n')
			return buf;
	}
	start = cp - buf;
	cp = strchr(cp, '\n');
	if (!cp)
		return buf; /* should not happen but be defensive */
	len = cp + 1 - (buf + start);

	strbuf_attach(&tmp, buf, strlen(buf), strlen(buf) + 1);
	if (is_encoding_utf8(encoding)) {
		/* we have re-coded to UTF-8; drop the header */
		strbuf_remove(&tmp, start, len);
	} else {
		/* just replaces XXXX in 'encoding XXXX\n' */
		strbuf_splice(&tmp, start + strlen("encoding "),
					  len - strlen("encoding \n"),
					  encoding, strlen(encoding));
	}
	return strbuf_detach(&tmp, NULL);
}
Beispiel #3
0
static void adjust_git_path(const struct repository *repo,
			    struct strbuf *buf, int git_dir_len)
{
	const char *base = buf->buf + git_dir_len;
	if (is_dir_file(base, "info", "grafts"))
		strbuf_splice(buf, 0, buf->len,
			      repo->graft_file, strlen(repo->graft_file));
	else if (!strcmp(base, "index"))
		strbuf_splice(buf, 0, buf->len,
			      repo->index_file, strlen(repo->index_file));
	else if (dir_prefix(base, "objects"))
		replace_dir(buf, git_dir_len + 7, repo->objects->odb->path);
	else if (git_hooks_path && dir_prefix(base, "hooks"))
		replace_dir(buf, git_dir_len + 5, git_hooks_path);
	else if (repo->different_commondir)
		update_common_dir(buf, git_dir_len, repo->commondir);
}
Beispiel #4
0
static void setup_branch_path(struct branch_info *branch)
{
	struct strbuf buf = STRBUF_INIT;

	strbuf_branchname(&buf, branch->name, INTERPRET_BRANCH_LOCAL);
	if (strcmp(buf.buf, branch->name))
		branch->name = xstrdup(buf.buf);
	strbuf_splice(&buf, 0, 0, "refs/heads/", 11);
	branch->path = strbuf_detach(&buf, NULL);
}
Beispiel #5
0
static void replace_dir(struct strbuf *buf, int len, const char *newdir)
{
	int newlen = strlen(newdir);
	int need_sep = (buf->buf[len] && !is_dir_sep(buf->buf[len])) &&
		!is_dir_sep(newdir[newlen - 1]);
	if (need_sep)
		len--;	 /* keep one char, to be replaced with '/'  */
	strbuf_splice(buf, 0, len, newdir, newlen);
	if (need_sep)
		buf->buf[newlen] = '/';
}
Beispiel #6
0
// returns 0 until it's past the end of the string
// only works on unix newlines ('\n' only)
static int
get_strbuf_line(struct strbuf* str, int* pos, struct strbuf* line)
{
    int begin;
    int len;
    char* buf;
    len = str->len;
    if (*pos >= len) {
        return 1;
    }
    begin = *pos;
    buf = str->buf;
    while (*pos < len && (buf[*pos] != '\r' && buf[*pos] != '\n')) {
        (*pos)++;
    }
    strbuf_splice(line, 0, line->len, str->buf+begin, (*pos)-begin);
    if (buf[*pos] == '\r' && *pos < (len-1) && buf[(*pos)+1] == '\n') {
        (*pos) += 2;
    } else {
        (*pos)++;
    }
    return 0;
}
Beispiel #7
0
static int replace_parents(struct strbuf *buf, int argc, const char **argv)
{
	struct strbuf new_parents = STRBUF_INIT;
	const char *parent_start, *parent_end;
	int i;

	/* find existing parents */
	parent_start = buf->buf;
	parent_start += GIT_SHA1_HEXSZ + 6; /* "tree " + "hex sha1" + "\n" */
	parent_end = parent_start;

	while (starts_with(parent_end, "parent "))
		parent_end += 48; /* "parent " + "hex sha1" + "\n" */

	/* prepare new parents */
	for (i = 0; i < argc; i++) {
		struct object_id oid;
		if (get_oid(argv[i], &oid) < 0) {
			strbuf_release(&new_parents);
			return error(_("Not a valid object name: '%s'"),
				     argv[i]);
		}
		if (!lookup_commit_reference(&oid)) {
			strbuf_release(&new_parents);
			return error(_("could not parse %s"), argv[i]);
		}
		strbuf_addf(&new_parents, "parent %s\n", oid_to_hex(&oid));
	}

	/* replace existing parents with new ones */
	strbuf_splice(buf, parent_start - buf->buf, parent_end - parent_start,
		      new_parents.buf, new_parents.len);

	strbuf_release(&new_parents);
	return 0;
}
Beispiel #8
0
void strbuf_remove(struct strbuf *sb, size_t pos, size_t len)
{
	strbuf_splice(sb, pos, len, NULL, 0);
}
Beispiel #9
0
void strbuf_insert(struct strbuf *sb, size_t pos, const void *data, size_t len)
{
	strbuf_splice(sb, pos, 0, data, len);
}
Beispiel #10
0
static inline void strbuf_replace(struct strbuf *sb, const char *a, const char *b)
{
	const char *ptr = strstr(sb->buf, a);
	if (ptr)
		strbuf_splice(sb, ptr - sb->buf, strlen(a), b, strlen(b));
}
Beispiel #11
0
void append_signoff(struct strbuf *msgbuf, int ignore_footer, unsigned flag)
{
    unsigned no_dup_sob = flag & APPEND_SIGNOFF_DEDUP;
    struct strbuf sob = STRBUF_INIT;
    int has_footer;

    strbuf_addstr(&sob, sign_off_header);
    strbuf_addstr(&sob, fmt_name(getenv("GIT_COMMITTER_NAME"),
                                 getenv("GIT_COMMITTER_EMAIL")));
    strbuf_addch(&sob, '\n');

    /*
     * If the whole message buffer is equal to the sob, pretend that we
     * found a conforming footer with a matching sob
     */
    if (msgbuf->len - ignore_footer == sob.len &&
            !strncmp(msgbuf->buf, sob.buf, sob.len))
        has_footer = 3;
    else
        has_footer = has_conforming_footer(msgbuf, &sob, ignore_footer);

    if (!has_footer) {
        const char *append_newlines = NULL;
        size_t len = msgbuf->len - ignore_footer;

        if (!len) {
            /*
             * The buffer is completely empty.  Leave foom for
             * the title and body to be filled in by the user.
             */
            append_newlines = "\n\n";
        } else if (msgbuf->buf[len - 1] != '\n') {
            /*
             * Incomplete line.  Complete the line and add a
             * blank one so that there is an empty line between
             * the message body and the sob.
             */
            append_newlines = "\n\n";
        } else if (len == 1) {
            /*
             * Buffer contains a single newline.  Add another
             * so that we leave room for the title and body.
             */
            append_newlines = "\n";
        } else if (msgbuf->buf[len - 2] != '\n') {
            /*
             * Buffer ends with a single newline.  Add another
             * so that there is an empty line between the message
             * body and the sob.
             */
            append_newlines = "\n";
        } /* else, the buffer already ends with two newlines. */

        if (append_newlines)
            strbuf_splice(msgbuf, msgbuf->len - ignore_footer, 0,
                          append_newlines, strlen(append_newlines));
    }

    if (has_footer != 3 && (!no_dup_sob || has_footer != 2))
        strbuf_splice(msgbuf, msgbuf->len - ignore_footer, 0,
                      sob.buf, sob.len);

    strbuf_release(&sob);
}
Beispiel #12
0
Datei: branch.c Projekt: emk/git
void create_branch(const char *head,
		   const char *name, const char *start_name,
		   int force, int reflog, enum branch_track track)
{
	struct ref_lock *lock;
	struct commit *commit;
	unsigned char sha1[20];
	char *real_ref, msg[PATH_MAX + 20];
	struct strbuf ref = STRBUF_INIT;
	int forcing = 0;
	int len;

	len = strlen(name);
	if (interpret_nth_last_branch(name, &ref) != len) {
		strbuf_reset(&ref);
		strbuf_add(&ref, name, len);
	}
	strbuf_splice(&ref, 0, 0, "refs/heads/", 11);

	if (check_ref_format(ref.buf))
		die("'%s' is not a valid branch name.", name);

	if (resolve_ref(ref.buf, sha1, 1, NULL)) {
		if (!force)
			die("A branch named '%s' already exists.", name);
		else if (!is_bare_repository() && !strcmp(head, name))
			die("Cannot force update the current branch.");
		forcing = 1;
	}

	real_ref = NULL;
	if (get_sha1(start_name, sha1))
		die("Not a valid object name: '%s'.", start_name);

	switch (dwim_ref(start_name, strlen(start_name), sha1, &real_ref)) {
	case 0:
		/* Not branching from any existing branch */
		if (track == BRANCH_TRACK_EXPLICIT)
			die("Cannot setup tracking information; starting point is not a branch.");
		break;
	case 1:
		/* Unique completion -- good, only if it is a real ref */
		if (track == BRANCH_TRACK_EXPLICIT && !strcmp(real_ref, "HEAD"))
			die("Cannot setup tracking information; starting point is not a branch.");
		break;
	default:
		die("Ambiguous object name: '%s'.", start_name);
		break;
	}

	if ((commit = lookup_commit_reference(sha1)) == NULL)
		die("Not a valid branch point: '%s'.", start_name);
	hashcpy(sha1, commit->object.sha1);

	lock = lock_any_ref_for_update(ref.buf, NULL, 0);
	if (!lock)
		die("Failed to lock ref for update: %s.", strerror(errno));

	if (reflog)
		log_all_ref_updates = 1;

	if (forcing)
		snprintf(msg, sizeof msg, "branch: Reset from %s",
			 start_name);
	else
		snprintf(msg, sizeof msg, "branch: Created from %s",
			 start_name);

	if (real_ref && track)
		setup_tracking(name, real_ref, track);

	if (write_ref_sha1(lock, sha1, msg) < 0)
		die("Failed to write ref: %s.", strerror(errno));

	strbuf_release(&ref);
	free(real_ref);
}