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.

Reply via email to