/usr/lib/ruby/1.8/svn/synchronizer.rb is in libsvn-ruby1.8 1.6.17dfsg-3ubuntu3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | # Experimental
require "cgi"
require "svn/ra"
module Svn
class Synchronizer
class Error < StandardError
end
class NotInitialized < Error
attr_reader :destination_url
def initialize(destination_url)
@destination_url = destination_url
super("#{@destination_url} is not initialized yet.")
end
end
class ConsistencyError < Error
attr_reader :destination_url, :destination_latest_revision, :next_revision
def initialize(destination_url, destination_latest_revision, next_revision)
@destination_url = destination_url
@destination_latest_revision = destination_latest_revision
@next_revision = next_revision
super("the latest revision (#{@destination_latest_revision}) of " +
"the destination repository (#{@destination_url}) " +
"should be #{@next_revision - 1}.")
end
end
module Property
Svn::Ext::Core.constants.each do |name|
case name.to_s
when /\ASVNSYNC_PROP_/
const_set($POSTMATCH, Svn::Ext::Core.const_get(name))
end
end
end
def initialize(destination_url, callbacks=nil)
@destination = Ra::Session.open(destination_url, nil, callbacks)
if @destination.repos_root != destination_url
raise ArgumentError,
"URL '#{destination_url}' is not repository root " +
"(#{@destination.repos_root})."
end
end
def source=(source)
@destination[Property::FROM_URL, 0] = source.repos_root
@destination[Property::FROM_UUID, 0] = source.uuid
@destination[Property::LAST_MERGED_REV, 0] = "0"
sync_property_re = /\A#{Property::PREFIX}/
source.properties(0).each do |key, value|
next if sync_property_re =~ key
@destination[key, 0] = value
end
end
def sync(callbacks=nil)
last_merged_rev = @destination[Property::LAST_MERGED_REV, 0]
raise NotInitialized.new(@destination.repos_root) if last_merged_rev.nil?
last_merged_rev = Integer(last_merged_rev)
source = Ra::Session.open(@destination[Property::FROM_URL, 0], nil,
callbacks)
(last_merged_rev + 1).upto(source.latest_revision) do |revision|
unless @destination.latest_revision + 1 == revision
raise ConsistencyError.new(@destination.repos_root,
@destination.latest_revision,
revision)
end
editor = sync_editor(source, revision)
source.replay(revision, 0, editor)
editor.close_edit
sync_svn_revision_properties(source, revision)
@destination[Property::LAST_MERGED_REV, 0] = revision.to_s
end
end
private
def sync_editor(source, base_revision)
properties = source.properties(base_revision)
commit_editor = @destination.commit_editor2(properties)
Editor.new(commit_editor, @destination.repos_root, base_revision)
end
def sync_svn_revision_properties(source, revision)
[Core::PROP_REVISION_AUTHOR, Core::PROP_REVISION_DATE].each do |key|
@destination[key, revision] = source[key, revision]
end
end
class Editor < Delta::WrapEditor
def initialize(wrapped_editor, dest_url, base_revision)
super(wrapped_editor)
@dest_url = dest_url
@base_revision = base_revision
@opened_root = false
end
def open_root(base_revision)
@opened_root = true
super
end
def add_directory(path, parent_baton, copy_from_path, copy_from_rev)
if copy_from_path
copy_from_path = "#{@dest_url}#{CGI.escape(copy_from_path)}"
end
super(path, parent_baton, copy_from_path, copy_from_rev)
end
def add_file(path, parent_baton, copy_from_path, copy_from_rev)
if copy_from_path
copy_from_path = "#{@dest_url}#{CGI.escape(copy_from_path)}"
end
super(path, parent_baton, copy_from_path, copy_from_rev)
end
def close_edit
unless @opened_root
baton = @wrapped_editor.open_root(@base_revision)
@wrapped_editor.close_directory(baton)
end
super
end
end
end
end
|