# # # patch "cvs_client.cc" # from [1731ab52251e166b7f7f06d87a0185fcb308d608] # to [d4fc961d1c95a24db48099a7a591313baf654d57] # # patch "cvs_sync.cc" # from [6c849e375b6ea67bdbc29d5e661979c5079804f9] # to [4513c1b1c7d15ded984a2e9aca23998f9709b6c7] # # patch "cvs_sync.hh" # from [387e299dc541a55e5522a15d3353ae2ef94eb275] # to [1429f43c5aa04ea1ab1b4bce7afc7504a49181b6] # # patch "tests/t_cvspull_cvsbranch.at" # from [dd49109af1d4638ec5355c78f7eb2a892c7e281c] # to [2b85e1e11c63947dcc83e385d878f7defd410392] # ============================================================ --- cvs_client.cc 1731ab52251e166b7f7f06d87a0185fcb308d608 +++ cvs_client.cc d4fc961d1c95a24db48099a7a591313baf654d57 @@ -1482,4 +1482,7 @@ for (std::map::const_iterator i=server_dir.begin(); i!=server_dir.end();++i) L(FL("server dir %s -> %s") % i->first % i->second); + // it is nearly certain that the server will be in a strange state now + // so reconnect + reconnect(); } ============================================================ --- cvs_sync.cc 6c849e375b6ea67bdbc29d5e661979c5079804f9 +++ cvs_sync.cc 4513c1b1c7d15ded984a2e9aca23998f9709b6c7 @@ -133,6 +133,16 @@ { return parts.size()&1; } +cvs_revision_nr cvs_revision_nr::get_branch_root() const +{ I(parts.size()>=4); + I(!(parts.size()&1)); // even number of digits + I(!parts[parts.size()-2]); // but last digit is zero + I(!(parts[parts.size()-1]&1)); // last digit is even + cvs_revision_nr result; + result.parts=std::vector(parts.begin(),parts.end()-2); + return result; +} + // cvs_repository ---------------------- // very short form to output in logs etc. @@ -292,7 +302,7 @@ result+= ")\n"; } result+= "Tags :\n"; - for (std::map >::const_iterator i=tags.begin(); + for (std::map >::const_iterator i=tags.begin(); i!=tags.end();++i) { result+= i->first + "(" + boost::lexical_cast(i->second.size()) + " files)\n"; } @@ -320,8 +330,9 @@ { MM(file); MM(tag); I(i->first==file); - std::map &tagslot=repo.tags[tag]; + std::map &tagslot=repo.tags[tag]; tagslot[file]=revision; + if (tag==repo.branch) repo.branch_point[file]=cvs_revision_nr(revision).get_branch_root(); } void cvs_repository::prime_log_cb::revision(const std::string &file,time_t checkin_time, @@ -857,7 +868,9 @@ MM(i->first); if (!branch.empty()) - args.push_back("-r"+branch); + { args.push_back("-r"+branch); + N(sync_since==-1, F("--since does not work on a side branch")); + } else args.push_back("-b"); ============================================================ --- cvs_sync.hh 387e299dc541a55e5522a15d3353ae2ef94eb275 +++ cvs_sync.hh 1429f43c5aa04ea1ab1b4bce7afc7504a49181b6 @@ -18,21 +18,27 @@ { std::vector parts; cvs_revision_nr(const std::string &x); + cvs_revision_nr() {} void operator++(); std::string get_string() const; bool is_branch() const; bool is_parent_of(const cvs_revision_nr &child) const; + // get the root of the side branch (1.1.1.1.0.6 => 1.1.1.1) + cvs_revision_nr get_branch_root() const; bool operator==(const cvs_revision_nr &b) const; bool operator<(const cvs_revision_nr &b) const; }; +// FIXME: future conversion to file_path +typedef std::string cvs_file_path; + struct file_state -{ time_t since_when; +{ time_t since_when; // boost::ptime std::string cvs_version; // cvs_revision_nr ? unsigned size; unsigned patchsize; bool dead; - std::string md5sum; + std::string md5sum; // hexenc hexenc sha1sum; // make this a file_id std::string log_msg; std::string author; @@ -53,14 +59,14 @@ typedef std::set::const_iterator cvs_file_state; // state of the files at a specific point in history, dead files do not occur here -typedef std::map cvs_manifest; +typedef std::map cvs_manifest; struct cvs_edge // careful this name is also used in cvs_import { std::string changelog; bool changelog_valid; std::string author; - time_t time; + time_t time; // boost::ptime mutable time_t time2; mutable revision_id delta_base; // delta encoded if !delta_base().empty() @@ -107,9 +113,11 @@ private: std::set edges; std::map::iterator> revision_lookup; - std::map files; + std::map files; // tag,file,rev - std::map > tags; + std::map > tags; + // the root of this branch (only applicable to side branches) + std::map branch_point; app_state &app; std::auto_ptr file_id_ticker; @@ -134,7 +142,7 @@ const std::set::iterator &e); void get_all_files(); void update(std::set::const_iterator s, - std::set::iterator s2,const std::string &file, + std::set::iterator s2,cvs_file_path const& file, std::string &contents); void store_checkout(std::set::iterator s2, const cvs_client::checkout &file, std::string &file_contents); @@ -148,18 +156,17 @@ // std::string is equivalent to data void store_contents(const data &contents, hexenc &sha1sum); -// void apply_delta(std::string &contents, const std::string &patch); void store_delta(const std::string &new_contents, const std::string &old_contents, const std::string &patch, const hexenc &from, hexenc &to); void cert_cvs(const cvs_edge &e, packet_consumer & pc); - cvs_file_state remember(std::set &s,const file_state &fs, std::string const& filename); + cvs_file_state remember(std::set &s,const file_state &fs, cvs_file_path const& filename); void join_edge_parts(std::set::iterator i); std::set::iterator last_known_revision(); std::set::iterator commit_mtn2cvs( std::set::iterator parent, const revision_id &rid, bool &fail); const cvs_manifest &get_files(const cvs_edge &e); // try harder (reconnect if something goes wrong) - struct checkout CheckOut2(const std::string &file, const std::string &revision); + struct checkout CheckOut2(const cvs_file_path &file, const std::string &revision); void takeover_dir(const std::string &path); void store_modules(); ============================================================ --- tests/t_cvspull_cvsbranch.at dd49109af1d4638ec5355c78f7eb2a892c7e281c +++ tests/t_cvspull_cvsbranch.at 2b85e1e11c63947dcc83e385d878f7defd410392 @@ -69,7 +69,8 @@ # pull into monotone -AT_CHECK(MONOTONE --branch=testbranch cvs_pull $CVSROOT test branch, [], [ignore], [ignore]) +AT_CHECK(echo MONOTONE --branch=testbranch cvs_pull $CVSROOT test branch, [], [ignore], [ignore]) +exit 1 # check presence of files