Philip Martin wrote on Mon, Mar 19, 2012 at 17:25:22 +0000: > Philip Martin <philip.mar...@wandisco.com> writes: > > > I can reproduce ove ra_local: > > > > svnadmin create repo > > svn mkdir -mm file://`pwd`/repo/A > > svn mkdir -mm file://`pwd`/repo/B > > svn co file://`pwd`/repo wc1 > > svn co file://`pwd`/repo wc2 > > svn ps svn:mergeinfo /P:2 wc1/A > > svn ps svn:mergeinfo /Q:2 wc2/B > > svn mkdir wc1/X > > svn mkdir wc2/Y > > svn ci -mm wc1 & svn ci -mm wc2 & wait > > > > Gives: > > > > Sending wc1/A > > Adding wc1/X > > Sending wc2/B > > Adding wc2/Y > > > > Committed revision 3. > > svn: E160004: Commit failed (details follow): > > svn: E160004: predecessor count for the root node-revision is wrong: found > > 3, committing r4 > > This is the problem code in libsvn_fs_fs/tree.c:merge > > SVN_ERR(svn_fs_fs__dag_get_predecessor_count(&pred_count, source, pool)); > SVN_ERR(update_ancestry(fs, source_id, target_id, target_path, > pred_count, pool)); > > if (svn_fs_fs__fs_supports_mergeinfo(fs)) > SVN_ERR(svn_fs_fs__dag_increment_mergeinfo_count(target, > mergeinfo_increment, > pool)); > > > target is dag_node_t* which is opaque outside dag.c and > target->node_revision->predecessor_count is 3 when we reach the above > code. > > update_ancestry rewrites the file repo/db/transactions/2-2.txn/node.0.0 > with the correctly updated value "count: 4" but nothing updates > target->node_revision->predecessor_count in memory. > > svn_fs_fs__dag_increment_mergeinfo_count then rewrites > repo/db/transactions/2-2.txn/node.0.0 > pulling the old value of target->node_revision->predecessor_count from > memory and putting "count: 3" back in the file. > > If I use the debugger to manually set target->node_revision to NULL > inside svn_fs_fs__dag_increment_mergeinfo_count then the commit works. > I'm not exactly sure how all the FSFS caching layers are supposed to > interact. Is tree.c:update_ancestry supposed to update the in-memory > predecessor_count? Should there be a svn_fs_fs__dag_xxx function to > change the predecessor count? Should target->node_revision be set to > NULL soemwehere? Something else?
Just a note that another option here is for merge() to re-fetch 'dag_node_t *target' via dag.h APIs, to get another struct with a fresh (actually: not yet populated) cache ->noderev member.