annotate svnwrap/svn_swig_wrapper.py @ 46:f30cda3389c2

This appears to fix pushing over both the http and svn protocols.
author Augie Fackler <durin42@gmail.com>
date Wed, 29 Oct 2008 11:48:58 -0500
parents ce00e6ffaa90
children 9738a7c4e3dd
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
45
ce00e6ffaa90 Change the implementation of the ra_session stuff. Thanks to Ben Collins-Sussman for pointing out the problem with the other method I was using.
Augie Fackler <durin42@gmail.com>
parents: 36
diff changeset
15 class RaCallbacks(ra.Callbacks):
46
f30cda3389c2 This appears to fix pushing over both the http and svn protocols.
Augie Fackler <durin42@gmail.com>
parents: 45
diff changeset
16 def open_tmp_file(self, pool):
f30cda3389c2 This appears to fix pushing over both the http and svn protocols.
Augie Fackler <durin42@gmail.com>
parents: 45
diff changeset
17 (fd, fn) = tempfile.mkstemp()
f30cda3389c2 This appears to fix pushing over both the http and svn protocols.
Augie Fackler <durin42@gmail.com>
parents: 45
diff changeset
18 os.close(fd)
f30cda3389c2 This appears to fix pushing over both the http and svn protocols.
Augie Fackler <durin42@gmail.com>
parents: 45
diff changeset
19 return fn
f30cda3389c2 This appears to fix pushing over both the http and svn protocols.
Augie Fackler <durin42@gmail.com>
parents: 45
diff changeset
20
45
ce00e6ffaa90 Change the implementation of the ra_session stuff. Thanks to Ben Collins-Sussman for pointing out the problem with the other method I was using.
Augie Fackler <durin42@gmail.com>
parents: 36
diff changeset
21 def get_client_string(self, pool):
ce00e6ffaa90 Change the implementation of the ra_session stuff. Thanks to Ben Collins-Sussman for pointing out the problem with the other method I was using.
Augie Fackler <durin42@gmail.com>
parents: 36
diff changeset
22 return 'hgsubversion'
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
23
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
24 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
25 creds = core.svn_auth_cred_simple_t()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
26 creds.may_save = ms
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
27 if default_username:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
28 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
29 creds.username = default_username
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
30 else:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
31 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
32 sys.stderr.write('Username: ')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
33 sys.stderr.flush()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
34 creds.username = sys.stdin.readline().strip()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
35 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
36 return creds
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
37
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
38 def _create_auth_baton(pool):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
39 """Create a Subversion authentication baton. """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
40 # 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
41 # providers.h
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
42 providers = [
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
43 client.get_simple_provider(),
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
44 client.get_username_provider(),
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
45 client.get_ssl_client_cert_file_provider(),
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
46 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
47 client.get_ssl_server_trust_file_provider(),
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
48 ]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
49 # Platform-dependant authentication methods
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
50 if hasattr(client, 'get_windows_simple_provider'):
36
c4523e651325 Fix tests against the improved SWIG bindings in Subversion 1.6.
Augie Fackler <durin42@gmail.com>
parents: 20
diff changeset
51 try:
c4523e651325 Fix tests against the improved SWIG bindings in Subversion 1.6.
Augie Fackler <durin42@gmail.com>
parents: 20
diff changeset
52 providers.append(client.get_windows_simple_provider())
c4523e651325 Fix tests against the improved SWIG bindings in Subversion 1.6.
Augie Fackler <durin42@gmail.com>
parents: 20
diff changeset
53 except:
c4523e651325 Fix tests against the improved SWIG bindings in Subversion 1.6.
Augie Fackler <durin42@gmail.com>
parents: 20
diff changeset
54 pass
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
55 if hasattr(client, 'get_keychain_simple_provider'):
36
c4523e651325 Fix tests against the improved SWIG bindings in Subversion 1.6.
Augie Fackler <durin42@gmail.com>
parents: 20
diff changeset
56 try:
c4523e651325 Fix tests against the improved SWIG bindings in Subversion 1.6.
Augie Fackler <durin42@gmail.com>
parents: 20
diff changeset
57 providers.append(client.get_keychain_simple_provider())
c4523e651325 Fix tests against the improved SWIG bindings in Subversion 1.6.
Augie Fackler <durin42@gmail.com>
parents: 20
diff changeset
58 except:
c4523e651325 Fix tests against the improved SWIG bindings in Subversion 1.6.
Augie Fackler <durin42@gmail.com>
parents: 20
diff changeset
59 pass
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
60 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
61 ])
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
62 return core.svn_auth_open(providers, pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
63
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 Revision(object):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
66 """Wrapper for a Subversion revision.
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 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
69 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
70 # TODO parse this into a datetime
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
71 self.date = date
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
72 self.paths = {}
20
2953c867ca99 Minor fixes to the push command to make it more robust.
Augie Fackler <durin42@gmail.com>
parents: 10
diff changeset
73 if paths:
2953c867ca99 Minor fixes to the push command to make it more robust.
Augie Fackler <durin42@gmail.com>
parents: 10
diff changeset
74 for p in paths:
2953c867ca99 Minor fixes to the push command to make it more robust.
Augie Fackler <durin42@gmail.com>
parents: 10
diff changeset
75 self.paths[p[len(strip_path):]] = paths[p]
0
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 def __str__(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
78 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
79
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
80 class SubversionRepo(object):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
81 """Wrapper for a Subversion repository.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
82
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
83 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
84 It takes a required param, the URL.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
85 """
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
86 def __init__(self, url='', username=''):
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
87 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
88 self.uname = username
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
89 self.auth_baton_pool = core.Pool()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
90 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
91
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
92 self.init_ra_and_client()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
93 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
94 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
95 # *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
96 self.subdir = url[len(repo_root):]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
97 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
98 self.subdir += '/'
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
99
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
100 def init_ra_and_client(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
101 """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
102 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
103 """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
104 # 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
105 self.pool = core.Pool()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
106 self.client_context = client.create_context()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
107 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
108 core.SVN_AUTH_PARAM_DEFAULT_USERNAME,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
109 self.uname)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
110
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
111 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
112 self.client_context.config = svn_config
45
ce00e6ffaa90 Change the implementation of the ra_session stuff. Thanks to Ben Collins-Sussman for pointing out the problem with the other method I was using.
Augie Fackler <durin42@gmail.com>
parents: 36
diff changeset
113 callbacks = RaCallbacks()
ce00e6ffaa90 Change the implementation of the ra_session stuff. Thanks to Ben Collins-Sussman for pointing out the problem with the other method I was using.
Augie Fackler <durin42@gmail.com>
parents: 36
diff changeset
114 callbacks.auth_baton = self.auth_baton
ce00e6ffaa90 Change the implementation of the ra_session stuff. Thanks to Ben Collins-Sussman for pointing out the problem with the other method I was using.
Augie Fackler <durin42@gmail.com>
parents: 36
diff changeset
115 self.callbacks = callbacks
ce00e6ffaa90 Change the implementation of the ra_session stuff. Thanks to Ben Collins-Sussman for pointing out the problem with the other method I was using.
Augie Fackler <durin42@gmail.com>
parents: 36
diff changeset
116 self.ra = ra.open2(self.svn_url.encode('utf-8'), callbacks,
ce00e6ffaa90 Change the implementation of the ra_session stuff. Thanks to Ben Collins-Sussman for pointing out the problem with the other method I was using.
Augie Fackler <durin42@gmail.com>
parents: 36
diff changeset
117 svn_config)
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
118
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
119
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
120 @property
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
121 def HEAD(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
122 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
123
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
124 @property
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
125 def START(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
126 return 0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
127
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
128 @property
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
129 def branches(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
130 """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
131 """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
132 branches = self.list_dir('branches').keys()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
133 branch_info = {}
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
134 head=self.HEAD
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
135 for b in branches:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
136 b_path = 'branches/%s' %b
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
137 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
138 hist = hist_gen.next()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
139 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
140 # 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
141 # branches by not listing them has branches
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
142 # 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
143 # 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
144 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
145 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
146 return branch_info
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 @property
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
149 def tags(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
150 """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
151
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
152 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
153 """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
154 tags = self.list_dir('tags').keys()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
155 tag_info = {}
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
156 head = self.HEAD
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
157 for t in tags:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
158 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
159 cached_head=head)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
160 return tag_info
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
161
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
162 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
163 """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
164 a copy of the entire tree.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
165 """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
166 if not cached_head:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
167 cached_head = self.HEAD
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
168 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
169 hist = hist_gen.next()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
170 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
171 return None, None
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
172 source = hist.paths[path].copyfrom_path
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
173 source_rev = 0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
174 for p in hist.paths:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
175 if hist.paths[p].copyfrom_rev:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
176 # 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
177 # 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
178 # 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
179 # *probably* be correct
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
180 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
181 source_rev = hist.paths[p].copyfrom_rev
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
182 source = source[len(self.subdir):]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
183 return source, source_rev
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
184
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
185 def list_dir(self, dir, revision=None):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
186 """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
187
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
188 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
189
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
190 Args:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
191 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
192 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
193 """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
194 if dir[-1] == '/':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
195 dir = dir[:-1]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
196 if revision is None:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
197 revision = self.HEAD
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
198 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
199 folders, props, junk = r
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
200 return folders
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
201
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
202 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
203 """Load the history of this repo.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
204
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
205 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
206 of revisions at a time.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
207
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
208 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
209 to perform RA calls to get deltas.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
210 """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
211 # 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
212 # 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
213 #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
214 # start=start)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
215 # 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
216 # kind of tough cookies, sadly.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
217 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
218 chunk_size=chunk_size):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
219 should_yield = False
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
220 i = 0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
221 paths = list(r.paths.keys())
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
222 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
223 p = paths[i]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
224 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
225 or p.startswith('branches')):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
226 should_yield = True
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
227 i += 1
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
228 if should_yield:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
229 yield r
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
230
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
231
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
232 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
233 chunk_size=1000):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
234 revisions = []
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
235 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
236 r = Revision(revnum, author, message, date, paths,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
237 strip_path=self.subdir)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
238 revisions.append(r)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
239 if not start:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
240 start = self.START
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
241 if not stop:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
242 stop = self.HEAD
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
243 while stop > start:
45
ce00e6ffaa90 Change the implementation of the ra_session stuff. Thanks to Ben Collins-Sussman for pointing out the problem with the other method I was using.
Augie Fackler <durin42@gmail.com>
parents: 36
diff changeset
244 ra.get_log(self.ra,
ce00e6ffaa90 Change the implementation of the ra_session stuff. Thanks to Ben Collins-Sussman for pointing out the problem with the other method I was using.
Augie Fackler <durin42@gmail.com>
parents: 36
diff changeset
245 paths,
ce00e6ffaa90 Change the implementation of the ra_session stuff. Thanks to Ben Collins-Sussman for pointing out the problem with the other method I was using.
Augie Fackler <durin42@gmail.com>
parents: 36
diff changeset
246 start+1,
ce00e6ffaa90 Change the implementation of the ra_session stuff. Thanks to Ben Collins-Sussman for pointing out the problem with the other method I was using.
Augie Fackler <durin42@gmail.com>
parents: 36
diff changeset
247 stop,
ce00e6ffaa90 Change the implementation of the ra_session stuff. Thanks to Ben Collins-Sussman for pointing out the problem with the other method I was using.
Augie Fackler <durin42@gmail.com>
parents: 36
diff changeset
248 chunk_size, #limit of how many log messages to load
ce00e6ffaa90 Change the implementation of the ra_session stuff. Thanks to Ben Collins-Sussman for pointing out the problem with the other method I was using.
Augie Fackler <durin42@gmail.com>
parents: 36
diff changeset
249 True, # don't need to know changed paths
ce00e6ffaa90 Change the implementation of the ra_session stuff. Thanks to Ben Collins-Sussman for pointing out the problem with the other method I was using.
Augie Fackler <durin42@gmail.com>
parents: 36
diff changeset
250 True, # stop on copies
ce00e6ffaa90 Change the implementation of the ra_session stuff. Thanks to Ben Collins-Sussman for pointing out the problem with the other method I was using.
Augie Fackler <durin42@gmail.com>
parents: 36
diff changeset
251 callback,
ce00e6ffaa90 Change the implementation of the ra_session stuff. Thanks to Ben Collins-Sussman for pointing out the problem with the other method I was using.
Augie Fackler <durin42@gmail.com>
parents: 36
diff changeset
252 self.pool)
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
253 if len(revisions) < chunk_size:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
254 # 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
255 # loop to exit
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
256 start = stop
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
257 else:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
258 start = revisions[-1].revnum
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
259 while len(revisions) > 0:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
260 yield revisions[0]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
261 revisions.pop(0)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
262
10
dfdc078661db Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents: 9
diff changeset
263 def commit(self, paths, message, file_data, base_revision, dirs,
dfdc078661db Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents: 9
diff changeset
264 properties):
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
265 """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
266 """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
267 self.init_ra_and_client()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
268 commit_info = []
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
269 def commit_cb(_commit_info, pool):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
270 commit_info.append(_commit_info)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
271 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
272 message,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
273 commit_cb,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
274 None,
20
2953c867ca99 Minor fixes to the push command to make it more robust.
Augie Fackler <durin42@gmail.com>
parents: 10
diff changeset
275 False,
2953c867ca99 Minor fixes to the push command to make it more robust.
Augie Fackler <durin42@gmail.com>
parents: 10
diff changeset
276 self.pool)
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
277 checksum = []
46
f30cda3389c2 This appears to fix pushing over both the http and svn protocols.
Augie Fackler <durin42@gmail.com>
parents: 45
diff changeset
278 # internal dir batons can fall out of scope and get GCed before svn is
f30cda3389c2 This appears to fix pushing over both the http and svn protocols.
Augie Fackler <durin42@gmail.com>
parents: 45
diff changeset
279 # done with them. This prevents that (credit to gvn for the idea).
f30cda3389c2 This appears to fix pushing over both the http and svn protocols.
Augie Fackler <durin42@gmail.com>
parents: 45
diff changeset
280 batons = [edit_baton, ]
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
281 def driver_cb(parent, path, pool):
46
f30cda3389c2 This appears to fix pushing over both the http and svn protocols.
Augie Fackler <durin42@gmail.com>
parents: 45
diff changeset
282 if not parent:
f30cda3389c2 This appears to fix pushing over both the http and svn protocols.
Augie Fackler <durin42@gmail.com>
parents: 45
diff changeset
283 bat = editor.open_root(edit_baton, base_revision, self.pool)
f30cda3389c2 This appears to fix pushing over both the http and svn protocols.
Augie Fackler <durin42@gmail.com>
parents: 45
diff changeset
284 batons.append(bat)
f30cda3389c2 This appears to fix pushing over both the http and svn protocols.
Augie Fackler <durin42@gmail.com>
parents: 45
diff changeset
285 return bat
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
286 if path in dirs:
46
f30cda3389c2 This appears to fix pushing over both the http and svn protocols.
Augie Fackler <durin42@gmail.com>
parents: 45
diff changeset
287 bat = editor.add_directory(path, parent, None, -1, pool)
f30cda3389c2 This appears to fix pushing over both the http and svn protocols.
Augie Fackler <durin42@gmail.com>
parents: 45
diff changeset
288 batons.append(bat)
f30cda3389c2 This appears to fix pushing over both the http and svn protocols.
Augie Fackler <durin42@gmail.com>
parents: 45
diff changeset
289 return bat
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
290 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
291 compute_delta = True
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
292 if action == 'modify':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
293 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
294 elif action == 'add':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
295 try:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
296 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
297 except (core.SubversionException, TypeError), e:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
298 print e.message
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
299 raise
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
300 elif action == 'delete':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
301 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
302 compute_delta = False
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
303
10
dfdc078661db Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents: 9
diff changeset
304 if path in properties:
dfdc078661db Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents: 9
diff changeset
305 if properties[path].get('svn:special', None):
dfdc078661db Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents: 9
diff changeset
306 new_text = 'link %s' % new_text
dfdc078661db Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents: 9
diff changeset
307 for p, v in properties[path].iteritems():
dfdc078661db Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents: 9
diff changeset
308 editor.change_file_prop(baton, p, v)
dfdc078661db Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents: 9
diff changeset
309
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
310 if compute_delta:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
311 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
312 self.pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
313
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
314 txdelta_stream = delta.svn_txdelta(
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
315 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
316 self.pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
317 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
318 wh_baton, pool)
46
f30cda3389c2 This appears to fix pushing over both the http and svn protocols.
Augie Fackler <durin42@gmail.com>
parents: 45
diff changeset
319 # TODO pass md5(new_text) instead of None
f30cda3389c2 This appears to fix pushing over both the http and svn protocols.
Augie Fackler <durin42@gmail.com>
parents: 45
diff changeset
320 editor.close_file(baton, None)
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
321
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
322 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
323 self.pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
324 editor.close_edit(edit_baton, self.pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
325
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
326 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
327 # 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
328 self.init_ra_and_client()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
329 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
330 try:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
331 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
332 e_baton, self.pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
333 except core.SubversionException, e:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
334 # 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
335 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
336 or e.apr_err == 170003):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
337 raise SubversionRepoCanNotReplay, ('This Subversion server '
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
338 '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
339 else:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
340 raise
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
341
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
342 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
343 deleted=True, ignore_type=False):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
344 """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
345 """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
346 # 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
347 # 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
348 self.init_ra_and_client()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
349
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
350 old_cwd = os.getcwd()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
351 assert path[0] != '/'
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
352 url = self.svn_url + '/' + path
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
353 url2 = url
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
354 if other_path is not None:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
355 url2 = self.svn_url + '/' + other_path
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
356 if other_rev is None:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
357 other_rev = revision - 1
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
358 tmpdir = tempfile.mkdtemp('svnwrap_temp')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
359 # 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
360 out_path = os.path.join(tmpdir, 'diffout')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
361 error_path = os.path.join(tmpdir, 'differr')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
362 out = open(out_path, 'w')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
363 err = open(error_path, 'w')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
364 rev_old = core.svn_opt_revision_t()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
365 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
366 rev_old.value.number = other_rev
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
367 rev_new = core.svn_opt_revision_t()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
368 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
369 rev_new.value.number = revision
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
370 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
371 deleted, ignore_type, 'UTF-8', out, err,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
372 self.client_context, self.pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
373 out.close()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
374 err.close()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
375 assert len(open(error_path).read()) == 0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
376 diff = open(out_path).read()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
377 os.chdir(old_cwd)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
378 shutil.rmtree(tmpdir)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
379 return diff
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
380
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
381 def get_file(self, path, revision):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
382 out = cStringIO.StringIO()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
383 tmpdir = tempfile.mkdtemp('svnwrap_temp')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
384 # 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
385 out_path = os.path.join(tmpdir, 'diffout')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
386 out = open(out_path, 'w')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
387 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
388 out.close()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
389 x = open(out_path).read()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
390 shutil.rmtree(tmpdir)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
391 return x
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
392
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
393 def proplist(self, path, revision, recurse=False):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
394 rev = core.svn_opt_revision_t()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
395 rev.kind = core.svn_opt_revision_number
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
396 rev.value.number = revision
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
397 if path[-1] == '/':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
398 path = path[:-1]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
399 if path[0] == '/':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
400 path = path[1:]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
401 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
402 self.client_context, self.pool))
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
403 pl2 = {}
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
404 for key, value in pl.iteritems():
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
405 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
406 return pl2
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
407
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
408 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
409 rev = core.svn_opt_revision_t()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
410 rev.kind = core.svn_opt_revision_number
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
411 rev.value.number = revision
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
412 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
413 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
414 self.client_context, self.pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
415
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
416 class SubversionRepoCanNotReplay(Exception):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
417 """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
418 """