# # patch "ChangeLog" # from [e21b770e333d939b96c56be641c4d14541d690af] # to [49c41f292efe8d05f3e53cbe11ec7283e877842d] # # patch "commands.cc" # from [29d7e3771d311fb949604030cee3e4fe6511ba7b] # to [dacd4ad20f431be30aee75690b848633fcd25363] # # patch "file_io.hh" # from [2b82c69614021cd23608ebdf7486716ed986514d] # to [87da82801eb51bc7297c917637e2895bd60ba8bc] # # patch "git.cc" # from [71b9f618b658a4d5e176910c28077801c632b98b] # to [64bdb960fc0fb008a0e30e18aa7817a01ecc00eb] # # patch "git.hh" # from [215071ed5af0e65bc816835dcb9188e6467c1ba0] # to [a990b78ee920f114adbaa017e28fcf9220221663] # ======================================================================== --- ChangeLog e21b770e333d939b96c56be641c4d14541d690af +++ ChangeLog 49c41f292efe8d05f3e53cbe11ec7283e877842d @@ -1,3 +1,11 @@ +2005-08-30 Nathaniel Smith + + * commands.cc (cvs_import, git_import): Fixup after merge. + * git.hh (import_git_repo): Port to paths.cc. + * git.cc: Port to paths.cc generally. + * file_io.hh (absolute_tree_walker, walk_tree_absolute): New + interface (still needs implementing). + 2005-08-20 Petr Baudis * git.cc: Support for incremental imports - when you pull new stuff to your GIT repository, you can then re-run git_import ======================================================================== --- commands.cc 29d7e3771d311fb949604030cee3e4fe6511ba7b +++ commands.cc dacd4ad20f431be30aee75690b848633fcd25363 @@ -3455,7 +3455,7 @@ if (args.size() != 1) throw usage(name); - import_cvs_repo(mkpath(idx(args, 0)()), app); + import_cvs_repo(system_path(idx(args, 0)), app); } CMD(git_import, "git", "GITREPO", "import given head from GIT repository", @@ -3464,7 +3464,7 @@ if (args.size() != 1) throw usage(name); - import_git_repo(mkpath(idx(args, 0)()), app); + import_git_repo(system_path(idx(args, 0)), app); } static void ======================================================================== --- file_io.hh 2b82c69614021cd23608ebdf7486716ed986514d +++ file_io.hh 87da82801eb51bc7297c917637e2895bd60ba8bc @@ -96,9 +96,16 @@ bool require_existing_path = true); // from anywhere, with native path +class absolute_tree_walker +{ +public: + virtual void visit_file(system_path const & path) = 0; + virtual ~absolute_tree_walker(); +} + void -walk_tree_absolute(fs::path const & path, - tree_walker & walker); +walk_tree_absolute(system_path const & path, + absolute_tree_walker & walker); ======================================================================== --- git.cc 71b9f618b658a4d5e176910c28077801c632b98b +++ git.cc 64bdb960fc0fb008a0e30e18aa7817a01ecc00eb @@ -94,7 +94,7 @@ struct git_db { - const fs::path path; + const system_path path; void get_object(const string type, const git_object_id objid, filebuf &fb); void get_object(const string type, const git_object_id objid, data &dat); @@ -105,7 +105,7 @@ // The @revision can be even head name. stack load_revs(const string revision, const set &exclude); - git_db(const fs::path &path_) : path(path_) { } + git_db(const system_path &path_) : path(path_) { } }; @@ -122,7 +122,7 @@ string base_branch; - git_history(const fs::path &path); + git_history(const system_path & path); }; @@ -158,7 +158,7 @@ F("git command %s failed") % str); fb.open(tmpfile.c_str(), ios::in); close(fd); - fs::remove(tmpfile); + delete_file(system_path(tmpfile)); } @@ -214,7 +214,7 @@ char revbuf[41]; stream.getline(revbuf, 41); if (strlen(revbuf) < 40) - continue; + continue; L(F("noted revision %s") % revbuf); st.push(git_object_id(string(revbuf))); } @@ -282,19 +282,19 @@ string fullname(prefix + name); if (mode & 040000) // directory - import_git_tree(git, app, gitoid, manifest, fullname + '/', attrs); + import_git_tree(git, app, gitoid, manifest, fullname + '/', attrs); else { - if (mode & 0100) // executable - { - L(F("marking '%s' as executable") % fullname); - attrs[fullname]["execute"] = "true"; - } + if (mode & 0100) // executable + { + L(F("marking '%s' as executable") % fullname); + attrs[fullname]["execute"] = "true"; + } - file_id fid = import_git_blob(git, app, gitoid); - L(F("entry monoid [%s]") % fid.inner()); - manifest.insert(manifest_entry(file_path(fullname), fid)); - } + file_id fid = import_git_blob(git, app, gitoid); + L(F("entry monoid [%s]") % fid.inner()); + manifest.insert(manifest_entry(file_path(fullname), fid)); + } } ++git.n_objs; @@ -330,7 +330,7 @@ revision_id rid = frontier.front(); frontier.pop(); if (seen.find(rid) != seen.end()) - continue; + continue; seen.insert(rid); revision_set rev; @@ -341,22 +341,22 @@ 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 gitrid = cv(); + // This is a GIT commit, then. + cert_value cv; + decode_base64(certs[0].inner().value, cv); + git_object_id gitrid = cv(); - git.commitmap[gitrid()] = make_pair(rid, rev.new_manifest); + git.commitmap[gitrid()] = make_pair(rid, rev.new_manifest); - git_heads.insert(gitrid); - continue; // stop traversing in this direction - } + git_heads.insert(gitrid); + continue; // stop traversing in this direction + } for (edge_map::const_iterator e = rev.edges.begin(); - e != rev.edges.end(); ++e) - { - frontier.push(edge_old_revision(e)); - } + e != rev.edges.end(); ++e) + { + frontier.push(edge_old_revision(e)); + } } } @@ -383,7 +383,7 @@ revision_id rid = frontier.front(); frontier.pop(); if (seen.find(rid) != seen.end()) - continue; + continue; seen.insert(rid); revision_set rev; @@ -394,25 +394,25 @@ 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(); + // 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); + git.commitmap[gitoid()] = make_pair(rid, rev.new_manifest); - if (gitoid == gitrid) - { - found_rid = rid; - return; - } - } + 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)); - } + e != rev.edges.end(); ++e) + { + frontier.push(edge_old_revision(e)); + } } N(false, @@ -450,9 +450,9 @@ manifest_map::const_iterator j = m_old.find(*i); manifest_map::const_iterator k = m_new.find(*i); if (j == m_old.end()) - cs.add_file(*i, manifest_entry_id(k)); + cs.add_file(*i, manifest_entry_id(k)); else if (k == m_new.end()) - cs.delete_file(*i); + cs.delete_file(*i); else if (!(manifest_entry_id(j) == manifest_entry_id(k))) cs.deltas.insert(std::make_pair(*i, std::make_pair(manifest_entry_id(j), manifest_entry_id(k)))); @@ -504,16 +504,16 @@ if (header && line.size() == 0) { - header = false; - continue; + header = false; + continue; } if (!header) { - L(F("LOG: %s") % line); - logmsg += line + '\n'; - continue; - } + L(F("LOG: %s") % line); + logmsg += line + '\n'; + continue; + } // HEADER // The order is always: tree, parent, author, committer @@ -525,83 +525,83 @@ L(F("HDR: '%s' => '%s'") % keyword % param); if (keyword == "tree") - { - attr_map attrs; - import_git_tree(git, app, param, manifest, "", attrs); + { + attr_map attrs; + import_git_tree(git, app, param, manifest, "", attrs); - // Write the attribute map - { - data attr_data; - write_attr_map(attr_data, attrs); + // Write the attribute map + { + data attr_data; + write_attr_map(attr_data, attrs); - file_id fid; - calculate_ident(attr_data, fid); - if (! app.db.file_version_exists(fid)) - app.db.put_file(fid, attr_data); + file_id fid; + calculate_ident(attr_data, fid); + if (! app.db.file_version_exists(fid)) + app.db.put_file(fid, attr_data); - file_path attr_path; - get_attr_path(attr_path); - manifest.insert(manifest_entry(attr_path, fid)); - } + file_path attr_path; + get_attr_path(attr_path); + manifest.insert(manifest_entry(attr_path, fid)); + } - calculate_ident(manifest, rev.new_manifest); - if (! app.db.manifest_version_exists(rev.new_manifest)) - { - manifest_data manidata; - write_manifest_map(manifest, manidata); - // TODO: put_manifest_with_delta() - app.db.put_manifest(rev.new_manifest, manidata); - } + calculate_ident(manifest, rev.new_manifest); + if (! app.db.manifest_version_exists(rev.new_manifest)) + { + manifest_data manidata; + write_manifest_map(manifest, manidata); + // TODO: put_manifest_with_delta() + app.db.put_manifest(rev.new_manifest, manidata); + } - L(F("[%s] Manifest ID: '%s'") % gitrid() % rev.new_manifest.inner()); - } + L(F("[%s] Manifest ID: '%s'") % gitrid() % rev.new_manifest.inner()); + } else if (keyword == "parent") - { - // FIXME: So far, in all the known GIT histories there was only a - // single "octopus" (>2 parents) merge. So this should be fixed - // to something a bit more history-friendly but it's not worth - // making a huge fuzz about it. - if (rev.edges.size() >= 2) - continue; + { + // FIXME: So far, in all the known GIT histories there was only a + // single "octopus" (>2 parents) merge. So this should be fixed + // to something a bit more history-friendly but it's not worth + // making a huge fuzz about it. + if (rev.edges.size() >= 2) + continue; - revision_id parent_rev; - manifest_id parent_mid; + revision_id parent_rev; + manifest_id parent_mid; - // given the topo order, we ought to have the parent hashed - except - // for incremental imports - map - >::const_iterator i = git.commitmap.find(param); - if (i != git.commitmap.end()) - { - parent_rev = i->second.first; - parent_mid = i->second.second; - } - else - { - historical_gitrev_to_monorev(git, app, param, parent_rev); - app.db.get_revision_manifest(parent_rev, parent_mid); - } + // given the topo order, we ought to have the parent hashed - except + // for incremental imports + map + >::const_iterator i = git.commitmap.find(param); + if (i != git.commitmap.end()) + { + parent_rev = i->second.first; + parent_mid = i->second.second; + } + else + { + historical_gitrev_to_monorev(git, app, param, parent_rev); + app.db.get_revision_manifest(parent_rev, parent_mid); + } - manifest_map parent_man; - L(F("parent revision '%s'") % parent_rev.inner()); - L(F("parent manifest '%s', loading...") % parent_mid.inner()); - app.db.get_manifest(parent_mid, parent_man); + manifest_map parent_man; + L(F("parent revision '%s'") % parent_rev.inner()); + L(F("parent manifest '%s', loading...") % parent_mid.inner()); + app.db.get_manifest(parent_mid, parent_man); - boost::shared_ptr changes(new change_set()); + boost::shared_ptr changes(new change_set()); - // complete_change_set(parent_man, manifest, *changes); - full_change_set(parent_man, manifest, *changes); + // complete_change_set(parent_man, manifest, *changes); + full_change_set(parent_man, manifest, *changes); - rev.edges.insert(make_pair(parent_rev, make_pair(parent_mid, changes))); - } + rev.edges.insert(make_pair(parent_rev, make_pair(parent_mid, changes))); + } else if (keyword == "committer") - { - parse_person_line(param, committer, commit_time); - } + { + parse_person_line(param, committer, commit_time); + } else if (keyword == "author") - { - parse_person_line(param, author, author_time); - } + { + parse_person_line(param, author, author_time); + } } revision_id rid; @@ -682,7 +682,7 @@ else { ui.warn(F("Warning: GIT tag '%s' (%s) does not tag a revision but a %s. Skipping...") - % name % gitoid() % type); + % name % gitoid() % type); return false; } } @@ -703,10 +703,10 @@ cert c = i->inner(); decode_base64(c.value, cname); if (cname == name) - { - L(F("tag already exists")); - return; - } + { + L(F("tag already exists")); + return; + } } revision_id rev; @@ -720,7 +720,7 @@ class tags_tree_walker - : public tree_walker + : public absolute_tree_walker { git_history & git; app_state & app; @@ -729,25 +729,26 @@ : git(g), app(a) { } - virtual void visit_file(file_path const & path) + virtual void visit_file(system_path const & path) { data refdata; - L(F("Processing tag file '%s'") % path()); - read_data(file_path(git.db.path.string() + "/refs/tags/" + path()), refdata); - import_unresolved_git_tag(git, app, path(), refdata().substr(0, 40)); + L(F("Processing tag file '%s'") % path); + read_data(path, refdata); + std::string tagname = fs::path(path.as_external(), fs::native).leaf(); + import_unresolved_git_tag(git, app, tagname, refdata().substr(0, 40)); } virtual ~tags_tree_walker() {} }; -git_history::git_history(const fs::path &path) +git_history::git_history(system_path const & path) : db(path), n_revs("revisions", "r", 1), n_objs("objects", "o", 10) { } void -import_git_repo(fs::path const & gitrepo, +import_git_repo(system_path const & gitrepo, app_state & app) { { @@ -762,7 +763,14 @@ F("path %s does not exist") % gitrepo.string()); N(fs::is_directory(gitrepo), F("path %s is not a directory") % gitrepo.string()); - putenv((char*)strdup((string("GIT_DIR=")+gitrepo.native_directory_string()).c_str())); + require_path_is_directory(gitrepo, + F("repo %s does not exist") % gitrepo, + F("repo %s is not a directory") % gitrepo); + + { + char * env_entry = stdrup((string("GIT_DIR=") + gitrepo.as_external()).c_str()); + putenv(env_entry); + } N(app.branch_name() != "", F("need base --branch argument for importing")); @@ -779,19 +787,19 @@ while (!revs.empty()) { - ui.set_tick_trailer(revs.top()()); - import_git_commit(git, app, revs.top()); - revs.pop(); + ui.set_tick_trailer(revs.top()()); + import_git_commit(git, app, revs.top()); + revs.pop(); } ui.set_tick_trailer(""); guard.commit(); } - fs::path tags_tree = gitrepo / "refs/tags"; - if (fs::exists(tags_tree)) + system_path tags_tree = gitrepo / "refs/tags"; + if (path_exists(tags_tree)) { - N(fs::is_directory(tags_tree), - F("path %s is not a directory") % tags_tree.string()); + N(directory_exists(tags_tree), + F("path %s is not a directory") % tags_tree); transaction_guard guard(app.db); app.db.ensure_open(); @@ -808,7 +816,7 @@ #else // WIN32 void -import_git_repo(fs::path const & gitrepo, +import_git_repo(system_path const & gitrepo, app_state & app) { E("git import not supported on win32"); ======================================================================== --- git.hh 215071ed5af0e65bc816835dcb9188e6467c1ba0 +++ git.hh a990b78ee920f114adbaa017e28fcf9220221663 @@ -9,6 +9,6 @@ #include "vocab.hh" #include "database.hh" -void import_git_repo(fs::path const & gitrepo, app_state & app); +void import_git_repo(system_path const & gitrepo, app_state & app); #endif // __GIT_IMPORT_HH__