On Wed, Mar 11, 2015 at 6:04 PM, Julian Foad <julianf...@btopenworld.com> wrote:
> Hi Stefan. > > A few comments below... > Thanks for the review, Julian! Uncovered a bug and fixed all the things you found: > ----- Original Message ----- > > URL: http://svn.apache.org/r1665894 > [...] > > Modified: subversion/trunk/subversion/libsvn_fs_fs/tree.c > > > ============================================================================== > > --- subversion/trunk/subversion/libsvn_fs_fs/tree.c (original) > > +++ subversion/trunk/subversion/libsvn_fs_fs/tree.c Wed Mar 11 15:03:17 > 2015 > [...] > > @@ -1344,19 +1349,11 @@ fs_node_relation(svn_fs_node_relation_t > > return SVN_NO_ERROR; > > } > > > > - /* Nodes from different transactions are never related. */ > > - if (root_a->is_txn_root && root_b->is_txn_root > > - && strcmp(root_a->txn, root_b->txn)) > > - { > > - *relation = svn_fs_node_unrelated; > > - return SVN_NO_ERROR; > > - } > > - > > /* Are both (!) root paths? Then, they are related and we only test > how > > * direct the relation is. */ > > if (a_is_root_dir && b_is_root_dir) > > { > > - *relation = root_a->rev == root_b->rev > > + *relation = ((root_a->rev == root_b->rev) && !different_txn) > > ? svn_fs_node_same > > : svn_fs_node_common_ancestor; > > That says: the root node-rev of rX is never the same as that of rY when X > != Y. > > Can I just double-check: is that guaranteed to be true for every FSFS > repository? It's possible to commit an empty revision. The > "svn_fs_fs__create_txn" function ensures the new txn always has a new > root node-rev, but is it in any way possible that a repository could > exist where an (empty) commit has bypassed that code path and ended up > with the root noderev of r11 the same as of r10? > That would not be a valid FSFS repository. Format 6 revisions and earlier end with a revision trailer that points to the root noderev and change list in that revision. Format 7 implies them as well albeit less explicitly. We check them explicitly in validate_root_noderev() and svn_fs_fs__verify_root(). It's probably fine, but it was a bit surprising to me to find this > requirement made explicit. Is that consistent with the rest of FSFS? > There are certainly places that assume that the root node is always available but I don't remember anything specific outside the consistency checks. If we were to allow for truly empty revisions in the future, then that would probably be a storage-only feature and the missing noderev structs would be created on-the-fly in the reader / parser function. > > return SVN_NO_ERROR; > > @@ -1365,21 +1362,35 @@ fs_node_relation(svn_fs_node_relation_t > > /* We checked for all separations between ID spaces (repos, txn). > > * Now, we can simply test for the ID values themselves. */ > > SVN_ERR(get_dag(&node, root_a, path_a, pool)); > > - id = svn_fs_fs__dag_get_id(node); > > - rev_item_a = *svn_fs_fs__id_rev_item(id); > > - node_id_a = *svn_fs_fs__id_node_id(id); > > + id_a = svn_fs_fs__dag_get_id(node); > > + node_id_a = *svn_fs_fs__id_node_id(id_a); > > > > SVN_ERR(get_dag(&node, root_b, path_b, pool)); > > - id = svn_fs_fs__dag_get_id(node); > > - rev_item_b = *svn_fs_fs__id_rev_item(id); > > - node_id_b = *svn_fs_fs__id_node_id(id); > > + id_b = svn_fs_fs__dag_get_id(node); > > + node_id_b = *svn_fs_fs__id_node_id(id_b); > > + > > + /* Noderevs from different nodes are unrelated. */ > > + if (!svn_fs_fs__id_part_eq(&node_id_a, &node_id_b)) > > + { > > + *relation = svn_fs_node_unrelated; > > + return SVN_NO_ERROR; > > + } > > > > - if (svn_fs_fs__id_part_eq(&rev_item_a, &rev_item_b)) > > + /* Noderevs have the same node-ID now. So, they *seem* to be related. > > + * > > + * Special case: Different txns may create the same (txn-local) node > ID. > > + * Only when they are committed can they actually be related to > others. */ > > + if (different_txn && node_id_a.revision == SVN_INVALID_REVNUM) > > + { > > + *relation = svn_fs_node_unrelated; > > + return SVN_NO_ERROR; > > + } > > I found this condition a bit difficult to understand. At first sight > it looks asymmetric, but that's because you already know the two > node-ids are equal so you only need to examine one to know that both > are created in their respective transactions. OK. > > The comment "Only when they are committed can they actually be related > to others" confused me. If a txn creates a new node-id, when *this* > txn is committed the node-id will definitely not be related to any > others. Only *later* commits may create new node-revs that are related > by having that same node-id. > > Would it be clearer to write: > > * Special case: Different txns may create the same (txn-local) node ID. > * These are not related to each other, nor to any other node ID so far. > */ > Committed as r1667090. r1667101 fixes another problem with that code. [...] > > Modified: subversion/trunk/subversion/tests/libsvn_fs/fs-test.c > > > ============================================================================== > > static svn_error_t * > > +check_txn_related(const svn_test_opts_t *opts, > > + apr_pool_t *pool) > > +{ > [...] > > + /*** Step I: Build up some state in our repository through a series > > + of commits */ > > + > > + /* This is the node graph we are testing. It contains one revision > (r1) > > + and two transactions, T1 and T2 - yet uncommitted. > > + > > + A is a file that exists in r1 (A-0) and gets modified in both txns. > > + C is a copy of A1 made in both txns. > > + B is a new node created in both txns > > + D is a file that exists in r1 (D-0) and never gets modified. > > + > > + +--A-0--+ D-0 > > + | | > > + +-----+ +-----+ > > + | | | | > > + B-1 C-T A-1 A-2 C-1 B-2 > > + */ > > + /* Revision 1 */ > [...] > > + /* Transaction 1 */ > [...] > > + /* Transaction 2 */ > [...] > > + > > + /*** Step II: Exhaustively verify relationship between all nodes in > > + existence. */ > [...] > > +} > > Can you add test cases for the root node-rev, because the code for > that is special-cased? > > (It's valid to copy the root, so you can create 'E' as a copy of the > root and test for relatedness between E and '/' in various revs/txnx.) > Done in r1667102. -- Stefan^2.