Obtain the list of commits and process them. */
| 1140 | /** Obtain the list of commits and process them. |
| 1141 | */ |
| 1142 | static void processLog(const Options & options) |
| 1143 | { |
| 1144 | ResultWriter result; |
| 1145 | |
| 1146 | std::string command = "git log --reverse --no-merges --pretty=%H"; |
| 1147 | fmt::print("{}\n", command); |
| 1148 | auto git_log = ShellCommand::execute(command); |
| 1149 | |
| 1150 | /// Collect hashes in memory. This is inefficient but allows to display beautiful progress. |
| 1151 | /// The number of commits is in order of single millions for the largest repositories, |
| 1152 | /// so don't care about potential waste of ~100 MB of memory. |
| 1153 | |
| 1154 | std::vector<std::string> hashes; |
| 1155 | |
| 1156 | auto & in = git_log->out; |
| 1157 | while (!in.eof()) |
| 1158 | { |
| 1159 | std::string hash; |
| 1160 | readString(hash, in); |
| 1161 | assertChar('\n', in); |
| 1162 | |
| 1163 | if (!options.skip_commits.contains(hash)) |
| 1164 | hashes.emplace_back(std::move(hash)); |
| 1165 | } |
| 1166 | |
| 1167 | size_t num_commits = hashes.size(); |
| 1168 | fmt::print("Total {} commits to process.\n", num_commits); |
| 1169 | |
| 1170 | /// Will run multiple processes in parallel |
| 1171 | size_t num_threads = options.threads; |
| 1172 | if (num_threads == 0) |
| 1173 | throw Exception(ErrorCodes::INCORRECT_DATA, "num-threads cannot be zero"); |
| 1174 | |
| 1175 | std::vector<std::unique_ptr<ShellCommand>> show_commands(num_threads); |
| 1176 | for (size_t i = 0; i < num_commits && i < num_threads; ++i) |
| 1177 | show_commands[i] = gitShow(hashes[i]); |
| 1178 | |
| 1179 | Snapshot snapshot; |
| 1180 | DiffHashes diff_hashes; |
| 1181 | |
| 1182 | for (size_t i = 0; i < num_commits; ++i) |
| 1183 | { |
| 1184 | ReadBuffer & show_in = show_commands[i % num_threads]->out; |
| 1185 | processCommit(show_in, options, i, num_commits, hashes[i], snapshot, diff_hashes, result); |
| 1186 | show_in.ignoreAll(); |
| 1187 | |
| 1188 | if (!options.stop_after_commit.empty() && hashes[i] == options.stop_after_commit) |
| 1189 | break; |
| 1190 | |
| 1191 | if (i + num_threads < num_commits) |
| 1192 | show_commands[i % num_threads] = gitShow(hashes[i + num_threads]); |
| 1193 | } |
| 1194 | |
| 1195 | result.finalize(); |
| 1196 | } |
| 1197 | |
| 1198 | |
| 1199 | } |
no test coverage detected