Improve the accuracy of the "Have props/contents changed between two nodes?" check for all three backends.
First, we consider props / text contents as equal whenever the same physical representation is being used - even if the uniquifiers differ. There is no such test for directories and it is not needed by any API, ATM. Secondly, file contents is considered equal when the SHA1 checksums match (same as in the working copy). We also compare the MD5 checksums as they are always available and offer a quick mismatch test.
Lastly, if the SHA1 is not available, we actually compare the reconstructed fulltexts - but only if the caller requires a strict equality test with no false negatives. The FS API currently calls the internal functionality in non-strict, i.e. "quick check" mode.
Property lists use a similar checking scheme. However, we limit the test to MD5 (FSFS, FSX only) and use a fulltext comparison in strict mode only if MD5s are not available. As a side-effect of the extra accuracy, the commit conflict detection / merge code in non-BDB now allows for equal directory property lists to be committed to the same node in concurrent transactions without creating a conflict.
The BDB implementation is the most straightforward of the three backends because the respective function are directly at the vtable level. We simply add checksum and fulltext comparison as needed.
In FSFS, the actual comparison lies deeper in the caller hierarchy and is being used by other functions as well. We need to replace the generic "is the rep equal" test by two tests, one for each kind of representation. They will then perform similar tests as in BDB but with more callers to update. The prop comparison will also use the MD5 checksums when available.
The FSX code has the same structure as FSFS but it does need to cater for legacy data. Therefore, the file contents check is much simpler and can always use the MD5 + SHA1 checksums.
* subversion/include/private/svn_fs_util.h (svn_fs__prop_lists_equal): Declare new private contents comparison API. * subversion/libsvn_fs_util/fs-util.c (svn_fs__prop_lists_equal): Implement it.
* subversion/libsvn_fs_base/dag.c (svn_fs_base__things_different): Ignore uniquifier since we are only interested in actual content differences. * subversion/libsvn_fs_base/tree.c (things_changed_args): Add the STRICT option to our parameter set. (txn_body_props_changed, txn_body_contents_changed): Add more comparisons to eliminate false positives as described above. (base_props_changed, base_contents_changed): FS API implementation is currently non-strict.
* subversion/libsvn_fs_fs/fs_fs.h (svn_fs_fs__noderev_same_rep_key): Drop old test function. (svn_fs_fs__file_text_rep_equal, svn_fs_fs__prop_rep_equal): Introduce separate APIs for different types of representations; provide more context such that we may query missing information. * subversion/libsvn_fs_fs/fs_fs.c (svn_fs_fs__noderev_same_rep_key): Drop old test function. (svn_fs_fs__file_text_rep_equal, svn_fs_fs__prop_rep_equal): Implement.
* subversion/libsvn_fs_fs/dag.h (svn_fs_fs__dag_things_different): Add STRICT option and provide a pool for FS queries as needed. * subversion/libsvn_fs_fs/dag.c (svn_fs_fs__dag_things_different): Update implementation to call the new comparison functions.
* subversion/libsvn_fs_fs/tree.c (fs_props_changed, fs_contents_changed): Update callers and use non-strict mode for these FS API functions. (merge): Adapt to API change and force strict prop comparison to prevent unnecessary conflicts.
* subversion/libsvn_fs_x/fs_x.h (svn_fs_x__noderev_same_rep_key): Drop old test function. (svn_fs_x__file_text_rep_equal): Similar to FSFS but with a simpler signature because there is no need to query for addition data. svn_fs_x__prop_rep_equal): Similar to FSFS. * subversion/libsvn_fs_x/fs_x.c (svn_fs_x__noderev_same_rep_key): Drop old test function. (svn_fs_x__file_text_rep_equal, svn_fs_x__prop_rep_equal): Implement.
Speed up 'svn log -g' to almost the same speed as 'svn log'. Also, provide a basis for speeding up other mergeinfo detection based code.
The problem is that svn_fs_path_change2_t used to report mergeinfo changes as simple prop changes. Since most files are being created with default props attached to them, this creates a lot of unnecessary property read and comparison operations.
The idea is to a derive a mergeinfo-mod flag from the FS propset function and store that in FSFS f7+ repositories (FSX will follow later). An extended svn_fs_path_change2_t makes the information visible to the user.
* subversion/include/svn_fs.h (svn_fs_path_change2_t): Add mergeinfo-mod as a tristate since we don't have that information in old repositories.
* subversion/libsvn_fs_util/fs-util.c (svn_fs__path_change_create_internal): Make sure the new member is always initialized properly.
* subversion/libsvn_repos/log.c (fs_mergeinfo_changed): Use the new information to skip unnecessary node prop processing.
* subversion/libsvn_fs_fs/structure (): Extend documentation to cover the new flag as well.
* subversion/libsvn_fs_fs/fs.h (SVN_FS_FS__MIN_MERGEINFO_IN_CHANGES_FORMAT): New format capability flag.
* subversion/libsvn_fs_fs/low_level.c (read_change): Detect the presense of the mergeinfo-mod flag and parse it if found. (write_change_entry): Write the mergeinfo-mod flag dependent on whether its value is known and the new INCLUDE_MERGEINFO_MODS parameter has been set. (svn_fs_fs__write_changes): Include mergeinfo-mod only if supported by the current FS format.