static int rebase_open_merge(git_rebase *rebase) { git_buf state_path = GIT_BUF_INIT, buf = GIT_BUF_INIT, cmt = GIT_BUF_INIT; git_oid id; git_rebase_operation *operation; size_t i, msgnum = 0, end; int error; if ((error = git_buf_puts(&state_path, rebase->state_path)) < 0) goto done; /* Read 'msgnum' if it exists (otherwise, let msgnum = 0) */ if ((error = rebase_readint(&msgnum, &buf, &state_path, MSGNUM_FILE)) < 0 && error != GIT_ENOTFOUND) goto done; if (msgnum) { rebase->started = 1; rebase->current = msgnum - 1; } /* Read 'end' */ if ((error = rebase_readint(&end, &buf, &state_path, END_FILE)) < 0) goto done; /* Read 'current' if it exists */ if ((error = rebase_readoid(&id, &buf, &state_path, CURRENT_FILE)) < 0 && error != GIT_ENOTFOUND) goto done; /* Read cmt.* */ git_array_init_to_size(rebase->operations, end); GITERR_CHECK_ARRAY(rebase->operations); for (i = 0; i < end; i++) { git_buf_clear(&cmt); if ((error = git_buf_printf(&cmt, "cmt.%" PRIuZ, (i+1))) < 0 || (error = rebase_readoid(&id, &buf, &state_path, cmt.ptr)) < 0) goto done; operation = rebase_operation_alloc(rebase, GIT_REBASE_OPERATION_PICK, &id, NULL); GITERR_CHECK_ALLOC(operation); } /* Read 'onto_name' */ if ((error = rebase_readfile(&buf, &state_path, ONTO_NAME_FILE)) < 0) goto done; rebase->onto_name = git_buf_detach(&buf); done: git_buf_free(&cmt); git_buf_free(&state_path); git_buf_free(&buf); return error; }
int git_rebase_finish( git_rebase *rebase, const git_signature *signature) { git_reference *terminal_ref = NULL, *branch_ref = NULL, *head_ref = NULL; git_commit *terminal_commit = NULL; git_buf branch_msg = GIT_BUF_INIT, head_msg = GIT_BUF_INIT; char onto[GIT_OID_HEXSZ]; int error; assert(rebase); if (rebase->inmemory) return 0; git_oid_fmt(onto, &rebase->onto_id); if ((error = git_buf_printf(&branch_msg, "rebase finished: %s onto %.*s", rebase->orig_head_name, GIT_OID_HEXSZ, onto)) < 0 || (error = git_buf_printf(&head_msg, "rebase finished: returning to %s", rebase->orig_head_name)) < 0 || (error = git_repository_head(&terminal_ref, rebase->repo)) < 0 || (error = git_reference_peel((git_object **)&terminal_commit, terminal_ref, GIT_OBJ_COMMIT)) < 0 || (error = git_reference_create_matching(&branch_ref, rebase->repo, rebase->orig_head_name, git_commit_id(terminal_commit), 1, &rebase->orig_head_id, branch_msg.ptr)) < 0 || (error = git_reference_symbolic_create(&head_ref, rebase->repo, GIT_HEAD_FILE, rebase->orig_head_name, 1, head_msg.ptr)) < 0 || (error = rebase_copy_notes(rebase, signature)) < 0) goto done; error = rebase_cleanup(rebase); done: git_buf_free(&head_msg); git_buf_free(&branch_msg); git_commit_free(terminal_commit); git_reference_free(head_ref); git_reference_free(branch_ref); git_reference_free(terminal_ref); return error; }
static int gen_request( git_buf *buf, http_stream *s, size_t content_length) { http_subtransport *t = OWNING_SUBTRANSPORT(s); const char *path = t->connection_data.path ? t->connection_data.path : "/"; git_buf_printf(buf, "%s %s%s HTTP/1.1\r\n", s->verb, path, s->service_url); git_buf_puts(buf, "User-Agent: git/1.0 (libgit2 " LIBGIT2_VERSION ")\r\n"); git_buf_printf(buf, "Host: %s\r\n", t->connection_data.host); if (s->chunked || content_length > 0) { git_buf_printf(buf, "Accept: application/x-git-%s-result\r\n", s->service); git_buf_printf(buf, "Content-Type: application/x-git-%s-request\r\n", s->service); if (s->chunked) git_buf_puts(buf, "Transfer-Encoding: chunked\r\n"); else git_buf_printf(buf, "Content-Length: %"PRIuZ "\r\n", content_length); } else git_buf_puts(buf, "Accept: */*\r\n"); /* Apply credentials to the request */ if (t->cred && t->cred->credtype == GIT_CREDTYPE_USERPASS_PLAINTEXT && t->auth_mechanism == GIT_HTTP_AUTH_BASIC && apply_basic_credential(buf, t->cred) < 0) return -1; /* Use url-parsed basic auth if username and password are both provided */ if (!t->cred && t->connection_data.user && t->connection_data.pass) { if (!t->url_cred && git_cred_userpass_plaintext_new(&t->url_cred, t->connection_data.user, t->connection_data.pass) < 0) return -1; if (apply_basic_credential(buf, t->url_cred) < 0) return -1; } git_buf_puts(buf, "\r\n"); if (git_buf_oom(buf)) return -1; return 0; }
int merge_trees_from_branches( git_index **index, git_repository *repo, const char *ours_name, const char *theirs_name, git_merge_tree_opts *opts) { git_commit *our_commit, *their_commit, *ancestor_commit = NULL; git_tree *our_tree, *their_tree, *ancestor_tree = NULL; git_oid our_oid, their_oid, ancestor_oid; git_buf branch_buf = GIT_BUF_INIT; int error; git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, ours_name); cl_git_pass(git_reference_name_to_id(&our_oid, repo, branch_buf.ptr)); cl_git_pass(git_commit_lookup(&our_commit, repo, &our_oid)); git_buf_clear(&branch_buf); git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, theirs_name); cl_git_pass(git_reference_name_to_id(&their_oid, repo, branch_buf.ptr)); cl_git_pass(git_commit_lookup(&their_commit, repo, &their_oid)); error = git_merge_base(&ancestor_oid, repo, git_commit_id(our_commit), git_commit_id(their_commit)); if (error != GIT_ENOTFOUND) { cl_git_pass(error); cl_git_pass(git_commit_lookup(&ancestor_commit, repo, &ancestor_oid)); cl_git_pass(git_commit_tree(&ancestor_tree, ancestor_commit)); } cl_git_pass(git_commit_tree(&our_tree, our_commit)); cl_git_pass(git_commit_tree(&their_tree, their_commit)); cl_git_pass(git_merge_trees(index, repo, ancestor_tree, our_tree, their_tree, opts)); git_buf_free(&branch_buf); git_tree_free(our_tree); git_tree_free(their_tree); git_tree_free(ancestor_tree); git_commit_free(our_commit); git_commit_free(their_commit); git_commit_free(ancestor_commit); return 0; }
void test_refs_branches_create__default_reflog_message(void) { git_reflog *log; git_buf buf = GIT_BUF_INIT; const git_reflog_entry *entry; git_annotated_commit *annotated; git_signature *sig; git_config *cfg; cl_git_pass(git_repository_config(&cfg, repo)); cl_git_pass(git_config_set_string(cfg, "user.name", "Foo Bar")); cl_git_pass(git_config_set_string(cfg, "user.email", "*****@*****.**")); git_config_free(cfg); cl_git_pass(git_signature_default(&sig, repo)); retrieve_known_commit(&target, repo); cl_git_pass(git_branch_create(&branch, repo, NEW_BRANCH_NAME, target, false)); cl_git_pass(git_reflog_read(&log, repo, "refs/heads/" NEW_BRANCH_NAME)); entry = git_reflog_entry_byindex(log, 0); cl_git_pass(git_buf_printf(&buf, "branch: Created from %s", git_oid_tostr_s(git_commit_id(target)))); cl_assert_equal_s(git_buf_cstr(&buf), git_reflog_entry_message(entry)); cl_assert_equal_s(sig->email, git_reflog_entry_committer(entry)->email); cl_git_pass(git_reference_remove(repo, "refs/heads/" NEW_BRANCH_NAME)); git_reference_free(branch); git_reflog_free(log); git_buf_clear(&buf); cl_git_pass(git_annotated_commit_from_revspec(&annotated, repo, "e90810b8df3")); cl_git_pass(git_branch_create_from_annotated(&branch, repo, NEW_BRANCH_NAME, annotated, true)); cl_git_pass(git_reflog_read(&log, repo, "refs/heads/" NEW_BRANCH_NAME)); entry = git_reflog_entry_byindex(log, 0); cl_git_pass(git_buf_printf(&buf, "branch: Created from e90810b8df3")); cl_assert_equal_s(git_buf_cstr(&buf), git_reflog_entry_message(entry)); cl_assert_equal_s(sig->email, git_reflog_entry_committer(entry)->email); git_annotated_commit_free(annotated); git_buf_free(&buf); git_reflog_free(log); git_signature_free(sig); }
static int apply_basic_credential(HINTERNET request, git_cred *cred) { git_cred_userpass_plaintext *c = (git_cred_userpass_plaintext *)cred; git_buf buf = GIT_BUF_INIT, raw = GIT_BUF_INIT; wchar_t *wide = NULL; int error = -1, wide_len = 0; git_buf_printf(&raw, "%s:%s", c->username, c->password); if (git_buf_oom(&raw) || git_buf_puts(&buf, "Authorization: Basic ") < 0 || git_buf_put_base64(&buf, git_buf_cstr(&raw), raw.size) < 0) goto on_error; wide_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, git_buf_cstr(&buf), -1, NULL, 0); if (!wide_len) { giterr_set(GITERR_OS, QT_TRANSLATE_NOOP("libgit2", "Failed to measure string for wide conversion")); goto on_error; } wide = git__malloc(wide_len * sizeof(wchar_t)); if (!wide) goto on_error; if (!MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, git_buf_cstr(&buf), -1, wide, wide_len)) { giterr_set(GITERR_OS, QT_TRANSLATE_NOOP("libgit2", "Failed to convert string to wide form")); goto on_error; } if (!WinHttpAddRequestHeaders(request, wide, (ULONG) -1L, WINHTTP_ADDREQ_FLAG_ADD)) { giterr_set(GITERR_OS, QT_TRANSLATE_NOOP("libgit2", "Failed to add a header to the request")); goto on_error; } error = 0; on_error: /* We were dealing with plaintext passwords, so clean up after ourselves a bit. */ if (wide) memset(wide, 0x0, wide_len * sizeof(wchar_t)); if (buf.size) memset(buf.ptr, 0x0, buf.size); if (raw.size) memset(raw.ptr, 0x0, raw.size); git__free(wide); git_buf_free(&buf); git_buf_free(&raw); return error; }
int git_branch_move( 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; int error; assert(branch && new_branch_name); if (!git_reference_is_branch(branch)) return not_a_local_branch(branch); if ((error = git_buf_joinpath(&new_reference_name, GIT_REFS_HEADS_DIR, new_branch_name)) < 0) goto cleanup; if (git_buf_printf( &old_config_section, "branch.%s", git_reference_name(branch) + strlen(GIT_REFS_HEADS_DIR)) < 0) goto cleanup; if ((error = git_reference_rename(branch, git_buf_cstr(&new_reference_name), force)) < 0) goto cleanup; if (git_buf_printf(&new_config_section, "branch.%s", new_branch_name) < 0) goto cleanup; if ((error = git_config_rename_section( git_reference_owner(branch), git_buf_cstr(&old_config_section), git_buf_cstr(&new_config_section))) < 0) goto cleanup; cleanup: git_buf_free(&new_reference_name); git_buf_free(&old_config_section); git_buf_free(&new_config_section); return error; }
static int diff_print_one_raw( const git_diff_delta *delta, float progress, void *data) { diff_print_info *pi = data; git_buf *out = pi->buf; char code = git_diff_status_char(delta->status); char start_oid[GIT_OID_HEXSZ+1], end_oid[GIT_OID_HEXSZ+1]; GIT_UNUSED(progress); if ((pi->flags & GIT_DIFF_SHOW_UNMODIFIED) == 0 && code == ' ') return 0; git_buf_clear(out); git_oid_tostr(start_oid, pi->oid_strlen, &delta->old_file.id); git_oid_tostr(end_oid, pi->oid_strlen, &delta->new_file.id); git_buf_printf( out, (pi->oid_strlen <= GIT_OID_HEXSZ) ? ":%06o %06o %s... %s... %c" : ":%06o %06o %s %s %c", delta->old_file.mode, delta->new_file.mode, start_oid, end_oid, code); if (delta->similarity > 0) git_buf_printf(out, "%03u", delta->similarity); if (delta->old_file.path != delta->new_file.path) git_buf_printf( out, "\t%s %s\n", delta->old_file.path, delta->new_file.path); else git_buf_printf( out, "\t%s\n", delta->old_file.path ? delta->old_file.path : delta->new_file.path); if (git_buf_oom(out)) return -1; pi->line.origin = GIT_DIFF_LINE_FILE_HDR; pi->line.content = git_buf_cstr(out); pi->line.content_len = git_buf_len(out); return pi->print_cb(delta, NULL, &pi->line, pi->payload); }
static int git_style_unc_path(git_buf *buf, const char *host, const char *path) { git_buf_clear(buf); if (host) git_buf_printf(buf, "//%s/", host); if (path[0] == '/') path++; if (git__isalpha(path[0]) && path[1] == ':' && path[2] == '/') { git_buf_printf(buf, "%c$/", path[0]); path += 3; } git_buf_puts(buf, path); return git_buf_oom(buf) ? -1 : 0; }
static void assert_submodule_url(const char* name, const char *url) { git_buf key = GIT_BUF_INIT; cl_git_pass(git_buf_printf(&key, "submodule.%s.url", name)); assert_config_entry_value(g_repo, git_buf_cstr(&key), url); git_buf_free(&key); }
static int rebase_init_merge( git_rebase *rebase, git_repository *repo, const git_annotated_commit *branch, const git_annotated_commit *upstream, const git_annotated_commit *onto) { git_reference *head_ref = NULL; git_commit *onto_commit = NULL; git_buf reflog = GIT_BUF_INIT; git_buf state_path = GIT_BUF_INIT; int error; GIT_UNUSED(upstream); if ((error = git_buf_joinpath(&state_path, repo->path_repository, REBASE_MERGE_DIR)) < 0) goto done; rebase->state_path = git_buf_detach(&state_path); GITERR_CHECK_ALLOC(rebase->state_path); if (branch->ref_name) { rebase->orig_head_name = git__strdup(branch->ref_name); GITERR_CHECK_ALLOC(rebase->orig_head_name); } else { rebase->head_detached = 1; } rebase->onto_name = git__strdup(rebase_onto_name(onto)); GITERR_CHECK_ALLOC(rebase->onto_name); rebase->quiet = rebase->options.quiet; git_oid_cpy(&rebase->orig_head_id, git_annotated_commit_id(branch)); git_oid_cpy(&rebase->onto_id, git_annotated_commit_id(onto)); if ((error = rebase_setupfiles(rebase)) < 0 || (error = git_buf_printf(&reflog, "rebase: checkout %s", rebase_onto_name(onto))) < 0 || (error = git_commit_lookup( &onto_commit, repo, git_annotated_commit_id(onto))) < 0 || (error = git_checkout_tree(repo, (git_object *)onto_commit, &rebase->options.checkout_options)) < 0 || (error = git_reference_create(&head_ref, repo, GIT_HEAD_FILE, git_annotated_commit_id(onto), 1, reflog.ptr)) < 0) goto done; done: git_reference_free(head_ref); git_commit_free(onto_commit); git_buf_free(&reflog); git_buf_free(&state_path); return error; }
static int diff_print_one_raw( const git_diff_delta *delta, float progress, void *data) { diff_print_info *pi = data; git_buf *out = pi->buf; char code = git_diff_status_char(delta->status); char start_oid[GIT_OID_HEXSZ+1], end_oid[GIT_OID_HEXSZ+1]; GIT_UNUSED(progress); if (code == ' ') return 0; git_buf_clear(out); git_oid_tostr(start_oid, pi->oid_strlen, &delta->old_file.oid); git_oid_tostr(end_oid, pi->oid_strlen, &delta->new_file.oid); git_buf_printf( out, ":%06o %06o %s... %s... %c", delta->old_file.mode, delta->new_file.mode, start_oid, end_oid, code); if (delta->similarity > 0) git_buf_printf(out, "%03u", delta->similarity); if (delta->old_file.path != delta->new_file.path) git_buf_printf( out, "\t%s %s\n", delta->old_file.path, delta->new_file.path); else git_buf_printf( out, "\t%s\n", delta->old_file.path ? delta->old_file.path : delta->new_file.path); if (git_buf_oom(out)) return -1; if (pi->print_cb(delta, NULL, GIT_DIFF_LINE_FILE_HDR, git_buf_cstr(out), git_buf_len(out), pi->payload)) return callback_error(); return 0; }
int git_commit_create( git_oid *oid, git_repository *repo, const char *update_ref, const git_signature *author, const git_signature *committer, const char *message_encoding, const char *message, const git_tree *tree, int parent_count, const git_commit *parents[]) { git_buf commit = GIT_BUF_INIT; int i; git_odb *odb; assert(git_object_owner((const git_object *)tree) == repo); git_oid__writebuf(&commit, "tree ", git_object_id((const git_object *)tree)); for (i = 0; i < parent_count; ++i) { assert(git_object_owner((const git_object *)parents[i]) == repo); git_oid__writebuf(&commit, "parent ", git_object_id((const git_object *)parents[i])); } git_signature__writebuf(&commit, "author ", author); git_signature__writebuf(&commit, "committer ", committer); if (message_encoding != NULL) git_buf_printf(&commit, "encoding %s\n", message_encoding); git_buf_putc(&commit, '\n'); if (git_buf_puts(&commit, message) < 0) goto on_error; if (git_repository_odb__weakptr(&odb, repo) < 0) goto on_error; if (git_odb_write(oid, odb, commit.ptr, commit.size, GIT_OBJ_COMMIT) < 0) goto on_error; git_buf_free(&commit); if (update_ref != NULL) return git_reference__update(repo, oid, update_ref); return 0; on_error: git_buf_free(&commit); giterr_set(GITERR_OBJECT, "Failed to create commit."); return -1; }
static int create_branch( git_reference **ref_out, git_repository *repository, const char *branch_name, const git_commit *commit, const char *from, int force) { int is_unmovable_head = 0; git_reference *branch = NULL; git_buf canonical_branch_name = GIT_BUF_INIT, log_message = GIT_BUF_INIT; int error = -1; int bare = git_repository_is_bare(repository); assert(branch_name && commit && ref_out); assert(git_object_owner((const git_object *)commit) == repository); if (force && !bare && git_branch_lookup(&branch, repository, branch_name, GIT_BRANCH_LOCAL) == 0) { error = git_branch_is_head(branch); git_reference_free(branch); branch = NULL; if (error < 0) goto cleanup; is_unmovable_head = error; } if (is_unmovable_head && force) { giterr_set(GITERR_REFERENCE, "Cannot force update branch '%s' as it is " "the current HEAD of the repository.", branch_name); error = -1; goto cleanup; } if (git_buf_joinpath(&canonical_branch_name, GIT_REFS_HEADS_DIR, branch_name) < 0) goto cleanup; if (git_buf_printf(&log_message, "branch: Created from %s", from) < 0) goto cleanup; error = git_reference_create(&branch, repository, git_buf_cstr(&canonical_branch_name), git_commit_id(commit), force, git_buf_cstr(&log_message)); if (!error) *ref_out = branch; cleanup: git_buf_free(&canonical_branch_name); git_buf_free(&log_message); return error; }
int git_refspec__serialize(git_buf *out, const git_refspec *refspec) { if (refspec->force) git_buf_putc(out, '+'); git_buf_printf(out, "%s:%s", refspec->src != NULL ? refspec->src : "", refspec->dst != NULL ? refspec->dst : ""); return git_buf_oom(out) == false; }
static void write_files(char *files[]) { char *filename; git_buf path = GIT_BUF_INIT, content = GIT_BUF_INIT; size_t i; for (i = 0, filename = files[i]; filename; filename = files[++i]) { git_buf_clear(&path); git_buf_clear(&content); git_buf_printf(&path, "%s/%s", TEST_REPO_PATH, filename); git_buf_printf(&content, "This is a dirty file in the working directory!\n\n" "It will not be staged! Its filename is %s.\n", filename); cl_git_mkfile(path.ptr, content.ptr); } git_buf_free(&path); git_buf_free(&content); }
static int diff_print_one_compact( const git_diff_delta *delta, float progress, void *data) { diff_print_info *pi = data; git_buf *out = pi->buf; char old_suffix, new_suffix, code = git_diff_status_char(delta->status); int (*strcomp)(const char *, const char *) = pi->diff ? pi->diff->strcomp : git__strcmp; GIT_UNUSED(progress); if (code == ' ') return 0; old_suffix = diff_pick_suffix(delta->old_file.mode); new_suffix = diff_pick_suffix(delta->new_file.mode); git_buf_clear(out); if (delta->old_file.path != delta->new_file.path && strcomp(delta->old_file.path,delta->new_file.path) != 0) git_buf_printf(out, "%c\t%s%c -> %s%c\n", code, delta->old_file.path, old_suffix, delta->new_file.path, new_suffix); else if (delta->old_file.mode != delta->new_file.mode && delta->old_file.mode != 0 && delta->new_file.mode != 0) git_buf_printf(out, "%c\t%s%c (%o -> %o)\n", code, delta->old_file.path, new_suffix, delta->old_file.mode, delta->new_file.mode); else if (old_suffix != ' ') git_buf_printf(out, "%c\t%s%c\n", code, delta->old_file.path, old_suffix); else git_buf_printf(out, "%c\t%s\n", code, delta->old_file.path); if (git_buf_oom(out)) return -1; if (pi->print_cb(delta, NULL, GIT_DIFF_LINE_FILE_HDR, git_buf_cstr(out), git_buf_len(out), pi->payload)) return callback_error(); return 0; }
int git_diff_file_stats__summary_to_buf( git_buf *out, const git_diff_delta *delta) { if (delta->old_file.mode != delta->new_file.mode) { if (delta->old_file.mode == 0) { git_buf_printf(out, " create mode %06o %s\n", delta->new_file.mode, delta->new_file.path); } else if (delta->new_file.mode == 0) { git_buf_printf(out, " delete mode %06o %s\n", delta->old_file.mode, delta->old_file.path); } else { git_buf_printf(out, " mode change %06o => %06o %s\n", delta->old_file.mode, delta->new_file.mode, delta->new_file.path); } } return 0; }
static int disambiguate_refname(git_reference **out, git_repository *repo, const char *refname) { int error = 0, i; bool fallbackmode = true; git_reference *ref; git_buf refnamebuf = GIT_BUF_INIT, name = GIT_BUF_INIT; static const char* formatters[] = { "%s", GIT_REFS_DIR "%s", GIT_REFS_TAGS_DIR "%s", GIT_REFS_HEADS_DIR "%s", GIT_REFS_REMOTES_DIR "%s", GIT_REFS_REMOTES_DIR "%s/" GIT_HEAD_FILE, NULL }; if (*refname) git_buf_puts(&name, refname); else { git_buf_puts(&name, GIT_HEAD_FILE); fallbackmode = false; } for (i = 0; formatters[i] && (fallbackmode || i == 0); i++) { git_buf_clear(&refnamebuf); if ((error = git_buf_printf(&refnamebuf, formatters[i], git_buf_cstr(&name))) < 0) goto cleanup; if (!git_reference_is_valid_name(git_buf_cstr(&refnamebuf))) { error = GIT_EINVALIDSPEC; continue; } error = git_reference_lookup_resolved(&ref, repo, git_buf_cstr(&refnamebuf), -1); if (!error) { *out = ref; error = 0; goto cleanup; } if (error != GIT_ENOTFOUND) goto cleanup; } cleanup: git_buf_free(&name); git_buf_free(&refnamebuf); return error; }
static void write_tree(git_buf *out, git_tree_cache *tree) { size_t i; git_buf_printf(out, "%s%c%"PRIdZ" %"PRIuZ"\n", tree->name, 0, tree->entry_count, tree->children_count); if (tree->entry_count != -1) git_buf_put(out, (const char *) &tree->oid, GIT_OID_RAWSZ); for (i = 0; i < tree->children_count; i++) write_tree(out, tree->children[i]); }
int git_cherry_pick( git_repository *repo, git_commit *commit, const git_cherry_pick_options *given_opts) { git_cherry_pick_options opts; git_reference *our_ref = NULL; git_commit *our_commit = NULL; char commit_oidstr[GIT_OID_HEXSZ + 1]; const char *commit_msg, *commit_summary; git_buf their_label = GIT_BUF_INIT; git_index *index_new = NULL; int error = 0; assert(repo && commit); GITERR_CHECK_VERSION(given_opts, GIT_CHERRY_PICK_OPTIONS_VERSION, "git_cherry_pick_options"); if ((error = git_repository__ensure_not_bare(repo, "cherry-pick")) < 0) return error; if ((commit_msg = git_commit_message(commit)) == NULL || (commit_summary = git_commit_summary(commit)) == NULL) { error = -1; goto on_error; } git_oid_nfmt(commit_oidstr, sizeof(commit_oidstr), git_commit_id(commit)); if ((error = write_merge_msg(repo, commit_msg)) < 0 || (error = git_buf_printf(&their_label, "%.7s... %s", commit_oidstr, commit_summary)) < 0 || (error = cherry_pick_normalize_opts(repo, &opts, given_opts, git_buf_cstr(&their_label))) < 0 || (error = write_cherry_pick_head(repo, commit_oidstr)) < 0 || (error = git_repository_head(&our_ref, repo)) < 0 || (error = git_reference_peel((git_object **)&our_commit, our_ref, GIT_OBJ_COMMIT)) < 0 || (error = git_cherry_pick_commit(&index_new, repo, commit, our_commit, opts.mainline, &opts.merge_opts)) < 0 || (error = git_merge__check_result(repo, index_new)) < 0 || (error = git_merge__append_conflicts_to_merge_msg(repo, index_new)) < 0 || (error = git_checkout_index(repo, index_new, &opts.checkout_opts)) < 0) goto on_error; goto done; on_error: cherry_pick_state_cleanup(repo); done: git_index_free(index_new); git_commit_free(our_commit); git_reference_free(our_ref); git_buf_free(&their_label); return error; }
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 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 = (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); }
static int diff_print_oid_range( git_buf *out, const git_diff_delta *delta, int oid_strlen) { char start_oid[GIT_OID_HEXSZ+1], end_oid[GIT_OID_HEXSZ+1]; git_oid_tostr(start_oid, oid_strlen, &delta->old_file.id); git_oid_tostr(end_oid, oid_strlen, &delta->new_file.id); /* TODO: Match git diff more closely */ if (delta->old_file.mode == delta->new_file.mode) { git_buf_printf(out, "index %s..%s %o\n", start_oid, end_oid, delta->old_file.mode); } else { if (delta->old_file.mode == 0) { git_buf_printf(out, "new file mode %o\n", delta->new_file.mode); } else if (delta->new_file.mode == 0) { git_buf_printf(out, "deleted file mode %o\n", delta->old_file.mode); } else { git_buf_printf(out, "old mode %o\n", delta->old_file.mode); git_buf_printf(out, "new mode %o\n", delta->new_file.mode); } git_buf_printf(out, "index %s..%s\n", start_oid, end_oid); } return git_buf_oom(out) ? -1 : 0; }
static int diff_print_one_name_status( const git_diff_delta *delta, float progress, void *data) { diff_print_info *pi = data; git_buf *out = pi->buf; char old_suffix, new_suffix, code = git_diff_status_char(delta->status); int (*strcomp)(const char *, const char *) = pi->diff ? pi->diff->strcomp : git__strcmp; GIT_UNUSED(progress); if ((pi->flags & GIT_DIFF_SHOW_UNMODIFIED) == 0 && code == ' ') return 0; old_suffix = diff_pick_suffix(delta->old_file.mode); new_suffix = diff_pick_suffix(delta->new_file.mode); git_buf_clear(out); if (delta->old_file.path != delta->new_file.path && strcomp(delta->old_file.path,delta->new_file.path) != 0) git_buf_printf(out, "%c\t%s%c %s%c\n", code, delta->old_file.path, old_suffix, delta->new_file.path, new_suffix); else if (delta->old_file.mode != delta->new_file.mode && delta->old_file.mode != 0 && delta->new_file.mode != 0) git_buf_printf(out, "%c\t%s%c %s%c\n", code, delta->old_file.path, old_suffix, delta->new_file.path, new_suffix); else if (old_suffix != ' ') git_buf_printf(out, "%c\t%s%c\n", code, delta->old_file.path, old_suffix); else git_buf_printf(out, "%c\t%s\n", code, delta->old_file.path); if (git_buf_oom(out)) return -1; pi->line.origin = GIT_DIFF_LINE_FILE_HDR; pi->line.content = git_buf_cstr(out); pi->line.content_len = git_buf_len(out); return pi->print_cb(delta, NULL, &pi->line, pi->payload); }
static int gen_request(git_buf *buf, const char *path, const char *host, const char *op, const char *service, ssize_t content_length, int ls) { if (path == NULL) /* Is 'git fetch http://host.com/' valid? */ path = "/"; if (ls) { git_buf_printf(buf, "%s %s/info/refs?service=git-%s HTTP/1.1\r\n", op, path, service); } else { git_buf_printf(buf, "%s %s/git-%s HTTP/1.1\r\n", op, path, service); } git_buf_puts(buf, "User-Agent: git/1.0 (libgit2 " LIBGIT2_VERSION ")\r\n"); git_buf_printf(buf, "Host: %s\r\n", host); if (content_length > 0) { git_buf_printf(buf, "Accept: application/x-git-%s-result\r\n", service); git_buf_printf(buf, "Content-Type: application/x-git-%s-request\r\n", service); git_buf_printf(buf, "Content-Length: %"PRIuZ "\r\n", content_length); } else { git_buf_puts(buf, "Accept: */*\r\n"); } git_buf_puts(buf, "\r\n"); if (git_buf_oom(buf)) return -1; return 0; }
static int diff_print_oid_range(diff_print_info *pi, const git_diff_delta *delta) { git_buf *out = pi->buf; char start_oid[GIT_OID_HEXSZ+1], end_oid[GIT_OID_HEXSZ+1]; git_oid_tostr(start_oid, pi->oid_strlen, &delta->old_file.oid); git_oid_tostr(end_oid, pi->oid_strlen, &delta->new_file.oid); /* TODO: Match git diff more closely */ if (delta->old_file.mode == delta->new_file.mode) { git_buf_printf(out, "index %s..%s %o\n", start_oid, end_oid, delta->old_file.mode); } else { if (delta->old_file.mode == 0) { git_buf_printf(out, "new file mode %o\n", delta->new_file.mode); } else if (delta->new_file.mode == 0) { git_buf_printf(out, "deleted file mode %o\n", delta->old_file.mode); } else { git_buf_printf(out, "old mode %o\n", delta->old_file.mode); git_buf_printf(out, "new mode %o\n", delta->new_file.mode); } git_buf_printf(out, "index %s..%s\n", start_oid, end_oid); } if (git_buf_oom(out)) return -1; return 0; }
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; }
static int gen_request( git_buf *buf, http_stream *s, size_t content_length) { http_subtransport *t = OWNING_SUBTRANSPORT(s); if (!t->path) t->path = "/"; git_buf_printf(buf, "%s %s%s HTTP/1.1\r\n", s->verb, t->path, s->service_url); git_buf_puts(buf, "User-Agent: git/1.0 (libgit2 " LIBGIT2_VERSION ")\r\n"); git_buf_printf(buf, "Host: %s\r\n", t->host); if (s->chunked || content_length > 0) { git_buf_printf(buf, "Accept: application/x-git-%s-result\r\n", s->service); git_buf_printf(buf, "Content-Type: application/x-git-%s-request\r\n", s->service); if (s->chunked) git_buf_puts(buf, "Transfer-Encoding: chunked\r\n"); else git_buf_printf(buf, "Content-Length: %"PRIuZ "\r\n", content_length); } else git_buf_puts(buf, "Accept: */*\r\n"); /* Apply credentials to the request */ if (t->cred && t->cred->credtype == GIT_CREDTYPE_USERPASS_PLAINTEXT && t->auth_mechanism == GIT_HTTP_AUTH_BASIC && apply_basic_credential(buf, t->cred) < 0) return -1; git_buf_puts(buf, "\r\n"); if (git_buf_oom(buf)) return -1; return 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 int unset_upstream(git_config *config, const char *shortname) { git_buf buf = GIT_BUF_INIT; if (git_buf_printf(&buf, "branch.%s.remote", shortname) < 0) return -1; if (git_config_delete_entry(config, git_buf_cstr(&buf)) < 0) goto on_error; git_buf_clear(&buf); if (git_buf_printf(&buf, "branch.%s.merge", shortname) < 0) goto on_error; if (git_config_delete_entry(config, git_buf_cstr(&buf)) < 0) goto on_error; git_buf_free(&buf); return 0; on_error: git_buf_free(&buf); return -1; }