|
2 | 2 | #include <git2/types.h> |
3 | 3 |
|
4 | 4 | #include "merge_subcommand.hpp" |
5 | | -// #include "../wrapper/repository_wrapper.hpp" |
| 5 | +#include <iostream> |
6 | 6 |
|
7 | 7 |
|
8 | 8 | merge_subcommand::merge_subcommand(const libgit2_object&, CLI::App& app) |
9 | 9 | { |
10 | 10 | auto *sub = app.add_subcommand("merge", "Join two or more development histories together"); |
11 | 11 |
|
12 | 12 | sub->add_option("<branch>", m_branches_to_merge, "Branch(es) to merge"); |
| 13 | + sub->add_flag("--no-ff", m_no_ff, ""); |
| 14 | + sub->add_flag("--commit", m_commit, "Perform the merge and commit the result. This option can be used to override --no-commit."); |
| 15 | + sub->add_flag("--no-commit", m_no_commit, "With --no-commit perform the merge and stop just before creating a merge commit, to give the user a chance to inspect and further tweak the merge result before committing. \nNote that fast-forward updates do not create a merge commit and therefore there is no way to stop those merges with --no-commit. Thus, if you want to ensure your branch is not changed or updated by the merge command, use --no-ff with --no-commit."); |
13 | 16 |
|
14 | 17 | sub->callback([this]() { this->run(); }); |
15 | 18 | } |
@@ -54,6 +57,60 @@ void perform_fastforward(repository_wrapper& repo, const git_oid target_oid, int |
54 | 57 | target_ref.write_new_ref(target_oid); |
55 | 58 | } |
56 | 59 |
|
| 60 | +static void create_merge_commit(repository_wrapper repo, index_wrapper index, std::vector<std::string> m_branches_to_merge, |
| 61 | + annotated_commit_list_wrapper commits_to_merge, size_t num_commits_to_merge) // std::vector<annotated_commit_wrapper> commits_to_merge |
| 62 | +{ |
| 63 | + auto head_ref = repo.head(); |
| 64 | + auto merge_ref = repo.find_reference_dwim(m_branches_to_merge.front()); |
| 65 | + // if (ref) |
| 66 | + // { |
| 67 | + // auto merge_ref = std::move(ref).value(); |
| 68 | + // } |
| 69 | + auto merge_commit = repo.resolve_local_ref(m_branches_to_merge.front()).value(); |
| 70 | + |
| 71 | + std::vector<commit_wrapper> parents_list; |
| 72 | + parents_list.reserve(num_commits_to_merge + 1); |
| 73 | + parents_list.push_back(std::move(head_ref.peel<commit_wrapper>())); |
| 74 | + for (size_t i=0; i<num_commits_to_merge; ++i) |
| 75 | + { |
| 76 | + std::cout << commits_to_merge[i]; |
| 77 | + parents_list.push_back(repo.find_commit(commits_to_merge[i]->oid())); |
| 78 | + } |
| 79 | + auto parents = commit_list_wrapper(std::move(parents_list)); |
| 80 | + |
| 81 | + auto author_committer_sign = signature_wrapper::get_default_signature_from_env(repo); |
| 82 | + std::string author_name; |
| 83 | + author_name = author_committer_sign.first.name(); |
| 84 | + std::string author_email; |
| 85 | + author_email = author_committer_sign.first.email(); |
| 86 | + auto author_committer_sign_now = signature_wrapper::signature_now(author_name, author_email, author_name, author_email); |
| 87 | + |
| 88 | + std::string msg_target = NULL; |
| 89 | + if (merge_ref) |
| 90 | + { |
| 91 | + msg_target = merge_ref->short_name(); |
| 92 | + } |
| 93 | + else |
| 94 | + { |
| 95 | + msg_target = git_oid_tostr_s(&(merge_commit.oid())); |
| 96 | + } |
| 97 | + |
| 98 | + std::string msg; |
| 99 | + msg = "Merge "; |
| 100 | + if (merge_ref) |
| 101 | + { |
| 102 | + msg.append("branch "); |
| 103 | + } |
| 104 | + else |
| 105 | + { |
| 106 | + msg.append("commit "); |
| 107 | + } |
| 108 | + msg.append(msg_target); |
| 109 | + std::cout << msg << std::endl; |
| 110 | + |
| 111 | + repo.create_commit(author_committer_sign_now, msg, std::optional<commit_list_wrapper>(std::move(parents))); |
| 112 | +} |
| 113 | + |
57 | 114 | void merge_subcommand::run() |
58 | 115 | { |
59 | 116 | auto directory = get_current_git_path(); |
@@ -97,4 +154,41 @@ void merge_subcommand::run() |
97 | 154 | assert(num_commits_to_merge == 1); |
98 | 155 | perform_fastforward(repo, target_oid, (analysis & GIT_MERGE_ANALYSIS_UNBORN)); |
99 | 156 | } |
| 157 | + else if (analysis & GIT_MERGE_ANALYSIS_NORMAL) |
| 158 | + { |
| 159 | + std::cout << "OR THERE ?" << std::endl; |
| 160 | + git_merge_options merge_opts = GIT_MERGE_OPTIONS_INIT; |
| 161 | + git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT; |
| 162 | + |
| 163 | + merge_opts.flags = 0; |
| 164 | + merge_opts.file_flags = GIT_MERGE_FILE_STYLE_DIFF3; |
| 165 | + |
| 166 | + checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE|GIT_CHECKOUT_ALLOW_CONFLICTS; |
| 167 | + |
| 168 | + if (preference & GIT_MERGE_PREFERENCE_FASTFORWARD_ONLY) |
| 169 | + { |
| 170 | + std::cout << "Fast-forward is preferred, but only a merge is possible\n" << std::endl; |
| 171 | + } |
| 172 | + |
| 173 | + throw_if_error(git_merge(repo, |
| 174 | + (const git_annotated_commit**)c_commits_to_merge, |
| 175 | + num_commits_to_merge, |
| 176 | + &merge_opts, |
| 177 | + &checkout_opts)); |
| 178 | + } |
| 179 | + |
| 180 | + index_wrapper index = repo.make_index(); |
| 181 | + |
| 182 | + if (git_index_has_conflicts(index)) |
| 183 | + { |
| 184 | + std::cout << "WAAAAAAAAAAAARRRRRR !!!!!!!!!" << std::endl; |
| 185 | + /* Handle conflicts */ |
| 186 | + // output_conflicts(index); |
| 187 | + } |
| 188 | + else if (!m_no_commit) |
| 189 | + { |
| 190 | + std::cout << "???" << std::endl; |
| 191 | + create_merge_commit(repo, index, m_branches_to_merge, commits_to_merge, num_commits_to_merge); |
| 192 | + printf("Merge made\n"); |
| 193 | + } |
100 | 194 | } |
0 commit comments