Revision: 78315 http://sourceforge.net/p/brlcad/code/78315 Author: starseeker Date: 2021-02-23 23:04:16 +0000 (Tue, 23 Feb 2021) Log Message: ----------- Add the ability to remove commits from the history (take a SHA1 list of commits to remove.)
Modified Paths: -------------- brlcad/trunk/misc/repowork/commit.cpp brlcad/trunk/misc/repowork/repowork.cpp brlcad/trunk/misc/repowork/repowork.h Modified: brlcad/trunk/misc/repowork/commit.cpp =================================================================== --- brlcad/trunk/misc/repowork/commit.cpp 2021-02-23 19:26:17 UTC (rev 78314) +++ brlcad/trunk/misc/repowork/commit.cpp 2021-02-23 23:04:16 UTC (rev 78315) @@ -639,6 +639,9 @@ return -1; } + if (c->skip_commit) + return 0; + // If this is a reset commit, it's handled quite differently if (c->reset_commit) { outfile << "reset " << c->branch << "\n"; Modified: brlcad/trunk/misc/repowork/repowork.cpp =================================================================== --- brlcad/trunk/misc/repowork/repowork.cpp 2021-02-23 19:26:17 UTC (rev 78314) +++ brlcad/trunk/misc/repowork/repowork.cpp 2021-02-23 23:04:16 UTC (rev 78315) @@ -556,6 +556,75 @@ } int +git_remove_commits(git_fi_data *s, std::string &remove_commits) +{ + if (!s->have_sha1s) { + std::cerr << "Fatal - commit removal requested, but don't have original sha1 ids - redo fast-export with the --show-original-ids option.\n"; + exit(1); + } + + std::ifstream infile_remove_commits(remove_commits, std::ifstream::binary); + if (remove_commits.length() && !infile_remove_commits.good()) { + std::cerr << "Could not open remove_commits file: " << remove_commits << "\n"; + exit(-1); + } + std::set<std::string> remove_sha1s; + if (infile_remove_commits.good()) { + std::string line; + while (std::getline(infile_remove_commits, line)) { + // Skip anything the wrong length + if (line.length() != 40) { + continue; + } + remove_sha1s.insert(line); + std::cout << "remove sha1: " << line << "\n"; + bool valid = false; + for (size_t i = 0; i < s->commits.size(); i++) { + if (s->commits[i].id.sha1 == line) { + valid = true; + break; + } + } + if (!valid) { + std::cout << "INVALID sha1 supplied for removal!\n"; + } + } + + infile_remove_commits.close(); + } + + + std::set<std::string>::iterator r_it; + for (r_it = remove_sha1s.begin(); r_it != remove_sha1s.end(); r_it++) { + git_commitish rfrom; + git_commitish rish; + for (size_t i = 0; i < s->commits.size(); i++) { + if (s->commits[i].id.sha1 == *r_it) { + rfrom = s->commits[i].from; + rish = s->commits[i].id; + s->commits[i].skip_commit = true; + break; + } + } + // Update any references + for (size_t i = 0; i < s->commits.size(); i++) { + if (s->commits[i].from == rish) { + std::cout << *r_it << " removal: updating from commit for " << s->commits[i].id.sha1 << "\n"; + s->commits[i].from = rfrom; + } + for (size_t j = 0; j < s->commits[i].merges.size(); j++) { + if (s->commits[i].merges[j] == rish) { + std::cout << *r_it << " removal: updating merge commit for " << s->commits[i].id.sha1 << "\n"; + s->commits[i].merges[j] = rfrom; + } + } + } + } + + return 0; +} + +int git_map_emails(git_fi_data *s, std::string &email_map) { // read map @@ -995,6 +1064,7 @@ bool collapse_notes = false; bool wrap_commit_lines = false; bool trim_whitespace = false; + bool list_empty = false; std::string repo_path; std::string email_map; std::string svn_map; @@ -1001,6 +1071,7 @@ std::string svn_rev_map; std::string svn_branch_map; std::string svn_branches_to_tags; + std::string remove_commits; std::string correct_branches; std::string cvs_auth_map; std::string cvs_branch_map; @@ -1022,6 +1093,7 @@ ("svn-branches", "Specify [git sha1|rev] -> svn branch (one mapping per line, format is key:[branch;branch])", cxxopts::value<std::vector<std::string>>(), "map file") ("svn-branches-to-tags", "Specify git sha1 list that was committed to tags, not branches", cxxopts::value<std::vector<std::string>>(), "sha1 list") ("correct-branches", "Specify rev -> branch sets (key;[branch;branch]. Will override svn-branches assignments.)", cxxopts::value<std::vector<std::string>>(), "map") + ("remove-commits", "Specify sha1 list of commits to remove from history", cxxopts::value<std::vector<std::string>>(), "list_file") ("cvs-auth-map", "msg&time -> cvs author map (needs sha1->key map)", cxxopts::value<std::vector<std::string>>(), "file") ("cvs-branch-map", "msg&time -> cvs branch map (needs sha1->key map)", cxxopts::value<std::vector<std::string>>(), "file") @@ -1034,6 +1106,7 @@ ("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)) ("no-blobs", "Write only commits in output .fi file.", cxxopts::value<bool>(no_blobs)) + ("list-empty", "Print out information about empty commits.", cxxopts::value<bool>(list_empty)) ("splice-commits", "Look for git fast-import files in a 'splices' directory and insert them into the history.", cxxopts::value<bool>(splice_commits)) @@ -1117,6 +1190,12 @@ correct_branches = ff[0]; } + if (result.count("remove-commits")) + { + auto& ff = result["remove-commits"].as<std::vector<std::string>>(); + remove_commits = ff[0]; + } + if (result.count("svn-branches-to-tags")) { auto& ff = result["svn-branches-to-tags"].as<std::vector<std::string>>(); @@ -1209,11 +1288,27 @@ git_map_svn_committers(&fi_data, svn_map); } + if (list_empty) { + for (size_t i = 0; i < fi_data.commits.size(); i++) { + if (fi_data.commits[i].commit_msg.length() && !fi_data.commits[i].fileops.size()) { + if (fi_data.commits[i].id.sha1.length()) { + std::cout << "Empty commit(" << fi_data.commits[i].id.sha1 << "): " << fi_data.commits[i].commit_msg << "\n"; + } else { + std::cout << "Empty commit: " << fi_data.commits[i].commit_msg << "\n"; + } + } + } + } + if (id_file.length()) { // Handle rebuild info git_id_rebuild_commits(&fi_data, id_file, repo_path, children_file); } + if (remove_commits.length()) { + git_remove_commits(&fi_data, remove_commits); + } + //////////////////////////////////////////////////// // Various note correction routines if (svn_rev_map.length()) { Modified: brlcad/trunk/misc/repowork/repowork.h =================================================================== --- brlcad/trunk/misc/repowork/repowork.h 2021-02-23 19:26:17 UTC (rev 78314) +++ brlcad/trunk/misc/repowork/repowork.h 2021-02-23 23:04:16 UTC (rev 78315) @@ -38,6 +38,13 @@ long mark = -1; // globally unique numerical identifier std::string sha1 = std::string(); // Original sha1 or part thereof, if available. If the commit is modified this string should be invalidated. std::string ref = std::string(); // branch reference or other Git reference + + bool operator==(const git_commitish &o) const { + if (index == o.index) return true; + if (mark == o.mark) return true; + if (sha1 == o.sha1) return true; + return false; + } }; @@ -95,6 +102,10 @@ // storage purpose, but they are written differently int reset_commit = 0; + + // If this commit is to be removed, set this flag + bool skip_commit = false; + // Special purpose entries for assigning an additional line // to the existing notes-based info to id SVN usernames std::string svn_id; 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