# # # patch "rcs_import.cc" # from [1fa382388d113382e204212cbc4ab7b65a5a4937] # to [bd87ac56d7655d81594254f944692d97b79a239b] # # patch "tests/importing_cvs_branches4/__driver__.lua" # from [e1c22ea7eb81e795c01e4e456185cc7bab2a837b] # to [b3fbd5e9fb292e4f27221538dbd69f41c72bd5c6] # # patch "tests/importing_cvs_branches4/cvs-repository/test/file1,v" # from [a503a0993e33ed98011760a13f149b779553cd3b] # to [15b368b5813a45731fa753a35bffba70a983ada2] # # patch "tests/importing_cvs_branches4/makerepo.sh" # from [8a68a1be17de13d40647c6eeb872f0b2b3171637] # to [0b94fd9b0d5643a2f4542b0adea152e99b065186] # # patch "tests/importing_cvs_files_with_identical_logs3/__driver__.lua" # from [79cc9512fa0f48b368d70b310c97061b0bae9cfd] # to [84ba24f106105034d0c0ce2902b14a23b240fd53] # ============================================================ --- rcs_import.cc 1fa382388d113382e204212cbc4ab7b65a5a4937 +++ rcs_import.cc bd87ac56d7655d81594254f944692d97b79a239b @@ -94,6 +94,8 @@ typedef enum ET_BRANCH_END = 4 } event_type; +typedef u64 time_i; + struct cvs_history; struct cvs_event_digest @@ -179,16 +181,16 @@ public: cvs_event { public: - time_t given_time; - time_t adj_time; + time_i given_time; + time_i adj_time; cvs_path path; cvs_blob_index bi; vector< cvs_event_ptr > dependencies; vector< cvs_event_ptr > dependents; - cvs_event(const cvs_path p, const time_t ti) + cvs_event(const cvs_path p, const time_i ti) : given_time(ti), - adj_time(ti), + adj_time(ti * 100), path(p) { }; @@ -214,7 +216,7 @@ public: cvs_rcs_version rcs_version; bool alive; - cvs_commit(const cvs_path p, const time_t ti, const cvs_mtn_version v, + cvs_commit(const cvs_path p, const time_i ti, const cvs_mtn_version v, const cvs_rcs_version r, const cvs_authorclog ac, const bool al) : cvs_event(p, ti), @@ -242,7 +244,7 @@ public: branchname(bn) { }; - cvs_branch_point(const cvs_path p, const cvs_branchname bn, time_t ti) + cvs_branch_point(const cvs_path p, const cvs_branchname bn, time_i ti) : cvs_event(p, ti), branchname(bn) { }; @@ -265,7 +267,7 @@ public: branchname(bn) { }; - cvs_branch_start(const cvs_path p, const cvs_branchname bn, time_t ti) + cvs_branch_start(const cvs_path p, const cvs_branchname bn, time_i ti) : cvs_event(p, ti), branchname(bn) { }; @@ -281,7 +283,7 @@ public: : public cvs_branch_start { public: - cvs_branch_end(const cvs_path p, const cvs_branchname bn, time_t ti) + cvs_branch_end(const cvs_path p, const cvs_branchname bn, time_i ti) : cvs_branch_start(p, bn, ti) { }; @@ -298,7 +300,7 @@ public: public: cvs_tag tag; - cvs_tag_point(const cvs_path p, const time_t ti, const cvs_tag ta) + cvs_tag_point(const cvs_path p, const time_i ti, const cvs_tag ta) : cvs_event(p, ti), tag(ta) { }; @@ -429,12 +431,13 @@ public: cached_deps_are_sorted = false; } - time_t get_avg_time(void) const + u64 get_avg_time(void) const { - long long avg = 0; + time_i avg = 0; for (blob_event_iter i = events.begin(); i != events.end(); ++i) avg += (*i)->adj_time; - return (time_t) avg / events.size(); + avg /= events.size(); + return avg; } void sort_events(void); @@ -1080,7 +1083,7 @@ get_cheapest_violation_to_solve(list > stack; + stack< pair< cvs_event_ptr, time_i > > stack; set< cvs_event_ptr > done; cvs_event_ptr dep = i->first; cvs_event_ptr ev = i->second; @@ -1097,7 +1100,7 @@ get_cheapest_violation_to_solve(list > stack; + stack< pair< cvs_event_ptr, time_i > > stack; set< cvs_event_ptr > done; cvs_event_ptr dep = solution.first->first; cvs_event_ptr ev = solution.first->second; @@ -1170,7 +1173,7 @@ solve_violation(cvs_history & cvs, t_sol while (!stack.empty()) { cvs_event_ptr e = stack.top().first; - time_t time_goal = stack.top().second; + time_i time_goal = stack.top().second; stack.pop(); done.insert(e); @@ -1194,7 +1197,7 @@ solve_violation(cvs_history & cvs, t_sol while (!stack.empty()) { cvs_event_ptr e = stack.top().first; - time_t time_goal = stack.top().second; + time_i time_goal = stack.top().second; stack.pop(); done.insert(e); @@ -2026,10 +2029,10 @@ class split_by_time class split_by_time : public split_decider_func { - time_t split_point; + u64 split_point; public: - split_by_time(time_t const ti) + split_by_time(time_i const ti) : split_point(ti) { }; @@ -2513,10 +2516,11 @@ public: // single blob split points: search only for intra-blob dependencies // and return split points to resolve these dependencies. -time_t +time_i get_best_split_point(cvs_history & cvs, cvs_blob_index bi) { - list< pair > ib_deps; + list< pair > ib_deps; + list simultaneous_deps; // Collect the conflicting intra-blob dependencies, storing the // timestamps of both events involved. @@ -2546,8 +2550,9 @@ get_best_split_point(cvs_history & cvs, for (blob_event_iter j = i + 1; j != cvs.blobs[bi].end(); ++j) if ((*i)->path == (*j)->path) { - I((*i)->adj_time != (*j)->adj_time); - if ((*i)->adj_time > (*j)->adj_time) + if ((*i)->adj_time == (*j)->adj_time) + simultaneous_deps.push_back((*i)->adj_time); + else if ((*i)->adj_time > (*j)->adj_time) ib_deps.push_back(make_pair((*j)->adj_time, (*i)->adj_time)); else ib_deps.push_back(make_pair((*i)->adj_time, (*j)->adj_time)); @@ -2576,10 +2581,9 @@ get_best_split_point(cvs_history & cvs, // that, we simply count how many intra-blob deps a split between any two // events would resolve. - typedef list< pair >::iterator dep_ity; + typedef list< pair >::iterator dep_ity; - vector< pair > results; - set< time_t > event_times; + set< time_i > event_times; for (dep_ity i = ib_deps.begin(); i != ib_deps.end(); ++i) { if (event_times.find(i->first) == event_times.end()) @@ -2591,20 +2595,22 @@ get_best_split_point(cvs_history & cvs, if (event_times.size() <= 0) { + I(simultaneous_deps.empty()); + W(F("unable to split blob %d") % bi); return 0; } - set::const_iterator last, curr; + set::const_iterator last, curr; last = event_times.begin(); curr = last; curr++; - pair best_split_range = make_pair(0, 0); + pair best_split_range = make_pair(0, 0); vector deps_resolved_by_best_split; unsigned int best_score = 0; for ( ; curr != event_times.end(); ++curr) { - time_t curr_split_point = *last + (*curr - *last) / 2; + time_i curr_split_point = *last + (*curr - *last) / 2; // just to get everything right here... I(*curr > *last); @@ -2637,7 +2643,7 @@ get_best_split_point(cvs_history & cvs, // not involved in the dependency cycle, but for which we need to // decide where to put them. - time_t best_split_point = best_split_range.first + + time_i best_split_point = best_split_range.first + (best_split_range.second - best_split_range.first) / 2; L(FL("Best split range: %d - %d (@%d)") @@ -2657,8 +2663,8 @@ split_cycle(cvs_history & cvs, set< cvs_ L(FL("choosing a blob to split (out of %d blobs)") % cycle_members.size()); typedef set::const_iterator cm_ity; - time_t largest_gap = 0; - time_t largest_gap_at = 0; + time_i largest_gap = 0; + time_i largest_gap_at = 0; int largest_gap_blob = -1; for (cm_ity cc = cycle_members.begin(); cc != cycle_members.end(); ++cc) @@ -2683,7 +2689,7 @@ split_cycle(cvs_history & cvs, set< cvs_ last_ev = this_ev; this_ev = *ity; - time_t time_diff = this_ev->adj_time - last_ev->adj_time; + time_i time_diff = this_ev->adj_time - last_ev->adj_time; if (time_diff > largest_gap) { largest_gap = time_diff; @@ -3577,7 +3583,8 @@ blob_consumer::operator()(cvs_blob_index I(app.db.put_revision(new_rid, rev)); { - time_t commit_time = blob.get_avg_time(); + time_i avg_time = blob.get_avg_time(); + time_t commit_time = avg_time / 100; string author, changelog; cvs.split_authorclog(ce->authorclog, author, changelog); ============================================================ --- tests/importing_cvs_branches4/__driver__.lua e1c22ea7eb81e795c01e4e456185cc7bab2a837b +++ tests/importing_cvs_branches4/__driver__.lua b3fbd5e9fb292e4f27221538dbd69f41c72bd5c6 @@ -17,13 +17,14 @@ writefile("file1-1.1", "version 1.1 of t -- author. writefile("file1-1.1", "version 1.1 of test file1\n") +writefile("file1-1.1.2.1", "version 1.1.2.1 of test file1\n") writefile("file1-1.1.4.1", "version 1.1.4.1 of test file1\n") writefile("file2-1.1", "version 1.1 of test file2\n") writefile("file2-1.1.2.1", "version 1.1.2.1 of test file2\n") -- import into monotone and check presence of files -xfail(mtn("--branch=test", "cvs_import", "cvs-repository/test"), 0, false, false) +check(mtn("--branch=test", "cvs_import", "cvs-repository/test"), 0, false, false) -- We currently don't handle blobs, which seem to belong to two different -- branches. See the branch_sanitizer. @@ -42,7 +43,7 @@ check(samefile("file2-1.1", "maindir/fil check(samefile("file2-1.1", "maindir/file2")) -- check for correctness of the files in branch A -check(samefile("file1-1.1", "branchA/file1")) +check(samefile("file1-1.1.2.1", "branchA/file1")) check(samefile("file2-1.1.2.1", "branchA/file2")) -- check for correctness of the files in branch B ============================================================ --- tests/importing_cvs_branches4/cvs-repository/test/file1,v a503a0993e33ed98011760a13f149b779553cd3b +++ tests/importing_cvs_branches4/cvs-repository/test/file1,v 15b368b5813a45731fa753a35bffba70a983ada2 @@ -59,6 +59,6 @@ a1 1 text @d1 1 a1 1 -xxx +version 1.1.2.1 of test file1 @ ============================================================ --- tests/importing_cvs_branches4/makerepo.sh 8a68a1be17de13d40647c6eeb872f0b2b3171637 +++ tests/importing_cvs_branches4/makerepo.sh 0b94fd9b0d5643a2f4542b0adea152e99b065186 @@ -28,8 +28,8 @@ cvs update -r A cvs update -r A # a commit which will later conflict with one in branch B +echo "version 1.1.2.1 of test file1" > file1 echo "version 1.1.2.1 of test file2" > file2 -echo "xxx" > file1 cvs commit -m "conflicting commit" file1 file2 # go back to the trunk and branch into B ============================================================ --- tests/importing_cvs_files_with_identical_logs3/__driver__.lua 79cc9512fa0f48b368d70b310c97061b0bae9cfd +++ tests/importing_cvs_files_with_identical_logs3/__driver__.lua 84ba24f106105034d0c0ce2902b14a23b240fd53 @@ -5,10 +5,5 @@ check(get("cvs-repository")) check(get("cvs-repository")) -- import into monotone -xfail(mtn("--branch=testbranch", "cvs_import", "cvs-repository/test"), 0, false, false) +check(mtn("--branch=testbranch", "cvs_import", "cvs-repository/test"), 0, false, false) --- This fails, because some event times are unfortunately adjusted, so --- that they exactly match another, conflicting event is the blob, which --- needs to be split. Needs better get_best_split_point logic (i.e. split --- a blob between two events with exactly the same timestamps). -