# # patch "git.cc" # from [6ea227700999cd346f440e882e01635ca37c5e55] # to [443deb7ce70ed3351306902462f369952be5475f] # # patch "git.hh" # from [455688c7759d9d2d749a89abf8f12d9347b38ed5] # to [7d4562a9da683e0b44154bef5a348585d6adbdda] # # patch "git_export.cc" # from [5442c384ab54c4e7fa64b92e0918aa2005b7123d] # to [0ffa8d709893776efdaa0cff76502124c12becc8] # # patch "git_import.cc" # from [345f0919c3dd1ab2fb7be4d2102a6df446edd225] # to [0fd5b50535d4fe7d6076aebbf15f4dfa128dbf9d] # ======================================================================== --- git.cc 6ea227700999cd346f440e882e01635ca37c5e55 +++ git.cc 443deb7ce70ed3351306902462f369952be5475f @@ -148,4 +148,66 @@ delete_file(system_path(intmpfile)); } + +// Look up given GIT commit id in present monotone history; +// this is used for incremental import. Being smart, it also +// populates the commitmap with GIT commits it finds along the way. +void +historical_gitrev_to_monorev(git_history &git, app_state &app, + git_object_id gitrid, revision_id &found_rid) +{ + queue frontier; + set seen; + + // All the ancestry should be at least already in our branch, so there is + // no need to work over the whole database. + set heads; + get_branch_heads(git.branch, app, heads); + for (set::const_iterator i = heads.begin(); + i != heads.end(); ++i) + frontier.push(*i); + + while (!frontier.empty()) + { + revision_id rid = frontier.front(); frontier.pop(); + + if (seen.find(rid) != seen.end()) + continue; + seen.insert(rid); + + revision_set rev; + app.db.get_revision(rid, rev); + + vector > certs; + app.db.get_revision_certs(rid, gitcommit_id_cert_name, certs); + I(certs.size() < 2); + if (certs.size() > 0) + { + // This is a GIT commit, then. + cert_value cv; + decode_base64(certs[0].inner().value, cv); + git_object_id gitoid = cv(); + + git.commitmap[gitoid()] = make_pair(rid, rev.new_manifest); + + if (gitoid == gitrid) + { + found_rid = rid; + return; + } + } + + for (edge_map::const_iterator e = rev.edges.begin(); + e != rev.edges.end(); ++e) + { + frontier.push(edge_old_revision(e)); + } + } + + N(false, + F("Wicked revision tree - incremental import wanted to import a GIT commit\n" + "whose parent is not in the Monotone database yet. This means a hole must\n" + "have popped up in the Monotone revision history.")); +} + #endif ======================================================================== --- git.hh 455688c7759d9d2d749a89abf8f12d9347b38ed5 +++ git.hh 7d4562a9da683e0b44154bef5a348585d6adbdda @@ -34,4 +34,7 @@ void capture_git_cmd_output(boost::format const &fmt, std::filebuf &fbout); void capture_git_cmd_io(boost::format const &fmt, data const &input, std::filebuf &fbout); +void historical_gitrev_to_monorev(git_history &git, app_state &app, + git_object_id gitrid, revision_id &found_rid); + #endif // __GIT_HH__ ======================================================================== --- git_export.cc 5442c384ab54c4e7fa64b92e0918aa2005b7123d +++ git_export.cc 0ffa8d709893776efdaa0cff76502124c12becc8 @@ -520,6 +520,16 @@ set ancestry; get_gitrev_ancestry(gitrev, ancestry); add_gitrevs_descendants(git, app, filter, ancestry); + + try + { + revision_id rev; + historical_gitrev_to_monorev(git, app, gitrev, rev); + } + catch (std::exception &e) + { + N(false, "head mtexport is not subset of our tree; perhaps import first?"); + } } vector revlist; revlist.clear(); ======================================================================== --- git_import.cc 345f0919c3dd1ab2fb7be4d2102a6df446edd225 +++ git_import.cc 0fd5b50535d4fe7d6076aebbf15f4dfa128dbf9d @@ -313,67 +313,6 @@ } } -// Look up given GIT commit id in present monotone history; -// this is used for incremental import. Being smart, it also -// populates the commitmap with GIT commits it finds along the way. -static void -historical_gitrev_to_monorev(git_history &git, app_state &app, - git_object_id gitrid, revision_id &found_rid) -{ - queue frontier; - set seen; - - // All the ancestry should be at least already in our branch, so there is - // no need to work over the whole database. - set heads; - get_branch_heads(git.branch, app, heads); - for (set::const_iterator i = heads.begin(); - i != heads.end(); ++i) - frontier.push(*i); - - while (!frontier.empty()) - { - revision_id rid = frontier.front(); frontier.pop(); - - if (seen.find(rid) != seen.end()) - continue; - seen.insert(rid); - - revision_set rev; - app.db.get_revision(rid, rev); - - vector > certs; - app.db.get_revision_certs(rid, gitcommit_id_cert_name, certs); - I(certs.size() < 2); - if (certs.size() > 0) - { - // This is a GIT commit, then. - cert_value cv; - decode_base64(certs[0].inner().value, cv); - git_object_id gitoid = cv(); - - git.commitmap[gitoid()] = make_pair(rid, rev.new_manifest); - - if (gitoid == gitrid) - { - found_rid = rid; - return; - } - } - - for (edge_map::const_iterator e = rev.edges.begin(); - e != rev.edges.end(); ++e) - { - frontier.push(edge_old_revision(e)); - } - } - - N(false, - F("Wicked revision tree - incremental import wanted to import a GIT commit\n" - "whose parent is not in the Monotone database yet. This means a hole must\n" - "have popped up in the Monotone revision history.")); -} - // extract_path_set() is silly and wipes its playground first static void extract_path_set_cont(manifest_map const & man, path_set & paths)