Trying attachment again, now with .txt extension.
On Thu, Feb 4, 2010 at 11:10 AM, Lieven Govaerts <[email protected]> wrote:
> Attached some tests I'm working on for svn_client_blame5 and
> svn_repos_get_file_revs2.
>
> I started moving some code to create a repository, ra session (...) to
> tests/svn_test_fs.c so that these can be reused in other tests.
> The test for svn_client_blame5 isn't finished yet.
>
> @DanielN: This might be useful for you, feel free to reuse and improve
> in any way you see fit. I'll probably commit later this week.
>
> Lieven
>
Index: subversion/tests/svn_test_fs.h
===================================================================
--- subversion/tests/svn_test_fs.h (revision 902368)
+++ subversion/tests/svn_test_fs.h (working copy)
@@ -73,6 +73,13 @@ svn_test__create_repos(svn_repos_t **repos_p,
const svn_test_opts_t *opts,
apr_pool_t *pool);
+/* Set URL to a "file://" url for the current directory, suffixed by the
+ forward-slash-style relative path SUFFIX, performing all allocation
+ in POOL. */
+svn_error_t *
+svn_test__current_directory_url(const char **url,
+ const char *suffix,
+ apr_pool_t *pool);
/* Read all data from a generic read STREAM, and return it in STRING.
Allocate the svn_stringbuf_t in APRPOOL. (All data in STRING will be
@@ -169,7 +176,20 @@ svn_error_t *
svn_test__create_greek_tree(svn_fs_root_t *txn_root,
apr_pool_t *pool);
+/* Create the Greek Tree under TXN_ROOT at dir ROOT_DIR. */
+svn_error_t *
+svn_test__create_greek_tree_at(svn_fs_root_t *txn_root,
+ const char *root_dir,
+ apr_pool_t *pool);
+/* Create a new repository with a greek tree, trunk, branch and some
+ merges between them. */
+svn_error_t *
+svn_test__create_blame_repository(svn_repos_t **out_repos,
+ const char *test_name,
+ const svn_test_opts_t *opts,
+ apr_pool_t *pool);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
Index: subversion/tests/libsvn_ra_local/ra-local-test.c
===================================================================
--- subversion/tests/libsvn_ra_local/ra-local-test.c (revision 902368)
+++ subversion/tests/libsvn_ra_local/ra-local-test.c (working copy)
@@ -26,15 +26,6 @@
#include <apr_general.h>
#include <apr_pools.h>
-#ifdef _MSC_VER
-#include <direct.h>
-#define getcwd _getcwd
-#else
-#include <unistd.h> /* for getcwd() */
-#endif
-
-#include "svn_string.h"
-#include "svn_utf.h"
#include "svn_error.h"
#include "svn_delta.h"
#include "svn_ra.h"
@@ -49,37 +40,7 @@
/** Helper routines. **/
-/* Helper function. Set URL to a "file://" url for the current directory,
- suffixed by the forward-slash-style relative path SUFFIX, performing all
- allocation in POOL. */
static svn_error_t *
-current_directory_url(const char **url,
- const char *suffix,
- apr_pool_t *pool)
-{
- /* 8KB is a lot, but it almost guarantees that any path will fit. */
- char curdir[8192];
- const char *utf8_ls_curdir, *utf8_is_curdir, *unencoded_url;
-
- if (! getcwd(curdir, sizeof(curdir)))
- return svn_error_create(SVN_ERR_BASE, NULL, "getcwd() failed");
-
- SVN_ERR(svn_utf_cstring_to_utf8(&utf8_ls_curdir, curdir, pool));
- utf8_is_curdir = svn_path_internal_style(utf8_ls_curdir, pool);
-
- unencoded_url = apr_psprintf(pool, "file://%s%s%s%s",
- (utf8_is_curdir[0] != '/') ? "/" : "",
- utf8_is_curdir,
- (suffix[0] && suffix[0] != '/') ? "/" : "",
- suffix);
-
- *url = svn_path_uri_encode(unencoded_url, pool);
-
- return SVN_NO_ERROR;
-}
-
-
-static svn_error_t *
make_and_open_local_repos(svn_ra_session_t **session,
const char *repos_name,
const svn_test_opts_t *opts,
@@ -94,7 +55,7 @@ make_and_open_local_repos(svn_ra_session_t **sessi
SVN_ERR(svn_test__create_repos(&repos, repos_name, opts, pool));
SVN_ERR(svn_ra_initialize(pool));
- SVN_ERR(current_directory_url(&url, repos_name, pool));
+ SVN_ERR(svn_test__current_directory_url(&url, repos_name, pool));
SVN_ERR(svn_ra_open3(session,
url,
@@ -262,7 +223,7 @@ check_split_url(const char *repos_path,
/* Create a filesystem and repository */
SVN_ERR(svn_test__create_repos(&repos, repos_path, opts, pool));
- SVN_ERR(current_directory_url(&root_url, repos_path, pool));
+ SVN_ERR(svn_test__current_directory_url(&root_url, repos_path, pool));
if (in_repos_path)
url = apr_pstrcat(pool, root_url, in_repos_path, NULL);
else
Index: subversion/tests/libsvn_client/client-test.c
===================================================================
--- subversion/tests/libsvn_client/client-test.c (revision 902368)
+++ subversion/tests/libsvn_client/client-test.c (working copy)
@@ -26,8 +26,10 @@
#include "../../libsvn_client/mergeinfo.h"
#include "svn_pools.h"
#include "svn_client.h"
+#include "svn_ra.h"
#include "../svn_test.h"
+#include "../svn_test_fs.h"
typedef struct {
const char *path;
@@ -99,8 +101,7 @@ test_elide_mergeinfo_catalog(apr_pool_t *pool)
static svn_error_t *
test_args_to_target_array(apr_pool_t *pool)
-{
- apr_size_t i;
+{ apr_size_t i;
apr_pool_t *iterpool;
svn_client_ctx_t *ctx;
static struct {
@@ -199,6 +200,92 @@ test_args_to_target_array(apr_pool_t *pool)
return SVN_NO_ERROR;
}
+
+/* Tests for svn_client_blameN() */
+
+typedef struct {
+ svn_revnum_t rev;
+ const char *path;
+ svn_boolean_t result_of_merge;
+ const char *author;
+} file_revs_t;
+
+static svn_error_t *
+blame_receiver(void *baton,
+ apr_int64_t line_no,
+ svn_revnum_t revision,
+ apr_hash_t *rev_props,
+ svn_revnum_t merged_revision,
+ apr_hash_t *merged_rev_props,
+ const char *merged_path,
+ const char *line,
+ svn_boolean_t local_change,
+ apr_pool_t *pool)
+{
+ printf("%s %s\n", merged_path, line);
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_svn_client_blame(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_repos_t *repos = NULL;
+ svn_fs_t *fs;
+ svn_revnum_t youngest_rev = 0;
+ apr_pool_t *subpool = svn_pool_create(pool);
+ svn_client_ctx_t *ctx;
+ svn_opt_revision_t start_rev, end_rev, peg_rev;
+ const char *repos_name = "test-client-blame";
+ const char *url;
+ svn_ra_callbacks2_t *cbtable;
+ svn_ra_session_t *session;
+ svn_diff_file_options_t *diff_options =
svn_diff_file_options_create(subpool);
+
+ /* Create the repository and verify blame results. */
+ SVN_ERR(svn_test__create_blame_repository(&repos, repos_name,
+ opts, subpool));
+ fs = svn_repos_fs(repos);
+
+ SVN_ERR(svn_fs_youngest_rev(&youngest_rev, fs, subpool));
+
+ SVN_ERR(svn_client_create_context(&ctx, subpool));
+
+ /* Open ra_local session */
+ SVN_ERR(svn_ra_create_callbacks(&cbtable, pool));
+ SVN_ERR(svn_ra_initialize(subpool));
+
+ SVN_ERR(svn_test__current_directory_url(&url, repos_name, subpool));
+
+ printf("url: %s\n", url);
+ SVN_ERR(svn_ra_open3(&session,
+ url,
+ NULL,
+ cbtable,
+ NULL,
+ NULL,
+ subpool));
+
+ peg_rev.kind = svn_opt_revision_head;
+ start_rev.kind = svn_opt_revision_number;
+ start_rev.value.number = youngest_rev;
+ end_rev.kind = svn_opt_revision_head;
+ SVN_ERR(svn_client_blame5(svn_uri_join(url, "branches/1.0.x/A/mu", subpool),
+ &peg_rev,
+ &start_rev,
+ &end_rev,
+ diff_options,
+ FALSE,
+ TRUE,
+ blame_receiver,
+ NULL,
+ ctx,
+ subpool));
+
+ return SVN_NO_ERROR;
+}
+
+
/* ==========================================================================
*/
struct svn_test_descriptor_t test_funcs[] =
@@ -208,5 +295,7 @@ struct svn_test_descriptor_t test_funcs[] =
"test svn_client__elide_mergeinfo_catalog"),
SVN_TEST_PASS2(test_args_to_target_array,
"test svn_client_args_to_target_array"),
+ SVN_TEST_OPTS_PASS(test_svn_client_blame,
+ "test svn_client_blame"),
SVN_TEST_NULL
};
Index: subversion/tests/libsvn_repos/repos-test.c
===================================================================
--- subversion/tests/libsvn_repos/repos-test.c (revision 902368)
+++ subversion/tests/libsvn_repos/repos-test.c (working copy)
@@ -2340,7 +2340,126 @@ get_logs(const svn_test_opts_t *opts,
return SVN_NO_ERROR;
}
+
+/* Tests for svn_repos_get_file_revsN() */
+typedef struct {
+ svn_revnum_t rev;
+ const char *path;
+ svn_boolean_t result_of_merge;
+ const char *author;
+} file_revs_t;
+
+/* Finds the revision REV in the hash table passed in in BATON, and checks
+ if the PATH and RESULT_OF_MERGE match are as expected. */
+static svn_error_t *
+file_rev_handler(void *baton, const char *path, svn_revnum_t rev,
+ apr_hash_t *rev_props, svn_boolean_t result_of_merge,
+ svn_txdelta_window_handler_t *delta_handler,
+ void **delta_baton, apr_array_header_t *prop_diffs,
+ apr_pool_t *pool)
+{
+ apr_hash_t *ht = baton;
+ const char *author;
+ file_revs_t *file_rev = apr_hash_get(ht, &rev, sizeof(svn_revnum_t));
+
+ if (!file_rev)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+ "Revision rev info not expected for rev %ld "
+ "from path %s",
+ rev, path);
+
+ author = svn_prop_get_value(rev_props,
+ SVN_PROP_REVISION_AUTHOR);
+
+ SVN_TEST_STRING_ASSERT(author, file_rev->author);
+ SVN_TEST_STRING_ASSERT(path, file_rev->path);
+ SVN_TEST_ASSERT(rev == file_rev->rev);
+ SVN_TEST_ASSERT(result_of_merge == file_rev->result_of_merge);
+
+ /* Remove this revision from this list so we'll be able to verify that we
+ have seen all expected revisions. */
+ apr_hash_set(ht, &rev, sizeof(svn_revnum_t), NULL);
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_get_file_revs(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_repos_t *repos = NULL;
+ svn_fs_t *fs;
+ svn_revnum_t youngest_rev = 0;
+ apr_pool_t *subpool = svn_pool_create(pool);
+ int i;
+
+ file_revs_t trunk_results[] = {
+ { 2, "/trunk/A/mu", FALSE, "initial" },
+ { 3, "/trunk/A/mu", FALSE, "user-trunk" },
+ { 4, "/branches/1.0.x/A/mu", TRUE, "copy" },
+ { 5, "/trunk/A/mu", FALSE, "user-trunk" },
+ { 6, "/branches/1.0.x/A/mu", TRUE, "user-branch" },
+ { 7, "/branches/1.0.x/A/mu", TRUE, "user-merge1" },
+ { 8, "/trunk/A/mu", FALSE, "user-merge2" },
+ };
+ file_revs_t branch_results[] = {
+ { 2, "/trunk/A/mu", FALSE, "initial" },
+ { 3, "/trunk/A/mu", FALSE, "user-trunk" },
+ { 4, "/branches/1.0.x/A/mu", FALSE, "copy" },
+ { 5, "/trunk/A/mu", TRUE, "user-trunk" },
+ { 6, "/branches/1.0.x/A/mu", FALSE, "user-branch" },
+ { 7, "/branches/1.0.x/A/mu", FALSE, "user-merge1" },
+ };
+ apr_hash_t *ht_trunk_results = apr_hash_make(subpool);
+ apr_hash_t *ht_branch_results = apr_hash_make(subpool);
+
+ for (i = 0; i < sizeof(trunk_results) / sizeof(trunk_results[0]); i++)
+ apr_hash_set(ht_trunk_results, &trunk_results[i].rev,
+ sizeof(svn_revnum_t), &trunk_results[i]);
+
+ for (i = 0; i < sizeof(branch_results) / sizeof(branch_results[0]); i++)
+ apr_hash_set(ht_branch_results, &branch_results[i].rev,
+ sizeof(svn_revnum_t), &branch_results[i]);
+
+ /* Create the repository and verify blame results. */
+ SVN_ERR(svn_test__create_blame_repository(&repos, "test-repo-get-filerevs",
+ opts, subpool));
+ fs = svn_repos_fs(repos);
+
+ SVN_ERR(svn_fs_youngest_rev(&youngest_rev, fs, subpool));
+
+ /* Verify blame of /trunk/A/mu */
+ SVN_ERR(svn_repos_get_file_revs2(repos, "/trunk/A/mu", 0, youngest_rev,
+ 1, NULL, NULL,
+ file_rev_handler,
+ ht_trunk_results,
+ subpool));
+ SVN_TEST_ASSERT(apr_hash_count(ht_trunk_results) == 0);
+
+ /* Verify blame of /branches/1.0.x/A/mu */
+ SVN_ERR(svn_repos_get_file_revs2(repos, "/branches/1.0.x/A/mu", 0,
+ youngest_rev,
+ 1, NULL, NULL,
+ file_rev_handler,
+ ht_branch_results,
+ subpool));
+ SVN_TEST_ASSERT(apr_hash_count(ht_branch_results) == 0);
+
+ /* Verify blame of /branches/1.0.x/A/mu in range 6-7 */
+#if 0
+ /* This should only return revision 6, 7 and maximum one revision < 6. */
+ printf("=== branch range\n");
+ SVN_ERR(svn_repos_get_file_revs2(repos, "/branches/1.0.x/A/mu", 6, 7,
+ 1, NULL, NULL,
+ file_rev_handler, NULL, subpool));
+#endif
+
+ svn_pool_destroy(subpool);
+
+ return SVN_NO_ERROR;
+}
+
/* The test table. */
@@ -2373,5 +2492,7 @@ struct svn_test_descriptor_t test_funcs[] =
"test if revprops are validated by repos"),
SVN_TEST_OPTS_PASS(get_logs,
"test svn_repos_get_logs ranges and limits"),
+ SVN_TEST_OPTS_PASS(test_get_file_revs,
+ "test svn_repos_get_file_revsN"),
SVN_TEST_NULL
};
Index: subversion/tests/svn_test_fs.c
===================================================================
--- subversion/tests/svn_test_fs.c (revision 902368)
+++ subversion/tests/svn_test_fs.c (working copy)
@@ -24,8 +24,17 @@
#include <string.h>
#include <apr_pools.h>
+#ifdef _MSC_VER
+#include <direct.h>
+#define getcwd _getcwd
+#else
+#include <unistd.h> /* for getcwd() */
+#endif
+
#include "svn_test.h"
+#include "svn_string.h"
+#include "svn_utf.h"
#include "svn_pools.h"
#include "svn_error.h"
#include "svn_fs.h"
@@ -227,7 +236,37 @@ svn_test__create_repos(svn_repos_t **repos_p,
}
+/* Helper function. Set URL to a "file://" url for the current directory,
+ suffixed by the forward-slash-style relative path SUFFIX, performing all
+ allocation in POOL. */
svn_error_t *
+svn_test__current_directory_url(const char **url,
+ const char *suffix,
+ apr_pool_t *pool)
+{
+ /* 8KB is a lot, but it almost guarantees that any path will fit. */
+ char curdir[8192];
+ const char *utf8_ls_curdir, *utf8_is_curdir, *unencoded_url;
+
+ if (! getcwd(curdir, sizeof(curdir)))
+ return svn_error_create(SVN_ERR_BASE, NULL, "getcwd() failed");
+
+ SVN_ERR(svn_utf_cstring_to_utf8(&utf8_ls_curdir, curdir, pool));
+ utf8_is_curdir = svn_path_internal_style(utf8_ls_curdir, pool);
+
+ unencoded_url = apr_psprintf(pool, "file://%s%s%s%s",
+ (utf8_is_curdir[0] != '/') ? "/" : "",
+ utf8_is_curdir,
+ (suffix[0] && suffix[0] != '/') ? "/" : "",
+ suffix);
+
+ *url = svn_path_uri_encode(unencoded_url, pool);
+
+ return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
svn_test__stream_to_string(svn_stringbuf_t **string,
svn_stream_t *stream,
apr_pool_t *pool)
@@ -606,55 +645,186 @@ svn_test__check_greek_tree(svn_fs_root_t *root,
return SVN_NO_ERROR;
}
-
-
+/**
+ * Loads the greek tree in a directory at ROOT_DIR under transaction TXN_ROOT.
+ * ROOT_DIR should be created by the caller.
+ *
+ * Note: this function will not commit the transaction.
+ */
svn_error_t *
-svn_test__create_greek_tree(svn_fs_root_t *txn_root,
- apr_pool_t *pool)
+svn_test__create_greek_tree_at(svn_fs_root_t *txn_root,
+ const char *root_dir,
+ apr_pool_t *pool)
{
- SVN_ERR(svn_fs_make_file(txn_root, "iota", pool));
+ char *iota = svn_relpath_join(root_dir, "iota", pool);
+ char *A = svn_relpath_join(root_dir, "A", pool);
+ char *Amu = svn_relpath_join(root_dir, "A/mu", pool);
+ char *AB = svn_relpath_join(root_dir, "A/B", pool);
+ char *ABlambda = svn_relpath_join(root_dir, "A/B/lambda", pool);
+ char *ABE = svn_relpath_join(root_dir, "A/B/E", pool);
+ char *ABEalpha = svn_relpath_join(root_dir, "A/B/E/alpha", pool);
+ char *ABEbeta = svn_relpath_join(root_dir, "A/B/E/beta", pool);
+ char *ABF = svn_relpath_join(root_dir, "A/B/F", pool);
+ char *AC = svn_relpath_join(root_dir, "A/C", pool);
+ char *AD = svn_relpath_join(root_dir, "A/D", pool);
+ char *ADgamma = svn_relpath_join(root_dir, "A/D/gamma", pool);
+ char *ADG = svn_relpath_join(root_dir, "A/D/G", pool);
+ char *ADGpi = svn_relpath_join(root_dir, "A/D/G/pi", pool);
+ char *ADGrho = svn_relpath_join(root_dir, "A/D/G/rho", pool);
+ char *ADGtau = svn_relpath_join(root_dir, "A/D/G/tau", pool);
+ char *ADH = svn_relpath_join(root_dir, "A/D/H", pool);
+ char *ADHchi = svn_relpath_join(root_dir, "A/D/H/chi", pool);
+ char *ADHpsi = svn_relpath_join(root_dir, "A/D/H/psi", pool);
+ char *ADHomega = svn_relpath_join(root_dir, "A/D/H/omega", pool);
+
+ SVN_ERR(svn_fs_make_file(txn_root, iota, pool));
SVN_ERR(svn_test__set_file_contents
- (txn_root, "iota", "This is the file 'iota'.\n", pool));
- SVN_ERR(svn_fs_make_dir (txn_root, "A", pool));
- SVN_ERR(svn_fs_make_file(txn_root, "A/mu", pool));
+ (txn_root, iota, "This is the file 'iota'.\n", pool));
+ SVN_ERR(svn_fs_make_dir (txn_root, A, pool));
+ SVN_ERR(svn_fs_make_file(txn_root, Amu, pool));
SVN_ERR(svn_test__set_file_contents
- (txn_root, "A/mu", "This is the file 'mu'.\n", pool));
- SVN_ERR(svn_fs_make_dir (txn_root, "A/B", pool));
- SVN_ERR(svn_fs_make_file(txn_root, "A/B/lambda", pool));
+ (txn_root, Amu, "This is the file 'mu'.\n", pool));
+ SVN_ERR(svn_fs_make_dir (txn_root, AB, pool));
+ SVN_ERR(svn_fs_make_file(txn_root, ABlambda, pool));
SVN_ERR(svn_test__set_file_contents
- (txn_root, "A/B/lambda", "This is the file 'lambda'.\n", pool));
- SVN_ERR(svn_fs_make_dir (txn_root, "A/B/E", pool));
- SVN_ERR(svn_fs_make_file(txn_root, "A/B/E/alpha", pool));
+ (txn_root, ABlambda, "This is the file 'lambda'.\n", pool));
+ SVN_ERR(svn_fs_make_dir (txn_root, ABE, pool));
+ SVN_ERR(svn_fs_make_file(txn_root, ABEalpha, pool));
SVN_ERR(svn_test__set_file_contents
- (txn_root, "A/B/E/alpha", "This is the file 'alpha'.\n", pool));
- SVN_ERR(svn_fs_make_file(txn_root, "A/B/E/beta", pool));
+ (txn_root, ABEalpha, "This is the file 'alpha'.\n", pool));
+ SVN_ERR(svn_fs_make_file(txn_root, ABEbeta, pool));
SVN_ERR(svn_test__set_file_contents
- (txn_root, "A/B/E/beta", "This is the file 'beta'.\n", pool));
- SVN_ERR(svn_fs_make_dir (txn_root, "A/B/F", pool));
- SVN_ERR(svn_fs_make_dir (txn_root, "A/C", pool));
- SVN_ERR(svn_fs_make_dir (txn_root, "A/D", pool));
- SVN_ERR(svn_fs_make_file(txn_root, "A/D/gamma", pool));
+ (txn_root, ABEbeta, "This is the file 'beta'.\n", pool));
+ SVN_ERR(svn_fs_make_dir (txn_root, ABF, pool));
+ SVN_ERR(svn_fs_make_dir (txn_root, AC, pool));
+ SVN_ERR(svn_fs_make_dir (txn_root, AD, pool));
+ SVN_ERR(svn_fs_make_file(txn_root, ADgamma, pool));
SVN_ERR(svn_test__set_file_contents
- (txn_root, "A/D/gamma", "This is the file 'gamma'.\n", pool));
- SVN_ERR(svn_fs_make_dir (txn_root, "A/D/G", pool));
- SVN_ERR(svn_fs_make_file(txn_root, "A/D/G/pi", pool));
+ (txn_root, ADgamma, "This is the file 'gamma'.\n", pool));
+ SVN_ERR(svn_fs_make_dir (txn_root, ADG, pool));
+ SVN_ERR(svn_fs_make_file(txn_root, ADGpi, pool));
SVN_ERR(svn_test__set_file_contents
- (txn_root, "A/D/G/pi", "This is the file 'pi'.\n", pool));
- SVN_ERR(svn_fs_make_file(txn_root, "A/D/G/rho", pool));
+ (txn_root, ADGpi, "This is the file 'pi'.\n", pool));
+ SVN_ERR(svn_fs_make_file(txn_root, ADGrho, pool));
SVN_ERR(svn_test__set_file_contents
- (txn_root, "A/D/G/rho", "This is the file 'rho'.\n", pool));
- SVN_ERR(svn_fs_make_file(txn_root, "A/D/G/tau", pool));
+ (txn_root, ADGrho, "This is the file 'rho'.\n", pool));
+ SVN_ERR(svn_fs_make_file(txn_root, ADGtau, pool));
SVN_ERR(svn_test__set_file_contents
- (txn_root, "A/D/G/tau", "This is the file 'tau'.\n", pool));
- SVN_ERR(svn_fs_make_dir (txn_root, "A/D/H", pool));
- SVN_ERR(svn_fs_make_file(txn_root, "A/D/H/chi", pool));
+ (txn_root, ADGtau, "This is the file 'tau'.\n", pool));
+ SVN_ERR(svn_fs_make_dir (txn_root, ADH, pool));
+ SVN_ERR(svn_fs_make_file(txn_root, ADHchi, pool));
SVN_ERR(svn_test__set_file_contents
- (txn_root, "A/D/H/chi", "This is the file 'chi'.\n", pool));
- SVN_ERR(svn_fs_make_file(txn_root, "A/D/H/psi", pool));
+ (txn_root, ADHchi, "This is the file 'chi'.\n", pool));
+ SVN_ERR(svn_fs_make_file(txn_root, ADHpsi, pool));
SVN_ERR(svn_test__set_file_contents
- (txn_root, "A/D/H/psi", "This is the file 'psi'.\n", pool));
- SVN_ERR(svn_fs_make_file(txn_root, "A/D/H/omega", pool));
+ (txn_root, ADHpsi, "This is the file 'psi'.\n", pool));
+ SVN_ERR(svn_fs_make_file(txn_root, ADHomega, pool));
SVN_ERR(svn_test__set_file_contents
- (txn_root, "A/D/H/omega", "This is the file 'omega'.\n", pool));
+ (txn_root, ADHomega, "This is the file 'omega'.\n", pool));
return SVN_NO_ERROR;
}
+
+svn_error_t *
+svn_test__create_greek_tree(svn_fs_root_t *txn_root,
+ apr_pool_t *pool)
+{
+ return svn_test__create_greek_tree_at(txn_root, "", pool);
+}
+
+svn_error_t *
+svn_test__create_blame_repository(svn_repos_t **out_repos,
+ const char *test_name,
+ const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_repos_t *repos;
+ svn_fs_t *fs;
+ svn_fs_txn_t *txn;
+ svn_fs_root_t *txn_root, *revision_root;
+ svn_revnum_t youngest_rev = 0;
+
+ /* Create a filesystem and repository. */
+ SVN_ERR(svn_test__create_repos(&repos, test_name,
+ opts, pool));
+ *out_repos = repos;
+
+ fs = svn_repos_fs(repos);
+
+ /* Revision 1: Add trunk, tags, branches. */
+ SVN_ERR(svn_repos_fs_begin_txn_for_commit(&txn, repos, youngest_rev,
+ "initial", "log msg", pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_fs_make_dir(txn_root, "trunk", pool));
+ SVN_ERR(svn_fs_make_dir(txn_root, "tags", pool));
+ SVN_ERR(svn_fs_make_dir(txn_root, "branches", pool));
+ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
+
+ /* Revision 2: Add the Greek tree on the trunk. */
+ SVN_ERR(svn_repos_fs_begin_txn_for_commit(&txn, repos, youngest_rev,
+ "initial", "log msg", pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_test__create_greek_tree_at(txn_root, "trunk", pool));
+ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
+
+ /* Revision 3: Tweak trunk/A/mu. */
+ SVN_ERR(svn_repos_fs_begin_txn_for_commit(&txn, repos, youngest_rev,
+ "user-trunk", "log msg", pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_test__set_file_contents(txn_root, "trunk/A/mu",
+ "A\nB\nC\nD\nE\nF\nG\nH\nI", pool));
+ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
+
+ /* Revision 4: Copy trunk to branches/1.0.x. */
+ SVN_ERR(svn_repos_fs_begin_txn_for_commit(&txn, repos, youngest_rev,
+ "copy", "log msg", pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_fs_revision_root(&revision_root, fs, youngest_rev, pool));
+ SVN_ERR(svn_fs_copy(revision_root, "trunk",
+ txn_root, "branches/1.0.x",
+ pool));
+ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
+
+ /* Revision 5: Tweak trunk/A/mu. */
+ SVN_ERR(svn_repos_fs_begin_txn_for_commit(&txn, repos, youngest_rev,
+ "user-trunk", "log msg", pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_test__set_file_contents(txn_root, "trunk/A/mu",
+ "A\nB\nC -- trunk
edit\nD\nE\nF\nG\nH\nI",
+ pool));
+ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
+
+ /* Revision 6: Tweak branches/1.0.x/A/mu. */
+ SVN_ERR(svn_repos_fs_begin_txn_for_commit(&txn, repos, youngest_rev,
+ "user-branch", "log msg", pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_test__set_file_contents(txn_root, "branches/1.0.x/A/mu",
+ "A\nB\nC\nD -- branch
edit\nE\nF\nG\nH\nI",
+ pool));
+ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
+
+ /* Revision 7: Merge trunk to branch. */
+ SVN_ERR(svn_repos_fs_begin_txn_for_commit(&txn, repos, youngest_rev,
+ "user-merge1", "log msg", pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_test__set_file_contents(txn_root, "branches/1.0.x/A/mu",
+ "A\nB\nC -- trunk edit\nD -- branch edit"
+ "\nE\nF\nG\nH\nI", pool));
+ SVN_ERR(svn_fs_change_node_prop(txn_root, "/branches/1.0.x", "svn:mergeinfo",
+ svn_string_create("/trunk:4-6", pool),
+ pool));
+ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
+
+ /* Revision 8: Merge branch to trunk. */
+ SVN_ERR(svn_repos_fs_begin_txn_for_commit(&txn, repos, youngest_rev,
+ "user-merge2", "log msg", pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_test__set_file_contents(txn_root, "trunk/A/mu",
+ "A\nB\nC -- trunk edit\nD -- branch
edit\n"
+ "E\nF\nG\nH\nI", pool));
+ SVN_ERR(svn_fs_change_node_prop(txn_root, "/trunk", "svn:mergeinfo",
+ svn_string_create("/branches/1.0.x:4-7",
pool),
+ pool));
+ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
+
+ return SVN_NO_ERROR;
+}