Revision: 76512 http://sourceforge.net/p/brlcad/code/76512 Author: starseeker Date: 2020-07-26 21:59:41 +0000 (Sun, 26 Jul 2020) Log Message: ----------- Checkpoint some work trying to set up to use CVS checkouts to rebuild individual 'bad' CVS commits. In principle the idea is similar to the svnfexport fallback which does a deleteall + full tree commit when the delta processing doesn't produce a matching checkout, but this time we are trying to do it without requiring a 2 week rebuild... repowork should allow for selective commit redefinition if we do it right. Will also have to produce blobs and tree states from the CVS checkouts... ick.
Modified Paths: -------------- brlcad/trunk/misc/repowork/repowork.cpp brlcad/trunk/misc/repowork/repowork.h Modified: brlcad/trunk/misc/repowork/repowork.cpp =================================================================== --- brlcad/trunk/misc/repowork/repowork.cpp 2020-07-26 20:22:43 UTC (rev 76511) +++ brlcad/trunk/misc/repowork/repowork.cpp 2020-07-26 21:59:41 UTC (rev 76512) @@ -100,6 +100,11 @@ s->commits[i].svn_id = std::string(svnidvar[1]); std::cout << "Identified revision " << s->commits[i].svn_id << "\n"; + // Store the id->sha1 relationship for potential later use + if (s->commits[i].id.sha1.length()) { + s->rev_to_sha1[s->commits[i].svn_id] = s->commits[i].id.sha1; + } + // We wrote the wrong SVN branch name for older dmtogl branches - // names were deliberately collapsed in git conversion, but we // should reflect the original SVN history in the metadata. Undo @@ -221,9 +226,105 @@ return 0; } +int +git_id_cvs_commits(git_fi_data *s, std::string &cvs_id_file, std::string &child_commits_file) +{ + { + // read children + std::ifstream cfile(child_commits_file, std::ifstream::binary); + if (!cfile.good()) { + std::cerr << "Could not open child_commits_file file: " << child_commits_file << "\n"; + exit(-1); + } + std::string rline; + while (std::getline(cfile, rline)) { + // Skip empty lines + if (!rline.length()) { + continue; + } + // First 40 characters are the key + std::string key = rline.substr(0, 40); + rline.erase(0,41); // Remove key and space + std::set<std::string> vals; + while (rline.length() >= 40) { + std::string val = rline.substr(0, 40); + vals.insert(val); + rline.erase(0,41); + } + if (vals.size()) { + s->children[key] = vals; + } + } + } + { + // read cvs ids + std::ifstream infile(cvs_id_file, std::ifstream::binary); + if (!infile.good()) { + std::cerr << "Could not open cvs_id_file file: " << cvs_id_file << "\n"; + exit(-1); + } + + std::set<std::string> cvs_ids; + + std::string line; + while (std::getline(infile, line)) { + // Skip empty lines + if (!line.length()) { + continue; + } + + std::string sha1; + if (line.length() < 40) { + // Given an svn revision - translate it to a sha1 + if (s->rev_to_sha1.find(line) == s->rev_to_sha1.end()) { + std::cerr << "SVN revision " << line << " could not be mapped to SHA1. May need to re-export fast import file with --show-original-ids.\n"; + exit(1); + } + sha1 = s->rev_to_sha1[line]; + } else { + sha1 = line; + } + + s->rebuild_commits.insert(sha1); + std::cout << "rebuild commit: " << line << " -> " << sha1 << "\n"; + } + } + + // Children of the rebuilt commits will need to fully define their + // contents, unless they are also being rebuilt (in which case their + // children will need to reset themselves.) + std::set<std::string> rbc = s->rebuild_commits; + while (rbc.size()) { + std::string rb = *rbc.begin(); + rbc.erase(rb); + std::cout << "Finding reset commit(s) for: " << rb << "\n"; + if (s->children.find(rb) == s->children.end()) { + // No child commits - no further work needed. + std::cout << "Leaf commit: " << rb << "\n"; + continue; + } + std::set<std::string>::iterator c_it; + std::set<std::string> rc = s->children[rb]; + while (rc.size()) { + std::string rcs = *rc.begin(); + rc.erase(rcs); + if (s->rebuild_commits.find(rcs) == s->rebuild_commits.end()) { + std::cout << "found reset commit: " << rcs << "\n"; + s->reset_commits.insert(rcs); + } else { + if (s->children.find(rcs) != s->children.end()) { + rc.insert(s->children[rcs].begin(), s->children[rcs].end()); + } + } + } + } + return 0; +} + + typedef int (*gitcmd_t)(git_fi_data *, std::ifstream &); gitcmd_t @@ -298,6 +399,9 @@ std::string repo_path; std::string email_map; std::string svn_map; + std::string children_file; + std::string cvs_id_file; + std::string cvs_repo_path; int cwidth = 72; // TODO - might be good do have a "validate" option that does the fast import and then @@ -308,12 +412,19 @@ options.add_options() ("e,email-map", "Specify replacement username+email mappings (one map per line, format is commit-id-1;commit-id-2)", cxxopts::value<std::vector<std::string>>(), "map file") - ("n,collapse-notes", "Take any git-notes contents and append them to regular commit messages.", cxxopts::value<bool>(collapse_notes)) - ("r,repo", "Original git repository path (must support running git log)", cxxopts::value<std::vector<std::string>>(), "path to repo") ("s,svn-map", "Specify svn rev -> committer map (one mapping per line, format is commit-rev name)", cxxopts::value<std::vector<std::string>>(), "map file") + ("t,trim-whitespace", "Trim extra spaces and end-of-line characters from the end of commit messages", cxxopts::value<bool>(trim_whitespace)) ("w,wrap-commit-lines", "Wrap long commit lines to 72 cols (won't wrap messages already having multiple non-empty lines)", cxxopts::value<bool>(wrap_commit_lines)) ("width", "Column wrapping width (if enabled)", cxxopts::value<int>(), "N") + + ("r,repo", "Original git repository path (must support running git log)", cxxopts::value<std::vector<std::string>>(), "path") + ("n,collapse-notes", "Take any git-notes contents and append them to regular commit messages.", cxxopts::value<bool>(collapse_notes)) + + ("children", "File with output of \"git rev-list --children --all\"", cxxopts::value<std::vector<std::string>>(), "file") + ("cvs-ids", "Specify CVS era commits (revision number or SHA1) to rebuild. Requires cvs-repo be set as well. Needs --show-original-ids information in fast import file", cxxopts::value<std::vector<std::string>>(), "file") + ("cvs-repo", "CVS repository path", cxxopts::value<std::vector<std::string>>(), "path") + ("h,help", "Print help") ; @@ -343,6 +454,24 @@ svn_map = ff[0]; } + if (result.count("children")) + { + auto& ff = result["children"].as<std::vector<std::string>>(); + children_file = ff[0]; + } + + if (result.count("cvs-ids")) + { + auto& ff = result["cvs-ids"].as<std::vector<std::string>>(); + cvs_id_file = ff[0]; + } + + if (result.count("cvs-repo")) + { + auto& ff = result["cvs-repo"].as<std::vector<std::string>>(); + cvs_repo_path = ff[0]; + } + if (result.count("width")) { cwidth = result["width"].as<int>(); @@ -360,6 +489,11 @@ return -1; } + if ((cvs_id_file.length() && !cvs_repo_path.length()) || (!cvs_id_file.length() && cvs_repo_path.length())) { + std::cerr << "Need both CVS id list and CVS repository path for processing!\n"; + return -1; + } + if (argc != 3) { std::cout << "repowork [opts] <input_file> <output_file>\n"; return -1; @@ -398,6 +532,11 @@ git_map_svn_committers(&fi_data, svn_map); } + if (cvs_id_file.length()) { + // Handle CVS rebuild info + git_id_cvs_commits(&fi_data, cvs_id_file, children_file); + } + fi_data.wrap_width = cwidth; fi_data.wrap_commit_lines = wrap_commit_lines; fi_data.trim_whitespace = trim_whitespace; Modified: brlcad/trunk/misc/repowork/repowork.h =================================================================== --- brlcad/trunk/misc/repowork/repowork.h 2020-07-26 20:22:43 UTC (rev 76511) +++ brlcad/trunk/misc/repowork/repowork.h 2020-07-26 21:59:41 UTC (rev 76512) @@ -162,6 +162,24 @@ return mark; }; + // For CVS rebuild, we need to store a) which commits must be rebuilt + // from the CVS checkout and b) which commits that are "good" in git + // immediately follow the rebuilt commits in their respective branches. + // The former need new trees and blobs based on the CVS checkout, and + // the latter need a full tree deleteall + rebuild commit based on the + // git contents (a diff tree in the commit may no longer make the + // necessary changes given the previous commit will have changed.) + // + // If a commit that would otherwise have been a reset commit is a + // rebuild commit, it is promoted to rebuild and the next commit + // becomes the reset commit. + std::set<std::string> rebuild_commits; + std::set<std::string> reset_commits; + std::map<std::string, std::set<std::string>> children; + + // We also need to be able to translate SVN revs into sha1s + std::map<std::string, std::string> rev_to_sha1; + private: long mark = -1; }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. _______________________________________________ BRL-CAD Source Commits mailing list brlcad-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/brlcad-commits