Wed, 25 Feb 2026 21:13:55 +0100
add reading commit hashes from the commit log - resolves #807
| CHANGELOG | file | annotate | diff | comparison | revisions | |
| src/commit-data.h | file | annotate | diff | comparison | revisions | |
| src/heatmap.cpp | file | annotate | diff | comparison | revisions | |
| src/html.cpp | file | annotate | diff | comparison | revisions | |
| src/main.cpp | file | annotate | diff | comparison | revisions |
--- a/CHANGELOG Fri Feb 06 18:44:47 2026 +0100 +++ b/CHANGELOG Wed Feb 25 21:13:55 2026 +0100 @@ -2,6 +2,7 @@ - Add --styles-and-script option to output the default CSS and Javascript - Add monthly summaries +- Add reading commit hashes from the commit log Version 1.1.2 - 2025-12-15
--- a/src/commit-data.h Fri Feb 06 18:44:47 2026 +0100 +++ b/src/commit-data.h Wed Feb 25 21:13:55 2026 +0100 @@ -31,14 +31,24 @@ #include <string> namespace fm { + struct commit_info final { + std::string hash; + std::string message; + commit_info(std::string_view hash, std::string_view message) + : hash{hash}, message {message} {} + }; + using commit_counts = std::unordered_map< std::string, // repository name unsigned>; using summaries_lists = std::unordered_map< std::string, // repository name - std::vector<std::string> >; + std::vector<commit_info> >; using tag_lists = std::unordered_map< std::string, // repository name + std::vector<commit_info> >; + using tag_summaries = std::unordered_map< + std::string, // repository name std::vector<std::string> >; struct commits final { @@ -57,7 +67,7 @@ }; struct commit_summary final { - tag_lists tags_with_date; + tag_summaries tags_with_date; commit_counts commits; [[nodiscard]] unsigned count(const std::string &repo) const {
--- a/src/heatmap.cpp Fri Feb 06 18:44:47 2026 +0100 +++ b/src/heatmap.cpp Wed Feb 25 21:13:55 2026 +0100 @@ -37,16 +37,17 @@ for (auto line: std::views::split(log, "\n"sv)) { if (line.empty()) continue; - // find all delimiters + // split the line by delimiter const auto line_view = std::string_view{line}; - const auto pos_delim1 = line_view.find('#', 0); - const auto pos_delim2 = line_view.find('#', pos_delim1 + 1); - const auto pos_delim3 = line_view.find('#', pos_delim2 + 1); + auto parts = std::views::split(line_view, '#') + | std::views::transform([](auto r) { return std::string_view(r); }) + | std::ranges::to<std::vector>(); - std::string author{settings.map_author(line_view.substr(0, pos_delim1))}; - std::string_view date_view{line_view.substr(pos_delim1+1, pos_delim2 - pos_delim1 - 1)}; - std::string_view tags_view{line_view.substr(pos_delim2+1, pos_delim3 - pos_delim2 - 1)}; - std::string_view summary_view{line_view.substr(pos_delim3+1)}; + std::string_view hash_view{parts[0]}; + std::string author{settings.map_author(parts[1])}; + std::string_view date_view{parts[2]}; + std::string_view tags_view{parts[3]}; + std::string_view summary_view{parts[4]}; int year = 0; unsigned int month = 0, day = 0; @@ -60,10 +61,10 @@ m_heatmap[repo_key][author][chrono::year_month_day{ chrono::year{year}, chrono::month{month}, chrono::day{day} }]; - summaries[m_current_repo].emplace_back(summary_view); + summaries[m_current_repo].emplace_back(hash_view, summary_view); // special case: if the (only) tag is "tip", we do not add it if (!tags_view.empty() && tags_view != "tip") { - tags[m_current_repo].emplace_back(tags_view); + tags[m_current_repo].emplace_back(hash_view, tags_view); } } } @@ -82,10 +83,10 @@ } for (auto &&[reponame, tags]: commits.tags) { if (tags.empty()) continue; - std::string tag_list = tags.at(0); + std::string tag_list = tags.at(0).message; for (unsigned i = 1; i < tags.size(); ++i) { tag_list.append(", "); - tag_list.append(tags.at(i)); + tag_list.append(tags.at(i).message); } cs.tags_with_date[reponame].emplace_back( std::format("{} on {}-{:02}-{:02}",
--- a/src/html.cpp Fri Feb 06 18:44:47 2026 +0100 +++ b/src/html.cpp Wed Feb 25 21:13:55 2026 +0100 @@ -92,7 +92,7 @@ if (hide_repo_names) { for (const auto &tags_vector: tags | std::views::values) { for (const auto &tag: tags_vector) { - tags_json += escape_json(tag); + tags_json += escape_json(tag.message); tags_json += ' '; } } @@ -104,7 +104,7 @@ for (const auto &[repo, tags_vector] : tags) { tags_json += "\"" + escape_json(repo) + "\":\""; for (const auto &tag: tags_vector) { - tags_json += escape_json(tag); + tags_json += escape_json(tag.message); tags_json += ' '; } if (!tags_vector.empty()) { @@ -120,7 +120,7 @@ return tags_json; } - static std::string build_tag_array(fm::tag_lists tags, bool hide_repo_names) { + static std::string build_tag_summary(fm::tag_summaries tags, bool hide_repo_names) { std::string tags_json; if (hide_repo_names) { tags_json += '['; @@ -482,7 +482,7 @@ commit_summary_json += '}'; commit_summary = std::format("data-commits=\"{}\"", encode(commit_summary_json)); } - std::string tags = build_tag_array(summary.tags_with_date, hide_repo_names); + std::string tags = build_tag_summary(summary.tags_with_date, hide_repo_names); printf("<th scope=\"col\" title=\"Total commits: %u\" colspan=\"%d\" data-total=\"%u\" %s data-tags=\"%s\">%s</th>\n", total, colspans[i], total, commit_summary.c_str(), @@ -535,10 +535,10 @@ } // Build a JSON object of commit summaries - auto add_summaries = [](std::string &json, const std::vector<std::string> &summaries) static { + auto add_summaries = [](std::string &json, const std::vector<fm::commit_info> &summaries) static { // We have to iterate in reverse order to sort the summaries chronologically for (const auto &summary : summaries | std::views::reverse) { - json += "\"" + escape_json(summary) + "\","; + json += "\"" + escape_json(summary.message) + "\","; } json.pop_back(); };
--- a/src/main.cpp Fri Feb 06 18:44:47 2026 +0100 +++ b/src/main.cpp Wed Feb 25 21:13:55 2026 +0100 @@ -276,7 +276,7 @@ proc.setbin(settings.hg); if (proc.exec_log({"log", "--date", std::format("{0}-01-01 00:00:00 to {0}-12-31 23:59:59", report_year), - "--template", "{author}#{date|shortdate}#{tags}#{desc|firstline}\\n"})) { + "--template", "{node}#{author}#{date|shortdate}#{tags}#{desc|firstline}\\n"})) { fprintf(stderr, "Reading commit log for repo '%s' failed!\n", repo.path.c_str()); return EXIT_FAILURE; } @@ -289,7 +289,7 @@ "--decorate-refs=refs/tags/", "--since", std::format("{0}-01-01 00:00:00", report_year), "--until", std::format("{0}-12-31 23:59:59", report_year), - "--format=tformat:%an <%ae>#%cs#%(decorate:prefix=,suffix=,tag=,separator= )#%s"})) { + "--format=tformat:%H#%an <%ae>#%cs#%(decorate:prefix=,suffix=,tag=,separator= )#%s"})) { fprintf(stderr, "Reading commit log for repo '%s' failed!\n", repo.path.c_str()); return EXIT_FAILURE; }