Author: julianfoad Date: Fri Jun 5 11:46:31 2015 New Revision: 1683718 URL: http://svn.apache.org/r1683718 Log: On the 'move-tracking-2' branch: Start implementing migration of history from non-move-tracking repository revisions. Just a framework, so far.
* subversion/include/private/svn_editor3e.h (svn_branch_get_migration_editor): New. * subversion/libsvn_delta/migrate.c New. * subversion/svnmover/svnmover.c (action_code_t, action_defn, execute): Define the 'migrate' action. (migrate_replay_baton_t, migrate_replay_rev_started, migrate_replay_rev_finished, do_migrate): New. Added: subversion/branches/move-tracking-2/subversion/libsvn_delta/migrate.c (with props) Modified: subversion/branches/move-tracking-2/subversion/include/private/svn_editor3e.h subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c Modified: subversion/branches/move-tracking-2/subversion/include/private/svn_editor3e.h URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/private/svn_editor3e.h?rev=1683718&r1=1683717&r2=1683718&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/include/private/svn_editor3e.h (original) +++ subversion/branches/move-tracking-2/subversion/include/private/svn_editor3e.h Fri Jun 5 11:46:31 2015 @@ -1263,6 +1263,16 @@ svn_editor3_in_memory(svn_editor3_t **ed void *fetch_baton, apr_pool_t *result_pool); +/* An Ev1 editor that drives (heuristically) a move-tracking editor. + */ +svn_error_t * +svn_branch_get_migration_editor(const svn_delta_editor_t **old_editor, + void **old_edit_baton, + svn_editor3_t *new_editor, + svn_ra_session_t *from_session, + svn_revnum_t revision, + apr_pool_t *result_pool); + #ifdef __cplusplus } Added: subversion/branches/move-tracking-2/subversion/libsvn_delta/migrate.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_delta/migrate.c?rev=1683718&view=auto ============================================================================== --- subversion/branches/move-tracking-2/subversion/libsvn_delta/migrate.c (added) +++ subversion/branches/move-tracking-2/subversion/libsvn_delta/migrate.c Fri Jun 5 11:46:31 2015 @@ -0,0 +1,361 @@ +/* + * migrate.c: Migrate history from non-move-tracking revisions + * + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + */ + +#include "svn_private_config.h" +#include "svn_client.h" +#include "svnmover.h" + +#include "../libsvn_delta/debug_editor.h" + + +struct edit_baton +{ + svn_editor3_t *new_editor; + svn_ra_session_t *from_session; + svn_revnum_t revision; +}; + +struct dir_baton +{ + void *edit_baton; +}; + +struct file_baton +{ + void *edit_baton; +}; + +static svn_error_t * +set_target_revision(void *edit_baton, + svn_revnum_t target_revision, + apr_pool_t *pool) +{ + struct edit_baton *eb = edit_baton; + + /*SVN_ERR(eb->wrapped_editor->set_target_revision(eb->wrapped_edit_baton, + target_revision, + pool));*/ + return SVN_NO_ERROR; +} + +static svn_error_t * +open_root(void *edit_baton, + svn_revnum_t base_revision, + apr_pool_t *pool, + void **root_baton) +{ + struct edit_baton *eb = edit_baton; + struct dir_baton *dir_baton = apr_palloc(pool, sizeof(*dir_baton)); + + /*SVN_ERR(eb->wrapped_editor->open_root(eb->wrapped_edit_baton, + base_revision, + pool, + &dir_baton->wrapped_dir_baton));*/ + + dir_baton->edit_baton = edit_baton; + + *root_baton = dir_baton; + + return SVN_NO_ERROR; +} + +static svn_error_t * +delete_entry(const char *path, + svn_revnum_t base_revision, + void *parent_baton, + apr_pool_t *pool) +{ + struct dir_baton *pb = parent_baton; + struct edit_baton *eb = pb->edit_baton; + + /*SVN_ERR(eb->wrapped_editor->delete_entry(path, + base_revision, + pb->wrapped_dir_baton, + pool);*/ + return SVN_NO_ERROR; +} + +static svn_error_t * +add_directory(const char *path, + void *parent_baton, + const char *copyfrom_path, + svn_revnum_t copyfrom_revision, + apr_pool_t *pool, + void **child_baton) +{ + struct dir_baton *pb = parent_baton; + struct edit_baton *eb = pb->edit_baton; + struct dir_baton *db = apr_palloc(pool, sizeof(*db)); + + /*SVN_ERR(eb->wrapped_editor->add_directory(path, + pb->wrapped_dir_baton, + copyfrom_path, + copyfrom_revision, + pool, + &db->wrapped_dir_baton));*/ + + db->edit_baton = eb; + *child_baton = db; + + return SVN_NO_ERROR; +} + +static svn_error_t * +open_directory(const char *path, + void *parent_baton, + svn_revnum_t base_revision, + apr_pool_t *pool, + void **child_baton) +{ + struct dir_baton *pb = parent_baton; + struct edit_baton *eb = pb->edit_baton; + struct dir_baton *db = apr_palloc(pool, sizeof(*db)); + + /*SVN_ERR(eb->wrapped_editor->open_directory(path, + pb->wrapped_dir_baton, + base_revision, + pool, + &db->wrapped_dir_baton));*/ + + db->edit_baton = eb; + *child_baton = db; + + return SVN_NO_ERROR; +} + +static svn_error_t * +add_file(const char *path, + void *parent_baton, + const char *copyfrom_path, + svn_revnum_t copyfrom_revision, + apr_pool_t *pool, + void **file_baton) +{ + struct dir_baton *pb = parent_baton; + struct edit_baton *eb = pb->edit_baton; + struct file_baton *fb = apr_palloc(pool, sizeof(*fb)); + + /*SVN_ERR(eb->wrapped_editor->add_file(path, + pb->wrapped_dir_baton, + copyfrom_path, + copyfrom_revision, + pool, + &fb->wrapped_file_baton));*/ + + fb->edit_baton = eb; + *file_baton = fb; + + return SVN_NO_ERROR; +} + +static svn_error_t * +open_file(const char *path, + void *parent_baton, + svn_revnum_t base_revision, + apr_pool_t *pool, + void **file_baton) +{ + struct dir_baton *pb = parent_baton; + struct edit_baton *eb = pb->edit_baton; + struct file_baton *fb = apr_palloc(pool, sizeof(*fb)); + + /*SVN_ERR(eb->wrapped_editor->open_file(path, + pb->wrapped_dir_baton, + base_revision, + pool, + &fb->wrapped_file_baton));*/ + + fb->edit_baton = eb; + *file_baton = fb; + + return SVN_NO_ERROR; +} + +static svn_error_t * +apply_textdelta(void *file_baton, + const char *base_checksum, + apr_pool_t *pool, + svn_txdelta_window_handler_t *handler, + void **handler_baton) +{ + struct file_baton *fb = file_baton; + struct edit_baton *eb = fb->edit_baton; + + /*SVN_ERR(eb->wrapped_editor->apply_textdelta(fb->wrapped_file_baton, + base_checksum, + pool, + handler, + handler_baton));*/ + + return SVN_NO_ERROR; +} + +static svn_error_t * +close_file(void *file_baton, + const char *text_checksum, + apr_pool_t *pool) +{ + struct file_baton *fb = file_baton; + struct edit_baton *eb = fb->edit_baton; + + /*SVN_ERR(eb->wrapped_editor->close_file(fb->wrapped_file_baton, + text_checksum, pool));*/ + + return SVN_NO_ERROR; +} + +static svn_error_t * +absent_file(const char *path, + void *file_baton, + apr_pool_t *pool) +{ + struct file_baton *fb = file_baton; + struct edit_baton *eb = fb->edit_baton; + + /*SVN_ERR(eb->wrapped_editor->absent_file(path, fb->wrapped_file_baton, + pool));*/ + + return SVN_NO_ERROR; +} + +static svn_error_t * +close_directory(void *dir_baton, + apr_pool_t *pool) +{ + struct dir_baton *db = dir_baton; + struct edit_baton *eb = db->edit_baton; + + /*SVN_ERR(eb->wrapped_editor->close_directory(db->wrapped_dir_baton, + pool));*/ + + return SVN_NO_ERROR; +} + +static svn_error_t * +absent_directory(const char *path, + void *dir_baton, + apr_pool_t *pool) +{ + struct dir_baton *db = dir_baton; + struct edit_baton *eb = db->edit_baton; + + /*SVN_ERR(eb->wrapped_editor->absent_directory(path, db->wrapped_dir_baton, + pool));*/ + + return SVN_NO_ERROR; +} + +static svn_error_t * +change_file_prop(void *file_baton, + const char *name, + const svn_string_t *value, + apr_pool_t *pool) +{ + struct file_baton *fb = file_baton; + struct edit_baton *eb = fb->edit_baton; + + /*SVN_ERR(eb->wrapped_editor->change_file_prop(fb->wrapped_file_baton, + name, + value, + pool));*/ + + return SVN_NO_ERROR; +} + +static svn_error_t * +change_dir_prop(void *dir_baton, + const char *name, + const svn_string_t *value, + apr_pool_t *pool) +{ + struct dir_baton *db = dir_baton; + struct edit_baton *eb = db->edit_baton; + + /*SVN_ERR(eb->wrapped_editor->change_dir_prop(db->wrapped_dir_baton, + name, + value, + pool));*/ + + return SVN_NO_ERROR; +} + +static svn_error_t * +close_edit(void *edit_baton, + apr_pool_t *pool) +{ + struct edit_baton *eb = edit_baton; + + /*SVN_ERR(eb->wrapped_editor->close_edit(eb->wrapped_edit_baton, pool));*/ + + return SVN_NO_ERROR; +} + +static svn_error_t * +abort_edit(void *edit_baton, + apr_pool_t *pool) +{ + struct edit_baton *eb = edit_baton; + + /*SVN_ERR(eb->wrapped_editor->abort_edit(eb->wrapped_edit_baton, pool));*/ + + return SVN_NO_ERROR; +} + +svn_error_t * +svn_branch_get_migration_editor(const svn_delta_editor_t **old_editor, + void **old_edit_baton, + svn_editor3_t *new_editor, + svn_ra_session_t *from_session, + svn_revnum_t revision, + apr_pool_t *result_pool) +{ + static const svn_delta_editor_t editor = { + set_target_revision, + open_root, + delete_entry, + add_directory, + open_directory, + change_dir_prop, + close_directory, + absent_directory, + add_file, + open_file, + apply_textdelta, + change_file_prop, + close_file, + absent_file, + close_edit, + abort_edit + }; + struct edit_baton *eb = apr_palloc(result_pool, sizeof(*eb)); + + eb->new_editor = new_editor; + eb->from_session = from_session; + eb->revision = revision; + + *old_editor = &editor; + *old_edit_baton = eb; + + return SVN_NO_ERROR; +} + Propchange: subversion/branches/move-tracking-2/subversion/libsvn_delta/migrate.c ------------------------------------------------------------------------------ svn:eol-style = native Propchange: subversion/branches/move-tracking-2/subversion/libsvn_delta/migrate.c ------------------------------------------------------------------------------ svn:mime-type = text/x-csrc Modified: subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c?rev=1683718&r1=1683717&r2=1683718&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c (original) +++ subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c Fri Jun 5 11:46:31 2015 @@ -495,7 +495,8 @@ typedef enum action_code_t { ACTION_COMMIT, ACTION_UPDATE, ACTION_STATUS, - ACTION_REVERT + ACTION_REVERT, + ACTION_MIGRATE } action_code_t; typedef struct action_defn_t { @@ -549,6 +550,8 @@ static const action_defn_t action_defn[] "same as 'diff .@base .'"}, {ACTION_REVERT, "revert", 0, "", "revert all uncommitted changes"}, + {ACTION_MIGRATE, "migrate", 1, ".@REV", + "migrate changes from non-move-tracking revision"}, }; typedef struct action_t { @@ -2107,6 +2110,96 @@ do_revert(svnmover_wc_t *wc, return SVN_NO_ERROR; } +/* Migration replay baton */ +typedef struct migrate_replay_baton_t { + svn_editor3_t *new_editor; + svn_ra_session_t *from_session; +} migrate_replay_baton_t; + +/* Callback function for svn_ra_replay_range, invoked when starting to parse + * a replay report. + */ +static svn_error_t * +migrate_replay_rev_started(svn_revnum_t revision, + void *replay_baton, + const svn_delta_editor_t **editor, + void **edit_baton, + apr_hash_t *rev_props, + apr_pool_t *pool) +{ + migrate_replay_baton_t *rb = replay_baton; + const svn_delta_editor_t *old_editor; + void *old_edit_baton; + + printf("DBG: migrate: start r%ld\n", revision); + + SVN_ERR(svn_branch_get_migration_editor(&old_editor, &old_edit_baton, + rb->new_editor, + rb->from_session, revision, + pool)); + SVN_ERR(svn_delta__get_debug_editor(&old_editor, &old_edit_baton, + old_editor, old_edit_baton, + "migrate: ", pool)); + + *editor = old_editor; + *edit_baton = old_edit_baton; + + return SVN_NO_ERROR; +} + +/* Callback function for svn_ra_replay_range, invoked when finishing parsing + * a replay report. + */ +static svn_error_t * +migrate_replay_rev_finished(svn_revnum_t revision, + void *replay_baton, + const svn_delta_editor_t *editor, + void *edit_baton, + apr_hash_t *rev_props, + apr_pool_t *pool) +{ + migrate_replay_baton_t *rb = replay_baton; + + printf("DBG: migrate: end r%ld\n", revision); + + SVN_ERR(editor->close_edit(edit_baton, pool)); + + return SVN_NO_ERROR; +} + +/* Migrate changes from non-move-tracking revisions. + */ +static svn_error_t * +do_migrate(svnmover_wc_t *wc, + svn_revnum_t start_revision, + svn_revnum_t end_revision, + apr_pool_t *scratch_pool) +{ + migrate_replay_baton_t *rb = apr_pcalloc(scratch_pool, sizeof(*rb)); + + if (start_revision < 1 || end_revision < 1 + || start_revision > end_revision + || end_revision > wc->head_revision) + { + return svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL, + _("migrate: Bad revision range (%ld to %ld); " + "minimum is 1 and maximum (head) is %ld"), + start_revision, end_revision, + wc->head_revision); + } + + rb->new_editor = wc->editor; + rb->from_session = wc->ra_session; + SVN_ERR(svn_ra_replay_range(rb->from_session, + start_revision, end_revision, + 0, TRUE, + migrate_replay_rev_started, + migrate_replay_rev_finished, + rb, scratch_pool)); + return SVN_NO_ERROR; +} + + typedef struct arg_t { const char *path_name; @@ -2563,6 +2656,17 @@ execute(svnmover_wc_t *wc, } break; + case ACTION_MIGRATE: + /* path (or eid) is currently required for syntax, but ignored */ + VERIFY_EID_EXISTS("migrate", 0); + VERIFY_REV_SPECIFIED("migrate", 0); + { + SVN_ERR(do_migrate(wc, + arg[0]->revnum, arg[0]->revnum, + iterpool)); + } + break; + default: SVN_ERR_MALFUNCTION(); }