/* * libgit2 "blame" example - shows how to use the blame API * * Written by the libgit2 contributors * * To the extent possible under law, the author(s) have dedicated all copyright * and related and neighboring rights to this software to the public domain * worldwide. This software is distributed without any warranty. * * You should have received a copy of the CC0 Public Domain Dedication along * with this software. If not, see * . */ #include #include "common.h" /** * This example implements the safe portion of the git's 'pull' * command. That is, merging fro upstream, which is the behaviour * which does not loose procedence information or reverse history. */ int main(int argc, char **argv) { git_repository *repo; git_reference *current_branch, *upstream; git_buf remote_name = {0}; git_remote *remote; git_threads_init(); /** * Figure out what the current branch's upstream remote is so * we know from which remote to fetch */ check_lg2(git_repository_open_ext(&repo, ".", 0, NULL), "failed to open repo", NULL); check_lg2(git_repository_head(¤t_branch, repo), "failed to lookup current branch", NULL); check_lg2(git_branch_remote_name(&remote_name, repo, git_reference_name(current_branch)), "failed to get the reference's upstream", NULL); check_lg2(git_remote_load(&remote, repo, remote_name.ptr), "failed to load remote", NULL); git_buf_free(&remote_name); check_lg2(git_remote_fetch(remote, NULL, NULL), "failed to fetch from upstream", NULL); /** * Now that we have the updated data from the remote, look up * our branch's upstream and merge from it. */ { git_merge_head *merge_heads[1]; check_lg2(git_branch_upstream(&upstream, current_branch), "failed to get upstream branch", NULL); check_lg2(git_merge_head_from_ref(&merge_heads[0], repo, upstream), "failed to create merge head", NULL); check_lg2(git_merge(repo, (const git_merge_head **) merge_heads, 1, NULL, NULL), "failed to merge", NULL); git_merge_head_free(merge_heads[1]); } /** * Once the merge operation succeeds, we need to check whether * there were any conflicts merging */ { git_index *index; int has_conflicts; check_lg2(git_repository_index(&index, repo), "failed to load index", NULL); has_conflicts = git_index_has_conflicts(index); git_index_free(index); if (has_conflicts) { printf("There were conflicts merging. Please resolve them and commit\n"); git_reference_free(upstream); git_reference_free(current_branch); git_repository_free(repo); return 0; } } /** * If there were no conflicts, then we commit with the message * that was prepared by the merge operation. * * A tool would take this opportunity to spawn the user's * editor and let them change it, but that is outside of our * purpose here. * * */ { git_index *index; git_buf message = {0}; git_oid commit_id, tree_id; git_commit *parents[2]; git_signature *user; git_tree *tree; /* Get the contents of the index into the repo as the tree want for the commit */ check_lg2(git_repository_index(&index, repo), "failed to load index", NULL); check_lg2(git_index_write_tree(&tree_id, index), "failed to write tree", NULL); git_index_free(index); check_lg2(git_signature_default(&user, repo), "failed to get user's ident", NULL); check_lg2(git_repository_message(&message, repo), "failed to get message", NULL); check_lg2(git_tree_lookup(&tree, repo, &tree_id), "failed to lookup tree", NULL); check_lg2(git_commit_lookup(&parents[0], repo, git_reference_target(current_branch)), "failed to lookup first parent", NULL); check_lg2(git_commit_lookup(&parents[1], repo, git_reference_target(upstream)), "failed to lookup second parent", NULL); check_lg2(git_commit_create(&commit_id, repo, "HEAD", user, user, NULL, message.ptr, tree, 2, (const git_commit **) parents), "failed to create commit", NULL); git_tree_free(tree); git_signature_free(user); } git_reference_free(upstream); git_reference_free(current_branch); git_repository_free(repo); return 0; }