# # # patch "ChangeLog" # from [57449324c3ec3774545b43e7efb6fbf7bb6458c2] # to [b70936c17f7dc2bd0e357f931e85c61086d4d381] # # patch "rcs_import.cc" # from [e9c6eb75a9e8080fd1ad5c48f940941115bfee14] # to [dd0852c19a2fb522abc49b2e5e5f17326fae48ab] # # patch "tests/t_cvsimport_branch.at" # from [bbc7bdc1acb7226c6ebd72f649350403feba72ca] # to [e3ebda84424188ade95fe676a13148e43563105a] # # patch "tests/t_cvsimport_branch2.at" # from [f9163b0a6f7b57369626cce2e7d2590611ed56ff] # to [b2dbbd9398ec67908425efa499bc0f2e2e1e7fab] # ============================================================ --- ChangeLog 57449324c3ec3774545b43e7efb6fbf7bb6458c2 +++ ChangeLog b70936c17f7dc2bd0e357f931e85c61086d4d381 @@ -1,3 +1,15 @@ +2006-04-06 Markus Schiltknecht + + * rcs_import.cc: Moved cvs_event::operator< out of the + struct definition. + Now calling 'note_branchpoint' and adding a branch event + only if curr_commit is alive. Likewise with + note_commit_following_branchpoint + + * tests/t_cvsimport_branch.at, tests/t_cvsimport_branch2.at: + added sleeps to allow cvs_import to distinguish branches + and commits by their timestamp. + 2006-04-07 Satoru SATOH * po/ja.po: Updated Japanese translation. ============================================================ --- rcs_import.cc e9c6eb75a9e8080fd1ad5c48f940941115bfee14 +++ rcs_import.cc dd0852c19a2fb522abc49b2e5e5f17326fae48ab @@ -89,10 +89,7 @@ vector tags; shared_ptr branch; - bool operator<(cvs_event const & other) const - { - return time < other.time; - } + bool operator<(cvs_event const & other) const; }; struct @@ -331,6 +328,24 @@ } +bool cvs_event::operator<(cvs_event const & other) const +{ + time_t this_time, other_time; + + if (type == ET_BRANCH) + this_time = branch->branch_time; + else + this_time = time; + + if (other.type == ET_BRANCH) + other_time = other.branch->branch_time; + else + other_time = other.time; + + return this_time < other_time; +} + + // piece table stuff struct piece; @@ -645,35 +660,45 @@ cvs.push_branch(i->second, false); shared_ptr b = cvs.stk.top(); if (curr_commit.alive) - b->live_at_beginning[cvs.curr_file_interned] = curr_commit.version; - b->note_branchpoint(curr_commit.time); + { + b->live_at_beginning[cvs.curr_file_interned] = curr_commit.version; + b->note_branchpoint(curr_commit.time); + } cvs.pop_branch(); - // write a branch event - cvs_event be(ET_BRANCH, 0, curr_commit.path, cvs); - be.branch = b; - cvs.stk.top()->append_event(be); - L(FL("added branch event for file %s in branch %s") - % cvs.path_interner.lookup(curr_commit.path) - % i->second); + // (ms) should this better be a '!is_synthetic_branchroot'? + if (curr_commit.alive) + { + // write a branch event + cvs_event be(ET_BRANCH, 0, curr_commit.path, cvs); + be.branch = b; + cvs.stk.top()->append_event(be); + L(FL("added branch event for file %s in branch %s") + % cvs.path_interner.lookup(curr_commit.path) + % i->second); + } } } - // mark the ending-of-branch time of this file if we're just past a - // branchpoint - range = cvs.branchpoints.equal_range(next_version); - if (range.first != cvs.branchpoints.end() - && range.first->first == next_version) + if (!curr_commit.is_synthetic_branch_root) { - for (ity i = range.first; i != range.second; i++) + // mark the ending-of-branch time of this file if we're just past a + // branchpoint + range = cvs.branchpoints.equal_range(next_version); + if (range.first != cvs.branchpoints.end() + && range.first->first == next_version) { - cvs.push_branch(i->second, false); - shared_ptr b = cvs.stk.top(); - b->note_commit_following_branchpoint(curr_commit.time); - cvs.pop_branch(); - L(FL("noted following commit for file %s in branch %s") - % cvs.path_interner.lookup(curr_commit.path) - % i->second); + for (ity i = range.first; i != range.second; i++) + { + cvs.push_branch(i->second, false); + shared_ptr b = cvs.stk.top(); + b->note_commit_following_branchpoint(curr_commit.time); + cvs.pop_branch(); + L(FL("noted following commit for file %s in branch %s [t:%d]") + % cvs.path_interner.lookup(curr_commit.path) + % i->second + % curr_commit.time); + } } } @@ -1144,7 +1169,7 @@ cluster_consumer cons(cvs, app, branchname, *branch, n_revs); unsigned long commits_remaining = branch->lineage.size(); - for (vector::const_iterator i = branch->lineage.begin(); + for (vector::iterator i = branch->lineage.begin(); i != branch->lineage.end(); ++i) { commits_remaining--; @@ -1159,6 +1184,8 @@ } else { + // correct the cvs_event time of the branch event + i->time = i->branch->branch_time; L(FL("examining next event: branch [t:%d] [p:%s]\n") % i->time % cvs.path_interner.lookup(i->path)); @@ -1357,7 +1384,7 @@ I(cvs.stk.size() == 1); - //check branch times + // check branch times for(map >::const_iterator i = cvs.branches.begin(); i != cvs.branches.end(); ++i) { @@ -1397,7 +1424,10 @@ ticker n_revs(_("revisions"), "r", 1); - // first, sort the lineages of the trunk and all branches + // First, sort the lineages of the trunk and all branches. Thanks to the + // logic in the 'operator<' this correctly handles branch events, which + // have their time stored in branch->branch_time. + // This is updated in import_branch later on. L(FL("sorting lineage of trunk\n")); stable_sort(cvs.trunk->lineage.begin(), cvs.trunk->lineage.end()); for(map >::const_iterator i = cvs.branches.begin(); @@ -1722,6 +1752,7 @@ else if (c.type == ET_BRANCH) { /* set the parent revision id of the branch */ + L(FL("setting the parent revision id of branch at %d") % c.branch->branch_time); c.branch->parent_rid = parent_rid; c.branch->has_parent_rid = true; } ============================================================ --- tests/t_cvsimport_branch.at bbc7bdc1acb7226c6ebd72f649350403feba72ca +++ tests/t_cvsimport_branch.at e3ebda84424188ade95fe676a13148e43563105a @@ -78,26 +78,36 @@ AT_CHECK(cvs -d $CVSROOT add testdir/changelog, [], [ignore], [ignore]) AT_CHECK(cvs -d $CVSROOT commit -m 'initial import' testdir/file1 testdir/file2 testdir/changelog, [], [ignore], [ignore]) +AT_CHECK(sleep 2) + # commit first changes AT_CHECK(cp file1.1 testdir/file1) AT_CHECK(cp changelog.1 testdir/changelog) AT_CHECK(cvs -d $CVSROOT commit -m 'first commit' testdir/file1 testdir/changelog, [], [ignore], [ignore]) +AT_CHECK(sleep 2) + # now we create a branch AT_CHECK(cd testdir; cvs -d $CVSROOT tag -b branched, [], [ignore], [ignore]) AT_CHECK(cd testdir; cvs -d $CVSROOT up -r branched, [], [ignore], [ignore]) +AT_CHECK(sleep 2) + # alter the files on the branch AT_CHECK(cp file2.1 testdir/file2) AT_CHECK(cp changelog.3 testdir/changelog) AT_CHECK(cvs -d $CVSROOT commit -m 'commit on branch' testdir/file2 testdir/changelog, [], [ignore], [ignore]) +AT_CHECK(sleep 2) + # and create some mainline changes after the branch AT_CHECK(cvs -d $CVSROOT up -A, [], [ignore], [ignore]) AT_CHECK(cp file1.2 testdir/file1) AT_CHECK(cp changelog.2 testdir/changelog) AT_CHECK(cvs -d $CVSROOT commit -m 'commit on mainline after branch' testdir/file1 testdir/changelog, [], [ignore], [ignore]) +AT_CHECK(sleep 2) + # import into monotone and check presence of files AT_CHECK(MTN --branch=test cvs_import $CVSROOT/testdir, [], [ignore], [ignore]) ============================================================ --- tests/t_cvsimport_branch2.at f9163b0a6f7b57369626cce2e7d2590611ed56ff +++ tests/t_cvsimport_branch2.at b2dbbd9398ec67908425efa499bc0f2e2e1e7fab @@ -120,36 +120,50 @@ AT_CHECK(cvs -d $CVSROOT add testdir/changelog, [], [ignore], [ignore]) AT_CHECK(cvs -d $CVSROOT commit -m 'initial import' testdir/file1 testdir/file2 testdir/changelog, [], [ignore], [ignore]) +AT_CHECK(sleep 2) + # commit first changes AT_CHECK(cp file1.1 testdir/file1) AT_CHECK(cp changelog.1 testdir/changelog) AT_CHECK(cvs -d $CVSROOT commit -m 'first commit' testdir/file1 testdir/changelog, [], [ignore], [ignore]) +AT_CHECK(sleep 2) + # now we create a branch A AT_CHECK(cd testdir; cvs -d $CVSROOT tag -b A, [], [ignore], [ignore]) AT_CHECK(cd testdir; cvs -d $CVSROOT up -r A, [], [ignore], [ignore]) +AT_CHECK(sleep 2) + # alter the files on branch A AT_CHECK(cp file2.1 testdir/file2) AT_CHECK(cp changelog.3 testdir/changelog) AT_CHECK(cvs -d $CVSROOT commit -m 'commit on branch A' testdir/file2 testdir/changelog, [], [ignore], [ignore]) +AT_CHECK(sleep 2) + # branch again into B AT_CHECK(cd testdir; cvs -d $CVSROOT tag -b B, [], [ignore], [ignore]) AT_CHECK(cd testdir; cvs -d $CVSROOT up -r B, [], [ignore], [ignore]) # branch B is left untouched +AT_CHECK(sleep 2) + # go back to A and branch into C AT_CHECK(cvs -d $CVSROOT up -r A -A, [], [ignore], [ignore]) AT_CHECK(cd testdir; cvs -d $CVSROOT tag -b C, [], [ignore], [ignore]) AT_CHECK(cd testdir; cvs -d $CVSROOT up -r C, [], [ignore], [ignore]) +AT_CHECK(sleep 2) + # add a file3 AT_CHECK(cp file3.0 testdir/file3) AT_CHECK(cp changelog.4 testdir/changelog) AT_CHECK(cd testdir; cvs -d $CVSROOT add file3, [], [ignore], [ignore]) AT_CHECK(cd testdir; cvs -d $CVSROOT commit -m 'commit on branch C' file3 changelog, [], [ignore], [ignore]) +AT_CHECK(sleep 2) + # branch into D AT_CHECK(cd testdir; cvs -d $CVSROOT tag -b D, [], [ignore], [ignore]) AT_CHECK(cd testdir; cvs -d $CVSROOT up -r D, [], [ignore], [ignore]) @@ -159,12 +173,16 @@ AT_CHECK(cp changelog.5 testdir/changelog) AT_CHECK(cd testdir; cvs -d $CVSROOT commit -m 'commit on branch D' file1 file2 file3 changelog, [], [ignore], [ignore]) +AT_CHECK(sleep 2) + # and create some mainline changes after the branch AT_CHECK(cvs -d $CVSROOT up -A, [], [ignore], [ignore]) AT_CHECK(cp file1.2 testdir/file1) AT_CHECK(cp changelog.2 testdir/changelog) AT_CHECK(cvs -d $CVSROOT commit -m 'commit on mainline after branch' testdir/file1 testdir/changelog, [], [ignore], [ignore]) +AT_CHECK(sleep 2) + # import into monotone and check presence of files AT_CHECK(MTN --branch=test cvs_import $CVSROOT/testdir, [], [ignore], [ignore])