annotate svnwrap/svn_swig_wrapper.py @ 296:9be04de434ed

Get rid of .hg/svn/last_rev: We now calculate the last known revision by iterating over all known revisions and finding the highest number. Theoretically, we might be able to simply read the latest entry, but in practice, that's a bug waiting to happen. For instance, we might want to achieve compatibility with '.hg/shamap' as generated by the ConvertExtension, and it not only cannot offer a guarantee of linearity, but it also allows more than one conversion to source exists. I'd say we have other problems to care about until this turns up as a hotspot in profiling. Such as why we leak circa 100MB of memory per 1000 revisions converted ;)
author Dan Villiom Podlaski Christiansen <danchr@gmail.com>
date Fri, 27 Mar 2009 01:09:36 +0100
parents fa26c7ef0180
children 32d3f1716e66
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
47
9738a7c4e3dd fix svn push when there's just a file removal
Valentino Volonghi aka dialtone <valentino@adroll.com>
parents: 46
diff changeset
7 import hashlib
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
8
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
9 from svn import client
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
10 from svn import core
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
11 from svn import delta
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
12 from svn import ra
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
13
196
77812f98e250 Add a naive hg svn version command that works as long as hgsubversion is run from a checkout.
Augie Fackler <durin42@gmail.com>
parents: 181
diff changeset
14 def version():
77812f98e250 Add a naive hg svn version command that works as long as hgsubversion is run from a checkout.
Augie Fackler <durin42@gmail.com>
parents: 181
diff changeset
15 return '%d.%d.%d' % (core.SVN_VER_MAJOR, core.SVN_VER_MINOR, core.SVN_VER_MICRO)
77812f98e250 Add a naive hg svn version command that works as long as hgsubversion is run from a checkout.
Augie Fackler <durin42@gmail.com>
parents: 181
diff changeset
16
63
2e30b59a9c19 Added some coverage pragmas to stop it from trying to cover things we can't test.
Augie Fackler <durin42@gmail.com>
parents: 59
diff changeset
17 if (core.SVN_VER_MAJOR, core.SVN_VER_MINOR, core.SVN_VER_MICRO) < (1, 5, 0): #pragma: no cover
50
80b923ab242b Drop any pretense of supporting svn 1.4.x.
Augie Fackler <durin42@gmail.com>
parents: 47
diff changeset
18 raise ImportError, 'You must have Subversion 1.5.0 or newer and matching SWIG bindings.'
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
19
89
edeec6829d80 SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents: 87
diff changeset
20 class SubversionRepoCanNotReplay(Exception):
edeec6829d80 SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents: 87
diff changeset
21 """Exception raised when the svn server is too old to have replay.
edeec6829d80 SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents: 87
diff changeset
22 """
edeec6829d80 SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents: 87
diff changeset
23
edeec6829d80 SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents: 87
diff changeset
24 class SubversionRepoCanNotDiff(Exception):
edeec6829d80 SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents: 87
diff changeset
25 """Exception raised when the svn API diff3() command cannot be used
edeec6829d80 SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents: 87
diff changeset
26 """
edeec6829d80 SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents: 87
diff changeset
27
75
cca31b6b1318 SubversionRepo: add optrev() to help generate client API revisions
Patrick Mezard <pmezard@gmail.com>
parents: 74
diff changeset
28 def optrev(revnum):
cca31b6b1318 SubversionRepo: add optrev() to help generate client API revisions
Patrick Mezard <pmezard@gmail.com>
parents: 74
diff changeset
29 optrev = core.svn_opt_revision_t()
cca31b6b1318 SubversionRepo: add optrev() to help generate client API revisions
Patrick Mezard <pmezard@gmail.com>
parents: 74
diff changeset
30 optrev.kind = core.svn_opt_revision_number
cca31b6b1318 SubversionRepo: add optrev() to help generate client API revisions
Patrick Mezard <pmezard@gmail.com>
parents: 74
diff changeset
31 optrev.value.number = revnum
cca31b6b1318 SubversionRepo: add optrev() to help generate client API revisions
Patrick Mezard <pmezard@gmail.com>
parents: 74
diff changeset
32 return optrev
cca31b6b1318 SubversionRepo: add optrev() to help generate client API revisions
Patrick Mezard <pmezard@gmail.com>
parents: 74
diff changeset
33
50
80b923ab242b Drop any pretense of supporting svn 1.4.x.
Augie Fackler <durin42@gmail.com>
parents: 47
diff changeset
34 svn_config = core.svn_config_get_config(None)
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
35 class RaCallbacks(ra.Callbacks):
63
2e30b59a9c19 Added some coverage pragmas to stop it from trying to cover things we can't test.
Augie Fackler <durin42@gmail.com>
parents: 59
diff changeset
36 def open_tmp_file(self, pool): #pragma: no cover
46
f30cda3389c2 This appears to fix pushing over both the http and svn protocols.
Augie Fackler <durin42@gmail.com>
parents: 45
diff changeset
37 (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
38 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
39 return fn
f30cda3389c2 This appears to fix pushing over both the http and svn protocols.
Augie Fackler <durin42@gmail.com>
parents: 45
diff changeset
40
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
41 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
42 return 'hgsubversion'
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
43
50
80b923ab242b Drop any pretense of supporting svn 1.4.x.
Augie Fackler <durin42@gmail.com>
parents: 47
diff changeset
44
63
2e30b59a9c19 Added some coverage pragmas to stop it from trying to cover things we can't test.
Augie Fackler <durin42@gmail.com>
parents: 59
diff changeset
45 def user_pass_prompt(realm, default_username, ms, pool): #pragma: no cover
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
46 creds = core.svn_auth_cred_simple_t()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
47 creds.may_save = ms
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
48 if default_username:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
49 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
50 creds.username = default_username
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
51 else:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
52 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
53 sys.stderr.write('Username: ')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
54 sys.stderr.flush()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
55 creds.username = sys.stdin.readline().strip()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
56 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
57 return creds
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
58
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
59 def _create_auth_baton(pool):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
60 """Create a Subversion authentication baton. """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
61 # 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
62 # providers.h
92
7486c6f6cccc svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents: 89
diff changeset
63 platform_specific = ['svn_auth_get_gnome_keyring_simple_provider',
7486c6f6cccc svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents: 89
diff changeset
64 'svn_auth_get_gnome_keyring_ssl_client_cert_pw_provider',
7486c6f6cccc svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents: 89
diff changeset
65 'svn_auth_get_keychain_simple_provider',
7486c6f6cccc svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents: 89
diff changeset
66 'svn_auth_get_keychain_ssl_client_cert_pw_provider',
7486c6f6cccc svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents: 89
diff changeset
67 'svn_auth_get_kwallet_simple_provider',
7486c6f6cccc svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents: 89
diff changeset
68 'svn_auth_get_kwallet_ssl_client_cert_pw_provider',
7486c6f6cccc svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents: 89
diff changeset
69 'svn_auth_get_ssl_client_cert_file_provider',
7486c6f6cccc svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents: 89
diff changeset
70 'svn_auth_get_windows_simple_provider',
7486c6f6cccc svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents: 89
diff changeset
71 'svn_auth_get_windows_ssl_server_trust_provider',
7486c6f6cccc svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents: 89
diff changeset
72 ]
7486c6f6cccc svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents: 89
diff changeset
73
7486c6f6cccc svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents: 89
diff changeset
74 providers = []
7486c6f6cccc svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents: 89
diff changeset
75
7486c6f6cccc svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents: 89
diff changeset
76 for p in platform_specific:
7486c6f6cccc svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents: 89
diff changeset
77 if hasattr(core, p):
7486c6f6cccc svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents: 89
diff changeset
78 try:
7486c6f6cccc svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents: 89
diff changeset
79 providers.append(getattr(core, p)())
7486c6f6cccc svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents: 89
diff changeset
80 except RuntimeError:
7486c6f6cccc svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents: 89
diff changeset
81 pass
7486c6f6cccc svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents: 89
diff changeset
82
7486c6f6cccc svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents: 89
diff changeset
83 providers += [
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
84 client.get_simple_provider(),
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
85 client.get_username_provider(),
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
86 client.get_ssl_client_cert_file_provider(),
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
87 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
88 client.get_ssl_server_trust_file_provider(),
92
7486c6f6cccc svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents: 89
diff changeset
89 client.get_simple_prompt_provider(user_pass_prompt, 2),
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
90 ]
92
7486c6f6cccc svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents: 89
diff changeset
91
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
92 return core.svn_auth_open(providers, pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
93
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
94
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
95 class Revision(object):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
96 """Wrapper for a Subversion revision.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
97 """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
98 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
99 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
100 # TODO parse this into a datetime
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
101 self.date = date
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
102 self.paths = {}
20
2953c867ca99 Minor fixes to the push command to make it more robust.
Augie Fackler <durin42@gmail.com>
parents: 10
diff changeset
103 if paths:
2953c867ca99 Minor fixes to the push command to make it more robust.
Augie Fackler <durin42@gmail.com>
parents: 10
diff changeset
104 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
105 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
106
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
107 def __str__(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
108 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
109
87
b033d74be76b fetch_command: in stupid non-diffy mode, take changed paths in account
Patrick Mezard <pmezard@gmail.com>
parents: 83
diff changeset
110 _svntypes = {
b033d74be76b fetch_command: in stupid non-diffy mode, take changed paths in account
Patrick Mezard <pmezard@gmail.com>
parents: 83
diff changeset
111 core.svn_node_dir: 'd',
b033d74be76b fetch_command: in stupid non-diffy mode, take changed paths in account
Patrick Mezard <pmezard@gmail.com>
parents: 83
diff changeset
112 core.svn_node_file: 'f',
b033d74be76b fetch_command: in stupid non-diffy mode, take changed paths in account
Patrick Mezard <pmezard@gmail.com>
parents: 83
diff changeset
113 }
b033d74be76b fetch_command: in stupid non-diffy mode, take changed paths in account
Patrick Mezard <pmezard@gmail.com>
parents: 83
diff changeset
114
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
115 class SubversionRepo(object):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
116 """Wrapper for a Subversion repository.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
117
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
118 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
119 It takes a required param, the URL.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
120 """
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
121 def __init__(self, url='', username=''):
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
122 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
123 self.uname = username
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
124 self.auth_baton_pool = core.Pool()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
125 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
126
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
127 self.init_ra_and_client()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
128 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
129 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
130 # *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
131 self.subdir = url[len(repo_root):]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
132 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
133 self.subdir += '/'
89
edeec6829d80 SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents: 87
diff changeset
134 self.hasdiff3 = True
0
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 def init_ra_and_client(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
137 """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
138 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
139 """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
140 # 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
141 self.pool = core.Pool()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
142 self.client_context = client.create_context()
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 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
145 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
146 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
147 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
148 self.callbacks = callbacks
293
fa26c7ef0180 Exception clean-ups; use symbolic names & avoid Python 2.6 deprecations.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 196
diff changeset
149 try:
fa26c7ef0180 Exception clean-ups; use symbolic names & avoid Python 2.6 deprecations.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 196
diff changeset
150 self.ra = ra.open2(self.svn_url.encode('utf-8'), callbacks,
fa26c7ef0180 Exception clean-ups; use symbolic names & avoid Python 2.6 deprecations.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 196
diff changeset
151 svn_config, self.pool)
fa26c7ef0180 Exception clean-ups; use symbolic names & avoid Python 2.6 deprecations.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 196
diff changeset
152 except core.SubversionException, e:
fa26c7ef0180 Exception clean-ups; use symbolic names & avoid Python 2.6 deprecations.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 196
diff changeset
153 raise hgutil.Abort(e.args[0])
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
154
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
155 def HEAD(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
156 return ra.get_latest_revnum(self.ra, self.pool)
181
e37f9d3fd5e7 remove decorators (compat with python2.3)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 180
diff changeset
157 HEAD = property(HEAD)
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
158
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
159 def START(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
160 return 0
181
e37f9d3fd5e7 remove decorators (compat with python2.3)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 180
diff changeset
161 START = property(START)
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
162
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
163 def branches(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
164 """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
165 """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
166 branches = self.list_dir('branches').keys()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
167 branch_info = {}
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
168 head=self.HEAD
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
169 for b in branches:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
170 b_path = 'branches/%s' %b
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
171 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
172 hist = hist_gen.next()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
173 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
174 # 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
175 # branches by not listing them has branches
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
176 # 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
177 # 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
178 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
179 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
180 return branch_info
181
e37f9d3fd5e7 remove decorators (compat with python2.3)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 180
diff changeset
181 branches = property(branches)
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
182
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
183 def tags(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
184 """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
185
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
186 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
187 """
155
ba801f44d240 utility_commands: Implement rebuildmeta so that metadata can be rebuilt.
Augie Fackler <durin42@gmail.com>
parents: 122
diff changeset
188 return self.tags_at_rev(self.HEAD)
181
e37f9d3fd5e7 remove decorators (compat with python2.3)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 180
diff changeset
189 tags = property(tags)
155
ba801f44d240 utility_commands: Implement rebuildmeta so that metadata can be rebuilt.
Augie Fackler <durin42@gmail.com>
parents: 122
diff changeset
190
ba801f44d240 utility_commands: Implement rebuildmeta so that metadata can be rebuilt.
Augie Fackler <durin42@gmail.com>
parents: 122
diff changeset
191 def tags_at_rev(self, revision):
ba801f44d240 utility_commands: Implement rebuildmeta so that metadata can be rebuilt.
Augie Fackler <durin42@gmail.com>
parents: 122
diff changeset
192 try:
ba801f44d240 utility_commands: Implement rebuildmeta so that metadata can be rebuilt.
Augie Fackler <durin42@gmail.com>
parents: 122
diff changeset
193 tags = self.list_dir('tags', revision=revision).keys()
ba801f44d240 utility_commands: Implement rebuildmeta so that metadata can be rebuilt.
Augie Fackler <durin42@gmail.com>
parents: 122
diff changeset
194 except core.SubversionException, e:
293
fa26c7ef0180 Exception clean-ups; use symbolic names & avoid Python 2.6 deprecations.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 196
diff changeset
195 if e.apr_err == core.SVN_ERR_FS_NOT_FOUND:
155
ba801f44d240 utility_commands: Implement rebuildmeta so that metadata can be rebuilt.
Augie Fackler <durin42@gmail.com>
parents: 122
diff changeset
196 return {}
ba801f44d240 utility_commands: Implement rebuildmeta so that metadata can be rebuilt.
Augie Fackler <durin42@gmail.com>
parents: 122
diff changeset
197 raise
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
198 tag_info = {}
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
199 for t in tags:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
200 tag_info[t] = self._get_copy_source('tags/%s' % t,
155
ba801f44d240 utility_commands: Implement rebuildmeta so that metadata can be rebuilt.
Augie Fackler <durin42@gmail.com>
parents: 122
diff changeset
201 cached_head=revision)
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
202 return tag_info
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
203
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
204 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
205 """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
206 a copy of the entire tree.
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 if not cached_head:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
209 cached_head = self.HEAD
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
210 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
211 hist = hist_gen.next()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
212 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
213 return None, None
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
214 source = hist.paths[path].copyfrom_path
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
215 source_rev = 0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
216 for p in hist.paths:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
217 if hist.paths[p].copyfrom_rev:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
218 # 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
219 # 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
220 # 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
221 # *probably* be correct
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
222 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
223 source_rev = hist.paths[p].copyfrom_rev
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
224 source = source[len(self.subdir):]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
225 return source, source_rev
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
226
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
227 def list_dir(self, dir, revision=None):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
228 """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
229
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
230 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
231
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
232 Args:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
233 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
234 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
235 """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
236 if dir[-1] == '/':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
237 dir = dir[:-1]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
238 if revision is None:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
239 revision = self.HEAD
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
240 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
241 folders, props, junk = r
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
242 return folders
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 revisions(self, start=None, chunk_size=1000):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
245 """Load the history of this repo.
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 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
248 of revisions at a time.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
249
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
250 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
251 to perform RA calls to get deltas.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
252 """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
253 # 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
254 # 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
255 #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
256 # start=start)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
257 # 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
258 # kind of tough cookies, sadly.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
259 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
260 chunk_size=chunk_size):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
261 should_yield = False
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
262 i = 0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
263 paths = list(r.paths.keys())
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
264 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
265 p = paths[i]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
266 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
267 or p.startswith('branches')):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
268 should_yield = True
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
269 i += 1
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
270 if should_yield:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
271 yield r
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
272
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 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
275 chunk_size=1000):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
276 revisions = []
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
277 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
278 r = Revision(revnum, author, message, date, paths,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
279 strip_path=self.subdir)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
280 revisions.append(r)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
281 if not start:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
282 start = self.START
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
283 if not stop:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
284 stop = self.HEAD
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
285 while stop > start:
50
80b923ab242b Drop any pretense of supporting svn 1.4.x.
Augie Fackler <durin42@gmail.com>
parents: 47
diff changeset
286 ra.get_log(self.ra,
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
287 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
288 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
289 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
290 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
291 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
292 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
293 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
294 self.pool)
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
295 if len(revisions) < chunk_size:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
296 # 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
297 # loop to exit
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
298 start = stop
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
299 else:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
300 start = revisions[-1].revnum
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
301 while len(revisions) > 0:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
302 yield revisions[0]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
303 revisions.pop(0)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
304
83
6c9b7cf1c5aa push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents: 81
diff changeset
305 def commit(self, paths, message, file_data, base_revision, addeddirs,
6c9b7cf1c5aa push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents: 81
diff changeset
306 deleteddirs, properties, copies):
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
307 """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
308 """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
309 self.init_ra_and_client()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
310 commit_info = []
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
311 def commit_cb(_commit_info, pool):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
312 commit_info.append(_commit_info)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
313 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
314 message,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
315 commit_cb,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
316 None,
20
2953c867ca99 Minor fixes to the push command to make it more robust.
Augie Fackler <durin42@gmail.com>
parents: 10
diff changeset
317 False,
2953c867ca99 Minor fixes to the push command to make it more robust.
Augie Fackler <durin42@gmail.com>
parents: 10
diff changeset
318 self.pool)
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
319 checksum = []
46
f30cda3389c2 This appears to fix pushing over both the http and svn protocols.
Augie Fackler <durin42@gmail.com>
parents: 45
diff changeset
320 # 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
321 # 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
322 batons = [edit_baton, ]
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
323 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
324 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
325 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
326 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
327 return bat
83
6c9b7cf1c5aa push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents: 81
diff changeset
328 if path in deleteddirs:
6c9b7cf1c5aa push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents: 81
diff changeset
329 bat = editor.delete_entry(path, base_revision, parent, pool)
6c9b7cf1c5aa push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents: 81
diff changeset
330 batons.append(bat)
6c9b7cf1c5aa push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents: 81
diff changeset
331 return bat
175
2412800b1258 Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents: 172
diff changeset
332 if path not in file_data:
2412800b1258 Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents: 172
diff changeset
333 if path in addeddirs:
2412800b1258 Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents: 172
diff changeset
334 bat = editor.add_directory(path, parent, None, -1, pool)
2412800b1258 Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents: 172
diff changeset
335 else:
2412800b1258 Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents: 172
diff changeset
336 bat = editor.open_directory(path, parent, base_revision, pool)
2412800b1258 Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents: 172
diff changeset
337 batons.append(bat)
2412800b1258 Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents: 172
diff changeset
338 props = properties.get(path, {})
2412800b1258 Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents: 172
diff changeset
339 if 'svn:externals' in props:
2412800b1258 Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents: 172
diff changeset
340 value = props['svn:externals']
2412800b1258 Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents: 172
diff changeset
341 editor.change_dir_prop(bat, 'svn:externals', value, pool)
2412800b1258 Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents: 172
diff changeset
342 return bat
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
343 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
344 compute_delta = True
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
345 if action == 'modify':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
346 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
347 elif action == 'add':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
348 try:
70
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents: 66
diff changeset
349 frompath, fromrev = copies.get(path, (None, -1))
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents: 66
diff changeset
350 if frompath:
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents: 66
diff changeset
351 frompath = self.svn_url + '/' + frompath
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents: 66
diff changeset
352 baton = editor.add_file(path, parent, frompath, fromrev, pool)
63
2e30b59a9c19 Added some coverage pragmas to stop it from trying to cover things we can't test.
Augie Fackler <durin42@gmail.com>
parents: 59
diff changeset
353 except (core.SubversionException, TypeError), e: #pragma: no cover
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
354 print e.message
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
355 raise
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
356 elif action == 'delete':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
357 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
358 compute_delta = False
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
359
10
dfdc078661db Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents: 9
diff changeset
360 if path in properties:
dfdc078661db Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents: 9
diff changeset
361 if properties[path].get('svn:special', None):
dfdc078661db Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents: 9
diff changeset
362 new_text = 'link %s' % new_text
dfdc078661db Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents: 9
diff changeset
363 for p, v in properties[path].iteritems():
dfdc078661db Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents: 9
diff changeset
364 editor.change_file_prop(baton, p, v)
dfdc078661db Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents: 9
diff changeset
365
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
366 if compute_delta:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
367 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
368 self.pool)
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 txdelta_stream = delta.svn_txdelta(
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
371 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
372 self.pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
373 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
374 wh_baton, pool)
47
9738a7c4e3dd fix svn push when there's just a file removal
Valentino Volonghi aka dialtone <valentino@adroll.com>
parents: 46
diff changeset
375
9738a7c4e3dd fix svn push when there's just a file removal
Valentino Volonghi aka dialtone <valentino@adroll.com>
parents: 46
diff changeset
376 # TODO pass md5(new_text) instead of None
9738a7c4e3dd fix svn push when there's just a file removal
Valentino Volonghi aka dialtone <valentino@adroll.com>
parents: 46
diff changeset
377 editor.close_file(baton, None, pool)
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
378
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
379 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
380 self.pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
381 editor.close_edit(edit_baton, self.pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
382
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
383 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
384 # 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
385 self.init_ra_and_client()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
386 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
387 try:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
388 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
389 e_baton, self.pool)
63
2e30b59a9c19 Added some coverage pragmas to stop it from trying to cover things we can't test.
Augie Fackler <durin42@gmail.com>
parents: 59
diff changeset
390 except core.SubversionException, e: #pragma: no cover
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
391 # can I depend on this number being constant?
293
fa26c7ef0180 Exception clean-ups; use symbolic names & avoid Python 2.6 deprecations.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 196
diff changeset
392 if (e.apr_err == core.SVN_ERR_RA_NOT_IMPLEMENTED or
fa26c7ef0180 Exception clean-ups; use symbolic names & avoid Python 2.6 deprecations.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 196
diff changeset
393 e.apr_err == core.SVN_ERR_UNSUPPORTED_FEATURE):
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
394 raise SubversionRepoCanNotReplay, ('This Subversion server '
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
395 '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
396 else:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
397 raise
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
398
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
399 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
400 deleted=True, ignore_type=False):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
401 """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
402 """
89
edeec6829d80 SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents: 87
diff changeset
403 if not self.hasdiff3:
edeec6829d80 SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents: 87
diff changeset
404 raise SubversionRepoCanNotDiff()
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
405 # 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
406 # 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
407 self.init_ra_and_client()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
408
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
409 assert path[0] != '/'
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
410 url = self.svn_url + '/' + path
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
411 url2 = url
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
412 if other_path is not None:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
413 url2 = self.svn_url + '/' + other_path
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
414 if other_rev is None:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
415 other_rev = revision - 1
81
85dcea81f22b SubversionRepo: close files before rmtree() in diff3
Patrick Mezard <pmezard@gmail.com>
parents: 77
diff changeset
416 old_cwd = os.getcwd()
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
417 tmpdir = tempfile.mkdtemp('svnwrap_temp')
89
edeec6829d80 SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents: 87
diff changeset
418 out, err = None, None
66
a31968146f3c svnwrap: Fix leakage of temp dirs by using try/finally blocks.
Augie Fackler <durin42@gmail.com>
parents: 63
diff changeset
419 try:
a31968146f3c svnwrap: Fix leakage of temp dirs by using try/finally blocks.
Augie Fackler <durin42@gmail.com>
parents: 63
diff changeset
420 # hot tip: the swig bridge doesn't like StringIO for these bad boys
a31968146f3c svnwrap: Fix leakage of temp dirs by using try/finally blocks.
Augie Fackler <durin42@gmail.com>
parents: 63
diff changeset
421 out_path = os.path.join(tmpdir, 'diffout')
a31968146f3c svnwrap: Fix leakage of temp dirs by using try/finally blocks.
Augie Fackler <durin42@gmail.com>
parents: 63
diff changeset
422 error_path = os.path.join(tmpdir, 'differr')
89
edeec6829d80 SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents: 87
diff changeset
423 out = open(out_path, 'w')
edeec6829d80 SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents: 87
diff changeset
424 err = open(error_path, 'w')
81
85dcea81f22b SubversionRepo: close files before rmtree() in diff3
Patrick Mezard <pmezard@gmail.com>
parents: 77
diff changeset
425 try:
85dcea81f22b SubversionRepo: close files before rmtree() in diff3
Patrick Mezard <pmezard@gmail.com>
parents: 77
diff changeset
426 client.diff3([], url2, optrev(other_rev), url, optrev(revision),
85dcea81f22b SubversionRepo: close files before rmtree() in diff3
Patrick Mezard <pmezard@gmail.com>
parents: 77
diff changeset
427 True, True, deleted, ignore_type, 'UTF-8', out, err,
85dcea81f22b SubversionRepo: close files before rmtree() in diff3
Patrick Mezard <pmezard@gmail.com>
parents: 77
diff changeset
428 self.client_context, self.pool)
89
edeec6829d80 SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents: 87
diff changeset
429 except core.SubversionException, e:
edeec6829d80 SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents: 87
diff changeset
430 # "Can't write to stream: The handle is invalid."
edeec6829d80 SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents: 87
diff changeset
431 # This error happens systematically under Windows, possibly
edeec6829d80 SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents: 87
diff changeset
432 # related to file handles being non-write shareable by default.
edeec6829d80 SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents: 87
diff changeset
433 if e.apr_err != 720006:
edeec6829d80 SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents: 87
diff changeset
434 raise
edeec6829d80 SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents: 87
diff changeset
435 self.hasdiff3 = False
edeec6829d80 SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents: 87
diff changeset
436 raise SubversionRepoCanNotDiff()
edeec6829d80 SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents: 87
diff changeset
437 out.close()
edeec6829d80 SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents: 87
diff changeset
438 err.close()
edeec6829d80 SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents: 87
diff changeset
439 out, err = None, None
66
a31968146f3c svnwrap: Fix leakage of temp dirs by using try/finally blocks.
Augie Fackler <durin42@gmail.com>
parents: 63
diff changeset
440 assert len(open(error_path).read()) == 0
a31968146f3c svnwrap: Fix leakage of temp dirs by using try/finally blocks.
Augie Fackler <durin42@gmail.com>
parents: 63
diff changeset
441 diff = open(out_path).read()
a31968146f3c svnwrap: Fix leakage of temp dirs by using try/finally blocks.
Augie Fackler <durin42@gmail.com>
parents: 63
diff changeset
442 return diff
a31968146f3c svnwrap: Fix leakage of temp dirs by using try/finally blocks.
Augie Fackler <durin42@gmail.com>
parents: 63
diff changeset
443 finally:
89
edeec6829d80 SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents: 87
diff changeset
444 if out: out.close()
edeec6829d80 SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents: 87
diff changeset
445 if err: err.close()
66
a31968146f3c svnwrap: Fix leakage of temp dirs by using try/finally blocks.
Augie Fackler <durin42@gmail.com>
parents: 63
diff changeset
446 shutil.rmtree(tmpdir)
81
85dcea81f22b SubversionRepo: close files before rmtree() in diff3
Patrick Mezard <pmezard@gmail.com>
parents: 77
diff changeset
447 os.chdir(old_cwd)
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
448
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
449 def get_file(self, path, revision):
76
6c62bd201785 SubversionRepo: make get_file() return the file mode
Patrick Mezard <pmezard@gmail.com>
parents: 75
diff changeset
450 """Return content and mode of file at given path and revision.
6c62bd201785 SubversionRepo: make get_file() return the file mode
Patrick Mezard <pmezard@gmail.com>
parents: 75
diff changeset
451
97
0d3a2a7cefa3 hg_delta_editor: fix symlink prefix confusion
Patrick Mezard <pmezard@gmail.com>
parents: 92
diff changeset
452 "link " prefix is dropped from symlink content. Mode is 'x' if
0d3a2a7cefa3 hg_delta_editor: fix symlink prefix confusion
Patrick Mezard <pmezard@gmail.com>
parents: 92
diff changeset
453 file is executable, 'l' if a symlink, the empty string
0d3a2a7cefa3 hg_delta_editor: fix symlink prefix confusion
Patrick Mezard <pmezard@gmail.com>
parents: 92
diff changeset
454 otherwise. If the file does not exist at this revision, raise
0d3a2a7cefa3 hg_delta_editor: fix symlink prefix confusion
Patrick Mezard <pmezard@gmail.com>
parents: 92
diff changeset
455 IOError.
76
6c62bd201785 SubversionRepo: make get_file() return the file mode
Patrick Mezard <pmezard@gmail.com>
parents: 75
diff changeset
456 """
6c62bd201785 SubversionRepo: make get_file() return the file mode
Patrick Mezard <pmezard@gmail.com>
parents: 75
diff changeset
457 mode = ''
66
a31968146f3c svnwrap: Fix leakage of temp dirs by using try/finally blocks.
Augie Fackler <durin42@gmail.com>
parents: 63
diff changeset
458 try:
122
04c92c2c4501 SubversionRepo: work around ra.get_files() not releasing input buffer
Patrick Mezard <pmezard@gmail.com>
parents: 97
diff changeset
459 out = cStringIO.StringIO()
76
6c62bd201785 SubversionRepo: make get_file() return the file mode
Patrick Mezard <pmezard@gmail.com>
parents: 75
diff changeset
460 info = ra.get_file(self.ra, path, revision, out)
122
04c92c2c4501 SubversionRepo: work around ra.get_files() not releasing input buffer
Patrick Mezard <pmezard@gmail.com>
parents: 97
diff changeset
461 data = out.getvalue()
04c92c2c4501 SubversionRepo: work around ra.get_files() not releasing input buffer
Patrick Mezard <pmezard@gmail.com>
parents: 97
diff changeset
462 out.close()
76
6c62bd201785 SubversionRepo: make get_file() return the file mode
Patrick Mezard <pmezard@gmail.com>
parents: 75
diff changeset
463 if isinstance(info, list):
6c62bd201785 SubversionRepo: make get_file() return the file mode
Patrick Mezard <pmezard@gmail.com>
parents: 75
diff changeset
464 info = info[-1]
6c62bd201785 SubversionRepo: make get_file() return the file mode
Patrick Mezard <pmezard@gmail.com>
parents: 75
diff changeset
465 mode = ("svn:executable" in info) and 'x' or ''
6c62bd201785 SubversionRepo: make get_file() return the file mode
Patrick Mezard <pmezard@gmail.com>
parents: 75
diff changeset
466 mode = ("svn:special" in info) and 'l' or mode
74
450d5d9d3b80 SubversionRepo: do not use temporary file in get_file()
Patrick Mezard <pmezard@gmail.com>
parents: 70
diff changeset
467 except core.SubversionException, e:
450d5d9d3b80 SubversionRepo: do not use temporary file in get_file()
Patrick Mezard <pmezard@gmail.com>
parents: 70
diff changeset
468 notfound = (core.SVN_ERR_FS_NOT_FOUND,
450d5d9d3b80 SubversionRepo: do not use temporary file in get_file()
Patrick Mezard <pmezard@gmail.com>
parents: 70
diff changeset
469 core.SVN_ERR_RA_DAV_PATH_NOT_FOUND)
450d5d9d3b80 SubversionRepo: do not use temporary file in get_file()
Patrick Mezard <pmezard@gmail.com>
parents: 70
diff changeset
470 if e.apr_err in notfound: # File not found
450d5d9d3b80 SubversionRepo: do not use temporary file in get_file()
Patrick Mezard <pmezard@gmail.com>
parents: 70
diff changeset
471 raise IOError()
450d5d9d3b80 SubversionRepo: do not use temporary file in get_file()
Patrick Mezard <pmezard@gmail.com>
parents: 70
diff changeset
472 raise
97
0d3a2a7cefa3 hg_delta_editor: fix symlink prefix confusion
Patrick Mezard <pmezard@gmail.com>
parents: 92
diff changeset
473 if mode == 'l':
0d3a2a7cefa3 hg_delta_editor: fix symlink prefix confusion
Patrick Mezard <pmezard@gmail.com>
parents: 92
diff changeset
474 linkprefix = "link "
0d3a2a7cefa3 hg_delta_editor: fix symlink prefix confusion
Patrick Mezard <pmezard@gmail.com>
parents: 92
diff changeset
475 if data.startswith(linkprefix):
0d3a2a7cefa3 hg_delta_editor: fix symlink prefix confusion
Patrick Mezard <pmezard@gmail.com>
parents: 92
diff changeset
476 data = data[len(linkprefix):]
76
6c62bd201785 SubversionRepo: make get_file() return the file mode
Patrick Mezard <pmezard@gmail.com>
parents: 75
diff changeset
477 return data, mode
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
478
172
84fbf1469a31 SubversionRepo: simplify and rename proplist() into list_prop()
Patrick Mezard <pmezard@gmail.com>
parents: 155
diff changeset
479 def list_props(self, path, revision):
84fbf1469a31 SubversionRepo: simplify and rename proplist() into list_prop()
Patrick Mezard <pmezard@gmail.com>
parents: 155
diff changeset
480 """Return a mapping of property names to values, raise IOError if
84fbf1469a31 SubversionRepo: simplify and rename proplist() into list_prop()
Patrick Mezard <pmezard@gmail.com>
parents: 155
diff changeset
481 specified path does not exist.
84fbf1469a31 SubversionRepo: simplify and rename proplist() into list_prop()
Patrick Mezard <pmezard@gmail.com>
parents: 155
diff changeset
482 """
180
3f1e8a5ec9dd svn_swig_wrapper: hacky workaround to prevent running out of files in stupid
Augie Fackler <durin42@gmail.com>
parents: 175
diff changeset
483 self.init_ra_and_client()
75
cca31b6b1318 SubversionRepo: add optrev() to help generate client API revisions
Patrick Mezard <pmezard@gmail.com>
parents: 74
diff changeset
484 rev = optrev(revision)
172
84fbf1469a31 SubversionRepo: simplify and rename proplist() into list_prop()
Patrick Mezard <pmezard@gmail.com>
parents: 155
diff changeset
485 rpath = (self.svn_url + '/' + path.strip('/')).strip('/')
84fbf1469a31 SubversionRepo: simplify and rename proplist() into list_prop()
Patrick Mezard <pmezard@gmail.com>
parents: 155
diff changeset
486 try:
84fbf1469a31 SubversionRepo: simplify and rename proplist() into list_prop()
Patrick Mezard <pmezard@gmail.com>
parents: 155
diff changeset
487 pl = client.proplist2(rpath, rev, rev, False,
84fbf1469a31 SubversionRepo: simplify and rename proplist() into list_prop()
Patrick Mezard <pmezard@gmail.com>
parents: 155
diff changeset
488 self.client_context, self.pool)
84fbf1469a31 SubversionRepo: simplify and rename proplist() into list_prop()
Patrick Mezard <pmezard@gmail.com>
parents: 155
diff changeset
489 except core.SubversionException, e:
84fbf1469a31 SubversionRepo: simplify and rename proplist() into list_prop()
Patrick Mezard <pmezard@gmail.com>
parents: 155
diff changeset
490 # Specified path does not exist at this revision
84fbf1469a31 SubversionRepo: simplify and rename proplist() into list_prop()
Patrick Mezard <pmezard@gmail.com>
parents: 155
diff changeset
491 if e.apr_err == core.SVN_ERR_NODE_UNKNOWN_KIND:
84fbf1469a31 SubversionRepo: simplify and rename proplist() into list_prop()
Patrick Mezard <pmezard@gmail.com>
parents: 155
diff changeset
492 raise IOError()
84fbf1469a31 SubversionRepo: simplify and rename proplist() into list_prop()
Patrick Mezard <pmezard@gmail.com>
parents: 155
diff changeset
493 raise
84fbf1469a31 SubversionRepo: simplify and rename proplist() into list_prop()
Patrick Mezard <pmezard@gmail.com>
parents: 155
diff changeset
494 if not pl:
84fbf1469a31 SubversionRepo: simplify and rename proplist() into list_prop()
Patrick Mezard <pmezard@gmail.com>
parents: 155
diff changeset
495 return {}
84fbf1469a31 SubversionRepo: simplify and rename proplist() into list_prop()
Patrick Mezard <pmezard@gmail.com>
parents: 155
diff changeset
496 return pl[0][1]
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
497
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
498 def fetch_all_files_to_dir(self, path, revision, checkout_path):
75
cca31b6b1318 SubversionRepo: add optrev() to help generate client API revisions
Patrick Mezard <pmezard@gmail.com>
parents: 74
diff changeset
499 rev = optrev(revision)
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
500 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
501 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
502 self.client_context, self.pool)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
503
77
ed3dd5bf45da fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents: 76
diff changeset
504 def list_files(self, dirpath, revision):
ed3dd5bf45da fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents: 76
diff changeset
505 """List the content of a directory at a given revision, recursively.
ed3dd5bf45da fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents: 76
diff changeset
506
ed3dd5bf45da fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents: 76
diff changeset
507 Yield tuples (path, kind) where 'path' is the entry path relatively to
ed3dd5bf45da fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents: 76
diff changeset
508 'dirpath' and 'kind' is 'f' if the entry is a file, 'd' if it is a
ed3dd5bf45da fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents: 76
diff changeset
509 directory. Raise IOError if the directory cannot be found at given
ed3dd5bf45da fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents: 76
diff changeset
510 revision.
ed3dd5bf45da fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents: 76
diff changeset
511 """
ed3dd5bf45da fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents: 76
diff changeset
512 dirpath = dirpath.strip('/')
ed3dd5bf45da fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents: 76
diff changeset
513 pool = core.Pool()
ed3dd5bf45da fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents: 76
diff changeset
514 rpath = '/'.join([self.svn_url, dirpath]).strip('/')
ed3dd5bf45da fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents: 76
diff changeset
515 rev = optrev(revision)
ed3dd5bf45da fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents: 76
diff changeset
516 try:
ed3dd5bf45da fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents: 76
diff changeset
517 entries = client.ls(rpath, rev, True, self.client_context, pool)
ed3dd5bf45da fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents: 76
diff changeset
518 except core.SubversionException, e:
ed3dd5bf45da fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents: 76
diff changeset
519 if e.apr_err == core.SVN_ERR_FS_NOT_FOUND:
ed3dd5bf45da fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents: 76
diff changeset
520 raise IOError('%s cannot be found at r%d' % (dirpath, revision))
ed3dd5bf45da fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents: 76
diff changeset
521 raise
ed3dd5bf45da fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents: 76
diff changeset
522 for path, e in entries.iteritems():
87
b033d74be76b fetch_command: in stupid non-diffy mode, take changed paths in account
Patrick Mezard <pmezard@gmail.com>
parents: 83
diff changeset
523 kind = _svntypes.get(e.kind)
77
ed3dd5bf45da fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents: 76
diff changeset
524 yield path, kind
ed3dd5bf45da fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents: 76
diff changeset
525
87
b033d74be76b fetch_command: in stupid non-diffy mode, take changed paths in account
Patrick Mezard <pmezard@gmail.com>
parents: 83
diff changeset
526 def checkpath(self, path, revision):
b033d74be76b fetch_command: in stupid non-diffy mode, take changed paths in account
Patrick Mezard <pmezard@gmail.com>
parents: 83
diff changeset
527 """Return the entry type at the given revision, 'f', 'd' or None
b033d74be76b fetch_command: in stupid non-diffy mode, take changed paths in account
Patrick Mezard <pmezard@gmail.com>
parents: 83
diff changeset
528 if the entry does not exist.
b033d74be76b fetch_command: in stupid non-diffy mode, take changed paths in account
Patrick Mezard <pmezard@gmail.com>
parents: 83
diff changeset
529 """
b033d74be76b fetch_command: in stupid non-diffy mode, take changed paths in account
Patrick Mezard <pmezard@gmail.com>
parents: 83
diff changeset
530 kind = ra.check_path(self.ra, path.strip('/'), revision)
b033d74be76b fetch_command: in stupid non-diffy mode, take changed paths in account
Patrick Mezard <pmezard@gmail.com>
parents: 83
diff changeset
531 return _svntypes.get(kind)