Index: /svn/local/subversion/include/svn_fs.h ================================================================== @@ -1205,6 +1205,19 @@ const char *path2, apr_pool_t *pool); +/** Check if the text of two root/path combos have changed. + * + * Set @a *changed_p to 1 if the contents at @a path1 under @a root1 differ + * from those at @a path2 under @a root2, or set it to 0 if they are the + * same. Both paths must exist under their respective roots, and both + * roots must be in the same filesystem. + */ +svn_error_t *svn_fs_text_changed (svn_boolean_t *changed_p, + svn_fs_root_t *root1, + const char *path1, + svn_fs_root_t *root2, + const char *path2, + apr_pool_t *pool); /* Filesystem revisions. */ Index: /svn/local/subversion/libsvn_fs/tree.c ================================================================== @@ -3826,7 +3826,7 @@ if ((svn_fs_root_fs (root1)) != (svn_fs_root_fs (root2))) return svn_error_create (SVN_ERR_FS_GENERAL, NULL, - "Asking props changed in two different filesystems."); + "Asking contents changed in two different filesystems."); /* Check that both paths are files. */ { @@ -3852,6 +3852,53 @@ SVN_ERR (svn_fs__retry_txn (root1->fs, txn_body_contents_changed, &args, pool)); + + return SVN_NO_ERROR; +} + +svn_error_t * +svn_fs_text_changed (svn_boolean_t *changed_p, + svn_fs_root_t *root1, + const char *path1, + svn_fs_root_t *root2, + const char *path2, + apr_pool_t *pool) +{ + svn_filesize_t size1, size2; + SVN_ERR (svn_fs_contents_changed (changed_p, root1, path1, + root2, path2, pool)); + if (!*changed_p) + return SVN_NO_ERROR; + + SVN_ERR (svn_fs_file_length (&size1, root1, path1, pool)); + SVN_ERR (svn_fs_file_length (&size2, root2, path2, pool)); + + if (size1 != size2) + *changed_p = TRUE; + else + { + svn_stream_t *stream1, *stream2; + char buf1[SVN_STREAM_CHUNK_SIZE], buf2[SVN_STREAM_CHUNK_SIZE]; + apr_size_t len1, len2; + + SVN_ERR (svn_fs_file_contents (&stream1, root1, path1, pool)); + SVN_ERR (svn_fs_file_contents (&stream2, root2, path2, pool)); + + *changed_p = FALSE; + do + { + len1 = len2 = SVN_STREAM_CHUNK_SIZE; + SVN_ERR (svn_stream_read (stream1, buf1, &len1)); + SVN_ERR (svn_stream_read (stream2, buf2, &len2)); + + if (len1 != len2 || memcmp (buf1, buf2, len1)) + { + *changed_p = TRUE; + break; + } + } + while (len1 > 0); + } return SVN_NO_ERROR; } Index: /svn/local/subversion/libsvn_repos/delta.c ================================================================== @@ -679,10 +679,16 @@ if (source_path) { /* Is this deltification worth our time? */ - SVN_ERR (svn_fs_contents_changed (&changed, - c->target_root, target_path, - c->source_root, source_path, - subpool)); + if (c->ignore_ancestry) + SVN_ERR (svn_fs_text_changed (&changed, + c->target_root, target_path, + c->source_root, source_path, + subpool)); + else + SVN_ERR (svn_fs_contents_changed (&changed, + c->target_root, target_path, + c->source_root, source_path, + subpool)); } else {