annotate svnwrap/svn_swig_wrapper.py @ 7:79b0e059319d

Reorganized the testing infrastructure a bit so that svnwrap is really separate from the rest of the project. Also made it easier to add more tests in the future without making the directory full of annoying files.
author Augie Fackler <durin42@gmail.com>
date Fri, 03 Oct 2008 09:41:25 -0500
parents 1a5bb173170b
children 9eb6bf2be1e7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
1 import cStringIO
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
2 import getpass
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
3 import os
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
4 import shutil
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
5 import sys
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
6 import tempfile
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
7
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
8 from svn import client
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
9 from svn import core
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
10 from svn import delta
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
11 from svn import ra
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
12
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
13 svn_config = core.svn_config_get_config(None)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
14
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
15
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
16 def user_pass_prompt(realm, default_username, ms, pool):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
17 creds = core.svn_auth_cred_simple_t()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
18 creds.may_save = ms
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
19 if default_username:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
20 sys.stderr.write('Auth realm: %s\n' % (realm,))
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
21 creds.username = default_username
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
22 else:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
23 sys.stderr.write('Auth realm: %s\n' % (realm,))
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
24 sys.stderr.write('Username: ')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
25 sys.stderr.flush()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
26 creds.username = sys.stdin.readline().strip()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
27 creds.password = getpass.getpass('Password for %s: ' % creds.username)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
28 return creds
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
29
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
30 def _create_auth_baton(pool):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
31 """Create a Subversion authentication baton. """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
32 # Give the client context baton a suite of authentication
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
33 # providers.h
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
34 providers = [
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
35 client.get_simple_provider(),
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
36 client.get_username_provider(),
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
37 client.get_ssl_client_cert_file_provider(),
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
38 client.get_ssl_client_cert_pw_file_provider(),
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
39 client.get_ssl_server_trust_file_provider(),
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
40 ]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
41 # Platform-dependant authentication methods
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
42 if hasattr(client, 'get_windows_simple_provider'):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
43 providers.append(client.get_windows_simple_provider())
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
44 if hasattr(client, 'get_keychain_simple_provider'):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
45 providers.append(client.get_keychain_simple_provider())
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
46 providers.extend([client.get_simple_prompt_provider(user_pass_prompt, 2),
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
47 ])
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
48 return core.svn_auth_open(providers, pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
49
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
50
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
51 class Revision(object):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
52 """Wrapper for a Subversion revision.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
53 """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
54 def __init__(self, revnum, author, message, date, paths, strip_path=''):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
55 self.revnum, self.author, self.message = revnum, author, message
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
56 # TODO parse this into a datetime
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
57 self.date = date
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
58 self.paths = {}
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
59 for p in paths:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
60 self.paths[p[len(strip_path):]] = paths[p]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
61
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
62 def __str__(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
63 return 'r%d by %s' % (self.revnum, self.author)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
64
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
65 class SubversionRepo(object):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
66 """Wrapper for a Subversion repository.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
67
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
68 This uses the SWIG Python bindings, and will only work on svn >= 1.4.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
69 It takes a required param, the URL.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
70 """
6
1a5bb173170b Fixes for win32 compatibility. Changes suggested by Shun-ichi GOTO, with some alterations by me.
Augie Fackler <durin42@gmail.com>
parents: 0
diff changeset
71 def __init__(self, url='', username=''):
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
72 self.svn_url = url
6
1a5bb173170b Fixes for win32 compatibility. Changes suggested by Shun-ichi GOTO, with some alterations by me.
Augie Fackler <durin42@gmail.com>
parents: 0
diff changeset
73 self.uname = username
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
74 self.auth_baton_pool = core.Pool()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
75 self.auth_baton = _create_auth_baton(self.auth_baton_pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
76
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
77 self.init_ra_and_client()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
78 self.uuid = ra.get_uuid(self.ra, self.pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
79 repo_root = ra.get_repos_root(self.ra, self.pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
80 # *will* have a leading '/', would not if we used get_repos_root2
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
81 self.subdir = url[len(repo_root):]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
82 if not self.subdir or self.subdir[-1] != '/':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
83 self.subdir += '/'
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
84
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
85 def init_ra_and_client(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
86 """Initializes the RA and client layers, because sometimes getting
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
87 unified diffs runs the remote server out of open files.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
88 """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
89 # while we're in here we'll recreate our pool
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
90 self.pool = core.Pool()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
91 self.client_context = client.create_context()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
92 core.svn_auth_set_parameter(self.auth_baton,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
93 core.SVN_AUTH_PARAM_DEFAULT_USERNAME,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
94 self.uname)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
95
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
96 self.client_context.auth_baton = self.auth_baton
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
97 self.client_context.config = svn_config
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
98 self.ra = client.open_ra_session(self.svn_url.encode('utf8'),
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
99 self.client_context)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
100
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
101
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
102 @property
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
103 def HEAD(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
104 return ra.get_latest_revnum(self.ra, self.pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
105
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
106 @property
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
107 def START(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
108 return 0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
109
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
110 @property
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
111 def branches(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
112 """Get the branches defined in this repo assuming a standard layout.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
113 """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
114 branches = self.list_dir('branches').keys()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
115 branch_info = {}
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
116 head=self.HEAD
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
117 for b in branches:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
118 b_path = 'branches/%s' %b
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
119 hist_gen = self.fetch_history_at_paths([b_path], stop=head)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
120 hist = hist_gen.next()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
121 source, source_rev = self._get_copy_source(b_path, cached_head=head)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
122 # This if statement guards against projects that have non-ancestral
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
123 # branches by not listing them has branches
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
124 # Note that they probably are really ancestrally related, but there
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
125 # is just no way for us to know how.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
126 if source is not None and source_rev is not None:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
127 branch_info[b] = (source, source_rev, hist.revnum)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
128 return branch_info
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
129
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
130 @property
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
131 def tags(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
132 """Get the current tags in this repo assuming a standard layout.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
133
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
134 This returns a dictionary of tag: (source path, source rev)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
135 """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
136 tags = self.list_dir('tags').keys()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
137 tag_info = {}
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
138 head = self.HEAD
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
139 for t in tags:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
140 tag_info[t] = self._get_copy_source('tags/%s' % t,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
141 cached_head=head)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
142 return tag_info
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
143
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
144 def _get_copy_source(self, path, cached_head=None):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
145 """Get copy revision for the given path, assuming it was meant to be
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
146 a copy of the entire tree.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
147 """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
148 if not cached_head:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
149 cached_head = self.HEAD
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
150 hist_gen = self.fetch_history_at_paths([path], stop=cached_head)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
151 hist = hist_gen.next()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
152 if hist.paths[path].copyfrom_path is None:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
153 return None, None
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
154 source = hist.paths[path].copyfrom_path
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
155 source_rev = 0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
156 for p in hist.paths:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
157 if hist.paths[p].copyfrom_rev:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
158 # We assume that the revision of the source tree as it was
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
159 # copied was actually the revision of the highest revision
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
160 # copied item. This could be wrong, but in practice it will
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
161 # *probably* be correct
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
162 if source_rev < hist.paths[p].copyfrom_rev:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
163 source_rev = hist.paths[p].copyfrom_rev
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
164 source = source[len(self.subdir):]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
165 return source, source_rev
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
166
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
167 def list_dir(self, dir, revision=None):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
168 """List the contents of a server-side directory.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
169
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
170 Returns a dict-like object with one dict key per directory entry.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
171
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
172 Args:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
173 dir: the directory to list, no leading slash
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
174 rev: the revision at which to list the directory, defaults to HEAD
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
175 """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
176 if dir[-1] == '/':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
177 dir = dir[:-1]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
178 if revision is None:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
179 revision = self.HEAD
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
180 r = ra.get_dir2(self.ra, dir, revision, core.SVN_DIRENT_KIND, self.pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
181 folders, props, junk = r
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
182 return folders
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
183
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
184 def revisions(self, start=None, chunk_size=1000):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
185 """Load the history of this repo.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
186
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
187 This is LAZY. It returns a generator, and fetches a small number
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
188 of revisions at a time.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
189
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
190 The reason this is lazy is so that you can use the same repo object
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
191 to perform RA calls to get deltas.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
192 """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
193 # NB: you'd think this would work, but you'd be wrong. I'm pretty
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
194 # convinced there must be some kind of svn bug here.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
195 #return self.fetch_history_at_paths(['tags', 'trunk', 'branches'],
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
196 # start=start)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
197 # this does the same thing, but at the repo root + filtering. It's
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
198 # kind of tough cookies, sadly.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
199 for r in self.fetch_history_at_paths([''], start=start,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
200 chunk_size=chunk_size):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
201 should_yield = False
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
202 i = 0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
203 paths = list(r.paths.keys())
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
204 while i < len(paths) and not should_yield:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
205 p = paths[i]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
206 if (p.startswith('trunk') or p.startswith('tags')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
207 or p.startswith('branches')):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
208 should_yield = True
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
209 i += 1
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
210 if should_yield:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
211 yield r
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
212
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
213
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
214 def fetch_history_at_paths(self, paths, start=None, stop=None,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
215 chunk_size=1000):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
216 revisions = []
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
217 def callback(paths, revnum, author, date, message, pool):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
218 r = Revision(revnum, author, message, date, paths,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
219 strip_path=self.subdir)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
220 revisions.append(r)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
221 if not start:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
222 start = self.START
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
223 if not stop:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
224 stop = self.HEAD
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
225 while stop > start:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
226 ra.get_log(self.ra, paths,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
227 start+1,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
228 stop,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
229 chunk_size, #limit of how many log messages to load
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
230 True, # don't need to know changed paths
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
231 True, # stop on copies
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
232 callback,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
233 self.pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
234 if len(revisions) < chunk_size:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
235 # this means there was no history for the path, so force the
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
236 # loop to exit
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
237 start = stop
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
238 else:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
239 start = revisions[-1].revnum
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
240 while len(revisions) > 0:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
241 yield revisions[0]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
242 revisions.pop(0)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
243
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
244 def commit(self, paths, message, file_data, base_revision, dirs):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
245 """Commits the appropriate targets from revision in editor's store.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
246 """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
247 self.init_ra_and_client()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
248 commit_info = []
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
249 def commit_cb(_commit_info, pool):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
250 commit_info.append(_commit_info)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
251 editor, edit_baton = ra.get_commit_editor2(self.ra,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
252 message,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
253 commit_cb,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
254 None,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
255 False)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
256 checksum = []
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
257 def driver_cb(parent, path, pool):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
258 if path in dirs:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
259 return baton
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
260 base_text, new_text, action = file_data[path]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
261 compute_delta = True
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
262 if action == 'modify':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
263 baton = editor.open_file(path, parent, base_revision, pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
264 elif action == 'add':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
265 try:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
266 baton = editor.add_file(path, parent, None, -1, pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
267 except (core.SubversionException, TypeError), e:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
268 print e.message
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
269 raise
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
270 elif action == 'delete':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
271 baton = editor.delete_entry(path, base_revision, parent, pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
272 compute_delta = False
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
273
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
274 if compute_delta:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
275 handler, wh_baton = editor.apply_textdelta(baton, None,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
276 self.pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
277
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
278 txdelta_stream = delta.svn_txdelta(
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
279 cStringIO.StringIO(base_text), cStringIO.StringIO(new_text),
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
280 self.pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
281 delta.svn_txdelta_send_txstream(txdelta_stream, handler,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
282 wh_baton, pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
283
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
284 delta.path_driver(editor, edit_baton, base_revision, paths, driver_cb,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
285 self.pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
286 editor.close_edit(edit_baton, self.pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
287
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
288 def get_replay(self, revision, editor, oldest_rev_i_have=0):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
289 # this method has a tendency to chew through RAM if you don't re-init
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
290 self.init_ra_and_client()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
291 e_ptr, e_baton = delta.make_editor(editor)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
292 try:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
293 ra.replay(self.ra, revision, oldest_rev_i_have, True, e_ptr,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
294 e_baton, self.pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
295 except core.SubversionException, e:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
296 # can I depend on this number being constant?
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
297 if (e.message == "Server doesn't support the replay command"
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
298 or e.apr_err == 170003):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
299 raise SubversionRepoCanNotReplay, ('This Subversion server '
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
300 'is older than 1.4.0, and cannot satisfy replay requests.')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
301 else:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
302 raise
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
303
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
304 def get_unified_diff(self, path, revision, other_path=None, other_rev=None,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
305 deleted=True, ignore_type=False):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
306 """Gets a unidiff of path at revision against revision-1.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
307 """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
308 # works around an svn server keeping too many open files (observed
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
309 # in an svnserve from the 1.2 era)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
310 self.init_ra_and_client()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
311
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
312 old_cwd = os.getcwd()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
313 assert path[0] != '/'
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
314 url = self.svn_url + '/' + path
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
315 url2 = url
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
316 if other_path is not None:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
317 url2 = self.svn_url + '/' + other_path
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
318 if other_rev is None:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
319 other_rev = revision - 1
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
320 tmpdir = tempfile.mkdtemp('svnwrap_temp')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
321 # hot tip: the swig bridge doesn't like StringIO for these bad boys
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
322 out_path = os.path.join(tmpdir, 'diffout')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
323 error_path = os.path.join(tmpdir, 'differr')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
324 out = open(out_path, 'w')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
325 err = open(error_path, 'w')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
326 rev_old = core.svn_opt_revision_t()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
327 rev_old.kind = core.svn_opt_revision_number
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
328 rev_old.value.number = other_rev
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
329 rev_new = core.svn_opt_revision_t()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
330 rev_new.kind = core.svn_opt_revision_number
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
331 rev_new.value.number = revision
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
332 client.diff3([], url2, rev_old, url, rev_new, True, True,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
333 deleted, ignore_type, 'UTF-8', out, err,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
334 self.client_context, self.pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
335 out.close()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
336 err.close()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
337 assert len(open(error_path).read()) == 0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
338 diff = open(out_path).read()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
339 os.chdir(old_cwd)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
340 shutil.rmtree(tmpdir)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
341 return diff
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
342
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
343 def get_file(self, path, revision):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
344 out = cStringIO.StringIO()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
345 tmpdir = tempfile.mkdtemp('svnwrap_temp')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
346 # hot tip: the swig bridge doesn't like StringIO for these bad boys
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
347 out_path = os.path.join(tmpdir, 'diffout')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
348 out = open(out_path, 'w')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
349 ra.get_file(self.ra, path,revision, out , None)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
350 out.close()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
351 x = open(out_path).read()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
352 shutil.rmtree(tmpdir)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
353 return x
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
354
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
355 def proplist(self, path, revision, recurse=False):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
356 rev = core.svn_opt_revision_t()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
357 rev.kind = core.svn_opt_revision_number
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
358 rev.value.number = revision
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
359 if path[-1] == '/':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
360 path = path[:-1]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
361 if path[0] == '/':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
362 path = path[1:]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
363 pl = dict(client.proplist2(self.svn_url+'/'+path, rev, rev, True,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
364 self.client_context, self.pool))
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
365 pl2 = {}
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
366 for key, value in pl.iteritems():
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
367 pl2[key[len(self.svn_url)+1:]] = value
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
368 return pl2
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
369
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
370 def fetch_all_files_to_dir(self, path, revision, checkout_path):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
371 rev = core.svn_opt_revision_t()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
372 rev.kind = core.svn_opt_revision_number
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
373 rev.value.number = revision
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
374 client.export3(self.svn_url+'/'+path, checkout_path, rev,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
375 rev, True, True, True, 'LF', # should be 'CRLF' on win32
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
376 self.client_context, self.pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
377
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
378 class SubversionRepoCanNotReplay(Exception):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
379 """Exception raised when the svn server is too old to have replay.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
380 """