| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,8 +1,11 @@ | |||
| 1 | + #include <exception> | ||
| 1 | 2 | #include <format> | |
| 2 | 3 | #include <git2.h> | |
| 3 | - #include <git2/revwalk.h> | ||
| 4 | + #include <git2/oid.h> | ||
| 5 | + #include <git2/refs.h> | ||
| 4 | 6 | #include <git2/types.h> | |
| 5 | 7 | #include <string_view> | |
| 8 | + #include <vector> | ||
| 6 | 9 | ||
| 7 | 10 | #include <termcolor/termcolor.hpp> | |
| 8 | 11 | ||
@@ -50,15 +53,181 @@ void print_time(git_time intime, std::string prefix) | |||
| 50 | 53 | std::cout << prefix << out << " " << sign << std::format("{:02d}", hours) << std::format("{:02d}", minutes) <<std::endl; | |
| 51 | 54 | } | |
| 52 | 55 | ||
| 53 | - void print_commit(const commit_wrapper& commit, std::string m_format_flag) | ||
| 56 | + std::vector<std::string> get_tags_for_commit(repository_wrapper& repo, const git_oid* commit_oid) | ||
| 57 | + { | ||
| 58 | + std::vector<std::string> tags; | ||
| 59 | + git_strarray tag_names = {0}; | ||
| 60 | + | ||
| 61 | + if (git_tag_list(&tag_names, repo) != 0) | ||
| 62 | + { | ||
| 63 | + return tags; | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + for (size_t i = 0; i < tag_names.count; i++) | ||
| 67 | + { | ||
| 68 | + std::string tag_name = tag_names.strings[i]; | ||
| 69 | + std::string ref_name = "refs/tags/" + std::string(tag_name); | ||
| 70 | + | ||
| 71 | + reference_wrapper tag_ref = repo.find_reference(ref_name); | ||
| 72 | + object_wrapper peeled = tag_ref.peel<object_wrapper>(); | ||
| 73 | + | ||
| 74 | + if (git_oid_equal(&peeled.oid(), commit_oid)) | ||
| 75 | + { | ||
| 76 | + tags.push_back(std::string(tag_name)); | ||
| 77 | + } | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + git_strarray_dispose(&tag_names); | ||
| 81 | + return tags; | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | + std::vector<std::string> get_branches_for_commit(repository_wrapper& repo, git_branch_t type, const git_oid* commit_oid, const std::string exclude_branch) | ||
| 85 | + { | ||
| 86 | + std::vector<std::string> branches; | ||
| 87 | + | ||
| 88 | + auto branch_iter = repo.iterate_branches(type); | ||
| 89 | + while (auto branch = branch_iter.next()) | ||
| 90 | + { | ||
| 91 | + const git_oid* branch_target = nullptr; | ||
| 92 | + git_reference* ref = branch.value(); | ||
| 93 | + | ||
| 94 | + if (git_reference_type(ref) == GIT_REFERENCE_DIRECT) | ||
| 95 | + { | ||
| 96 | + branch_target = git_reference_target(ref); | ||
| 97 | + } | ||
| 98 | + else if (git_reference_type(ref) == GIT_REFERENCE_SYMBOLIC) | ||
| 99 | + { | ||
| 100 | + git_reference* resolved = nullptr; | ||
| 101 | + if (git_reference_resolve(&resolved, ref) == 0) | ||
| 102 | + { | ||
| 103 | + branch_target = git_reference_target(resolved); | ||
| 104 | + git_reference_free(resolved); | ||
| 105 | + } | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + if (branch_target && git_oid_equal(branch_target, commit_oid)) | ||
| 109 | + { | ||
| 110 | + std::string branch_name; | ||
| 111 | + branch_name = branch->name(); | ||
| 112 | + if (type == GIT_BRANCH_LOCAL) | ||
| 113 | + { | ||
| 114 | + if (branch_name != exclude_branch) | ||
| 115 | + { | ||
| 116 | + branches.push_back(branch_name); | ||
| 117 | + } | ||
| 118 | + } | ||
| 119 | + else | ||
| 120 | + { | ||
| 121 | + branches.push_back(branch_name); | ||
| 122 | + } | ||
| 123 | + } | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + return branches; | ||
| 127 | + } | ||
| 128 | + | ||
| 129 | + struct commit_refs | ||
| 130 | + { | ||
| 131 | + std::string head_branch; | ||
| 132 | + std::vector<std::string> tags; | ||
| 133 | + std::vector<std::string> local_branches; | ||
| 134 | + std::vector<std::string> remote_branches; | ||
| 135 | + | ||
| 136 | + bool has_refs() const { | ||
| 137 | + return !head_branch.empty() || !tags.empty() || | ||
| 138 | + !local_branches.empty() || !remote_branches.empty(); | ||
| 139 | + } | ||
| 140 | + }; | ||
| 141 | + | ||
| 142 | + commit_refs get_refs_for_commit(repository_wrapper& repo, const git_oid* commit_oid) | ||
| 143 | + { | ||
| 144 | + commit_refs refs; | ||
| 145 | + | ||
| 146 | + if (!repo.is_head_unborn()) | ||
| 147 | + { | ||
| 148 | + auto head = repo.head(); | ||
| 149 | + auto head_taget = head.target(); | ||
| 150 | + if (git_oid_equal(head_taget, commit_oid)) | ||
| 151 | + { | ||
| 152 | + refs.head_branch = head.short_name(); | ||
| 153 | + } | ||
| 154 | + } | ||
| 155 | + | ||
| 156 | + refs.tags = get_tags_for_commit(repo, commit_oid); | ||
| 157 | + refs.local_branches = get_branches_for_commit(repo, GIT_BRANCH_LOCAL, commit_oid, refs.head_branch); | ||
| 158 | + refs.remote_branches = get_branches_for_commit(repo, GIT_BRANCH_REMOTE, commit_oid, ""); | ||
| 159 | + | ||
| 160 | + return refs; | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | + void print_refs(commit_refs refs) | ||
| 164 | + { | ||
| 165 | + if (!refs.has_refs()) | ||
| 166 | + { | ||
| 167 | + return; | ||
| 168 | + } | ||
| 169 | + | ||
| 170 | + std::cout << " ("; | ||
| 171 | + | ||
| 172 | + bool first = true; | ||
| 173 | + | ||
| 174 | + if (!refs.head_branch.empty()) | ||
| 175 | + { | ||
| 176 | + std::cout << termcolor::bold << termcolor::cyan << "HEAD" << termcolor::reset | ||
| 177 | + << termcolor::yellow << " -> " << termcolor::reset | ||
| 178 | + << termcolor::bold << termcolor::green << refs.head_branch << termcolor::reset | ||
| 179 | + << termcolor::yellow; | ||
| 180 | + first = false; | ||
| 181 | + } | ||
| 182 | + | ||
| 183 | + for (const auto& tag :refs.tags) | ||
| 184 | + { | ||
| 185 | + if (!first) | ||
| 186 | + { | ||
| 187 | + std::cout << ", "; | ||
| 188 | + } | ||
| 189 | + std::cout << termcolor::bold << "tag: " << tag << termcolor::reset << termcolor::yellow; | ||
| 190 | + first = false; | ||
| 191 | + } | ||
| 192 | + | ||
| 193 | + for (const auto& remote : refs.remote_branches) | ||
| 194 | + { | ||
| 195 | + if (!first) | ||
| 196 | + { | ||
| 197 | + std::cout << ", "; | ||
| 198 | + } | ||
| 199 | + std::cout << termcolor::bold << termcolor::red << remote << termcolor::reset << termcolor::yellow; | ||
| 200 | + first = false; | ||
| 201 | + } | ||
| 202 | + | ||
| 203 | + for (const auto& local : refs.local_branches) | ||
| 204 | + { | ||
| 205 | + if (!first) | ||
| 206 | + { | ||
| 207 | + std::cout << ", "; | ||
| 208 | + } | ||
| 209 | + std::cout << termcolor::bold << termcolor::green << local << termcolor::reset << termcolor::yellow; | ||
| 210 | + first = false; | ||
| 211 | + } | ||
| 212 | + | ||
| 213 | + std::cout << ")" << termcolor::reset; | ||
| 214 | + } | ||
| 215 | + | ||
| 216 | + void print_commit(repository_wrapper& repo, const commit_wrapper& commit, std::string m_format_flag) | ||
| 54 | 217 | { | |
| 55 | 218 | std::string buf = commit.commit_oid_tostr(); | |
| 56 | 219 | ||
| 57 | 220 | signature_wrapper author = signature_wrapper::get_commit_author(commit); | |
| 58 | 221 | signature_wrapper committer = signature_wrapper::get_commit_committer(commit); | |
| 59 | 222 | ||
| 60 | 223 | stream_colour_fn colour = termcolor::yellow; | |
| 61 | - std::cout << colour << "commit " << buf << termcolor::reset << std::endl; | ||
| 224 | + std::cout << colour << "commit " << buf; | ||
| 225 | + | ||
| 226 | + commit_refs refs = get_refs_for_commit(repo, &commit.oid()); | ||
| 227 | + print_refs(refs); | ||
| 228 | + | ||
| 229 | + std::cout << termcolor::reset << std::endl; | ||
| 230 | + | ||
| 62 | 231 | if (m_format_flag=="fuller") | |
| 63 | 232 | { | |
| 64 | 233 | std::cout << "Author:\t " << author.name() << " " << author.email() << std::endl; | |
@@ -78,7 +247,7 @@ void print_commit(const commit_wrapper& commit, std::string m_format_flag) | |||
| 78 | 247 | print_time(author.when(), "Date:\t"); | |
| 79 | 248 | } | |
| 80 | 249 | } | |
| 81 | - std::cout << "\n " << commit.message() << "\n" << std::endl; | ||
| 250 | + std::cout << "\n " << commit.message(); | ||
| 82 | 251 | } | |
| 83 | 252 | ||
| 84 | 253 | void log_subcommand::run() | |
@@ -102,8 +271,12 @@ void log_subcommand::run() | |||
| 102 | 271 | git_oid commit_oid; | |
| 103 | 272 | while (!walker.next(commit_oid) && i<m_max_count_flag) | |
| 104 | 273 | { | |
| 274 | + if (i != 0) | ||
| 275 | + { | ||
| 276 | + std::cout << std::endl; | ||
| 277 | + } | ||
| 105 | 278 | commit_wrapper commit = repo.find_commit(commit_oid); | |
| 106 | - print_commit(commit, m_format_flag); | ||
| 279 | + print_commit(repo, commit, m_format_flag); | ||
| 107 | 280 | ++i; | |
| 108 | 281 | } | |
| 109 | 282 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments