Mercurial > hgsubversion
annotate svnwrap/svn_swig_wrapper.py @ 92:7486c6f6cccc
svnwrap: Fix handling of auth providers so cached credentials can work.
Also fixed things so that svn 1.6 should enable platform-specific auth providers.
author | Augie Fackler <durin42@gmail.com> |
---|---|
date | Wed, 19 Nov 2008 09:41:09 -0600 |
parents | edeec6829d80 |
children | 0d3a2a7cefa3 |
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 |
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
|
14 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
|
15 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
|
16 |
89
edeec6829d80
SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents:
87
diff
changeset
|
17 class SubversionRepoCanNotReplay(Exception): |
edeec6829d80
SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents:
87
diff
changeset
|
18 """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
|
19 """ |
edeec6829d80
SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents:
87
diff
changeset
|
20 |
edeec6829d80
SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents:
87
diff
changeset
|
21 class SubversionRepoCanNotDiff(Exception): |
edeec6829d80
SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents:
87
diff
changeset
|
22 """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
|
23 """ |
edeec6829d80
SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents:
87
diff
changeset
|
24 |
75
cca31b6b1318
SubversionRepo: add optrev() to help generate client API revisions
Patrick Mezard <pmezard@gmail.com>
parents:
74
diff
changeset
|
25 def optrev(revnum): |
cca31b6b1318
SubversionRepo: add optrev() to help generate client API revisions
Patrick Mezard <pmezard@gmail.com>
parents:
74
diff
changeset
|
26 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
|
27 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
|
28 optrev.value.number = revnum |
cca31b6b1318
SubversionRepo: add optrev() to help generate client API revisions
Patrick Mezard <pmezard@gmail.com>
parents:
74
diff
changeset
|
29 return optrev |
cca31b6b1318
SubversionRepo: add optrev() to help generate client API revisions
Patrick Mezard <pmezard@gmail.com>
parents:
74
diff
changeset
|
30 |
50
80b923ab242b
Drop any pretense of supporting svn 1.4.x.
Augie Fackler <durin42@gmail.com>
parents:
47
diff
changeset
|
31 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
|
32 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
|
33 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
|
34 (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
|
35 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
|
36 return fn |
f30cda3389c2
This appears to fix pushing over both the http and svn protocols.
Augie Fackler <durin42@gmail.com>
parents:
45
diff
changeset
|
37 |
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
|
38 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
|
39 return 'hgsubversion' |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
40 |
50
80b923ab242b
Drop any pretense of supporting svn 1.4.x.
Augie Fackler <durin42@gmail.com>
parents:
47
diff
changeset
|
41 |
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
|
42 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
|
43 creds = core.svn_auth_cred_simple_t() |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
44 creds.may_save = ms |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
45 if default_username: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
46 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
|
47 creds.username = default_username |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
48 else: |
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 sys.stderr.write('Username: ') |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
51 sys.stderr.flush() |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
52 creds.username = sys.stdin.readline().strip() |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
53 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
|
54 return creds |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
55 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
56 def _create_auth_baton(pool): |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
57 """Create a Subversion authentication baton. """ |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
58 # 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
|
59 # providers.h |
92
7486c6f6cccc
svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents:
89
diff
changeset
|
60 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
|
61 '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
|
62 '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
|
63 '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
|
64 '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
|
65 '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
|
66 '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
|
67 '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
|
68 '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
|
69 ] |
7486c6f6cccc
svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents:
89
diff
changeset
|
70 |
7486c6f6cccc
svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents:
89
diff
changeset
|
71 providers = [] |
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 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
|
74 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
|
75 try: |
7486c6f6cccc
svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents:
89
diff
changeset
|
76 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
|
77 except RuntimeError: |
7486c6f6cccc
svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents:
89
diff
changeset
|
78 pass |
7486c6f6cccc
svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents:
89
diff
changeset
|
79 |
7486c6f6cccc
svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents:
89
diff
changeset
|
80 providers += [ |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
81 client.get_simple_provider(), |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
82 client.get_username_provider(), |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
83 client.get_ssl_client_cert_file_provider(), |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
84 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
|
85 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
|
86 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
|
87 ] |
92
7486c6f6cccc
svnwrap: Fix handling of auth providers so cached credentials can work.
Augie Fackler <durin42@gmail.com>
parents:
89
diff
changeset
|
88 |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
89 return core.svn_auth_open(providers, pool) |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
90 |
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 class Revision(object): |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
93 """Wrapper for a Subversion revision. |
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 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
|
96 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
|
97 # TODO parse this into a datetime |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
98 self.date = date |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
99 self.paths = {} |
20
2953c867ca99
Minor fixes to the push command to make it more robust.
Augie Fackler <durin42@gmail.com>
parents:
10
diff
changeset
|
100 if paths: |
2953c867ca99
Minor fixes to the push command to make it more robust.
Augie Fackler <durin42@gmail.com>
parents:
10
diff
changeset
|
101 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
|
102 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
|
103 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
104 def __str__(self): |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
105 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
|
106 |
87
b033d74be76b
fetch_command: in stupid non-diffy mode, take changed paths in account
Patrick Mezard <pmezard@gmail.com>
parents:
83
diff
changeset
|
107 _svntypes = { |
b033d74be76b
fetch_command: in stupid non-diffy mode, take changed paths in account
Patrick Mezard <pmezard@gmail.com>
parents:
83
diff
changeset
|
108 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
|
109 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
|
110 } |
b033d74be76b
fetch_command: in stupid non-diffy mode, take changed paths in account
Patrick Mezard <pmezard@gmail.com>
parents:
83
diff
changeset
|
111 |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
112 class SubversionRepo(object): |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
113 """Wrapper for a Subversion repository. |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
114 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
115 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
|
116 It takes a required param, the URL. |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
117 """ |
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
|
118 def __init__(self, url='', username=''): |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
119 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
|
120 self.uname = username |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
121 self.auth_baton_pool = core.Pool() |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
122 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
|
123 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
124 self.init_ra_and_client() |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
125 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
|
126 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
|
127 # *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
|
128 self.subdir = url[len(repo_root):] |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
129 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
|
130 self.subdir += '/' |
89
edeec6829d80
SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents:
87
diff
changeset
|
131 self.hasdiff3 = True |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
132 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
133 def init_ra_and_client(self): |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
134 """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
|
135 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
|
136 """ |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
137 # 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
|
138 self.pool = core.Pool() |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
139 self.client_context = client.create_context() |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
140 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
141 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
|
142 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
|
143 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
|
144 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
|
145 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
|
146 self.ra = ra.open2(self.svn_url.encode('utf-8'), callbacks, |
50
80b923ab242b
Drop any pretense of supporting svn 1.4.x.
Augie Fackler <durin42@gmail.com>
parents:
47
diff
changeset
|
147 svn_config, self.pool) |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
148 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
149 @property |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
150 def HEAD(self): |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
151 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
|
152 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
153 @property |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
154 def START(self): |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
155 return 0 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
156 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
157 @property |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
158 def branches(self): |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
159 """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
|
160 """ |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
161 branches = self.list_dir('branches').keys() |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
162 branch_info = {} |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
163 head=self.HEAD |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
164 for b in branches: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
165 b_path = 'branches/%s' %b |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
166 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
|
167 hist = hist_gen.next() |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
168 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
|
169 # 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
|
170 # branches by not listing them has branches |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
171 # 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
|
172 # 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
|
173 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
|
174 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
|
175 return branch_info |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
176 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
177 @property |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
178 def tags(self): |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
179 """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
|
180 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
181 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
|
182 """ |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
183 tags = self.list_dir('tags').keys() |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
184 tag_info = {} |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
185 head = self.HEAD |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
186 for t in tags: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
187 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
|
188 cached_head=head) |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
189 return tag_info |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
190 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
191 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
|
192 """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
|
193 a copy of the entire tree. |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
194 """ |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
195 if not cached_head: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
196 cached_head = self.HEAD |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
197 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
|
198 hist = hist_gen.next() |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
199 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
|
200 return None, None |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
201 source = hist.paths[path].copyfrom_path |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
202 source_rev = 0 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
203 for p in hist.paths: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
204 if hist.paths[p].copyfrom_rev: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
205 # 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
|
206 # 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
|
207 # 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
|
208 # *probably* be correct |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
209 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
|
210 source_rev = hist.paths[p].copyfrom_rev |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
211 source = source[len(self.subdir):] |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
212 return source, source_rev |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
213 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
214 def list_dir(self, dir, revision=None): |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
215 """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
|
216 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
217 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
|
218 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
219 Args: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
220 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
|
221 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
|
222 """ |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
223 if dir[-1] == '/': |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
224 dir = dir[:-1] |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
225 if revision is None: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
226 revision = self.HEAD |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
227 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
|
228 folders, props, junk = r |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
229 return folders |
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 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
|
232 """Load the history of this repo. |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
233 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
234 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
|
235 of revisions at a time. |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
236 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
237 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
|
238 to perform RA calls to get deltas. |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
239 """ |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
240 # 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
|
241 # 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
|
242 #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
|
243 # start=start) |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
244 # 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
|
245 # kind of tough cookies, sadly. |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
246 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
|
247 chunk_size=chunk_size): |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
248 should_yield = False |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
249 i = 0 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
250 paths = list(r.paths.keys()) |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
251 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
|
252 p = paths[i] |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
253 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
|
254 or p.startswith('branches')): |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
255 should_yield = True |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
256 i += 1 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
257 if should_yield: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
258 yield r |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
259 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
260 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
261 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
|
262 chunk_size=1000): |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
263 revisions = [] |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
264 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
|
265 r = Revision(revnum, author, message, date, paths, |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
266 strip_path=self.subdir) |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
267 revisions.append(r) |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
268 if not start: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
269 start = self.START |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
270 if not stop: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
271 stop = self.HEAD |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
272 while stop > start: |
50
80b923ab242b
Drop any pretense of supporting svn 1.4.x.
Augie Fackler <durin42@gmail.com>
parents:
47
diff
changeset
|
273 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
|
274 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
|
275 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
|
276 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
|
277 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
|
278 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
|
279 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
|
280 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
|
281 self.pool) |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
282 if len(revisions) < chunk_size: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
283 # 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
|
284 # loop to exit |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
285 start = stop |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
286 else: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
287 start = revisions[-1].revnum |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
288 while len(revisions) > 0: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
289 yield revisions[0] |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
290 revisions.pop(0) |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
291 |
83
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
81
diff
changeset
|
292 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
|
293 deleteddirs, properties, copies): |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
294 """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
|
295 """ |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
296 self.init_ra_and_client() |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
297 commit_info = [] |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
298 def commit_cb(_commit_info, pool): |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
299 commit_info.append(_commit_info) |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
300 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
|
301 message, |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
302 commit_cb, |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
303 None, |
20
2953c867ca99
Minor fixes to the push command to make it more robust.
Augie Fackler <durin42@gmail.com>
parents:
10
diff
changeset
|
304 False, |
2953c867ca99
Minor fixes to the push command to make it more robust.
Augie Fackler <durin42@gmail.com>
parents:
10
diff
changeset
|
305 self.pool) |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
306 checksum = [] |
46
f30cda3389c2
This appears to fix pushing over both the http and svn protocols.
Augie Fackler <durin42@gmail.com>
parents:
45
diff
changeset
|
307 # 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
|
308 # 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
|
309 batons = [edit_baton, ] |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
310 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
|
311 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
|
312 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
|
313 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
|
314 return bat |
83
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
81
diff
changeset
|
315 if path in addeddirs: |
46
f30cda3389c2
This appears to fix pushing over both the http and svn protocols.
Augie Fackler <durin42@gmail.com>
parents:
45
diff
changeset
|
316 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
|
317 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
|
318 return bat |
83
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
81
diff
changeset
|
319 if path in deleteddirs: |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
81
diff
changeset
|
320 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
|
321 batons.append(bat) |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
81
diff
changeset
|
322 return bat |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
323 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
|
324 compute_delta = True |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
325 if action == 'modify': |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
326 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
|
327 elif action == 'add': |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
328 try: |
70
49b7cbe4c8e3
push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
66
diff
changeset
|
329 frompath, fromrev = copies.get(path, (None, -1)) |
49b7cbe4c8e3
push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
66
diff
changeset
|
330 if frompath: |
49b7cbe4c8e3
push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
66
diff
changeset
|
331 frompath = self.svn_url + '/' + frompath |
49b7cbe4c8e3
push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
66
diff
changeset
|
332 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
|
333 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
|
334 print e.message |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
335 raise |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
336 elif action == 'delete': |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
337 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
|
338 compute_delta = False |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
339 |
10
dfdc078661db
Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents:
9
diff
changeset
|
340 if path in properties: |
dfdc078661db
Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents:
9
diff
changeset
|
341 if properties[path].get('svn:special', None): |
dfdc078661db
Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents:
9
diff
changeset
|
342 new_text = 'link %s' % new_text |
dfdc078661db
Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents:
9
diff
changeset
|
343 for p, v in properties[path].iteritems(): |
dfdc078661db
Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents:
9
diff
changeset
|
344 editor.change_file_prop(baton, p, v) |
dfdc078661db
Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents:
9
diff
changeset
|
345 |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
346 if compute_delta: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
347 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
|
348 self.pool) |
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 txdelta_stream = delta.svn_txdelta( |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
351 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
|
352 self.pool) |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
353 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
|
354 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
|
355 |
9738a7c4e3dd
fix svn push when there's just a file removal
Valentino Volonghi aka dialtone <valentino@adroll.com>
parents:
46
diff
changeset
|
356 # 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
|
357 editor.close_file(baton, None, pool) |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
358 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
359 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
|
360 self.pool) |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
361 editor.close_edit(edit_baton, self.pool) |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
362 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
363 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
|
364 # 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
|
365 self.init_ra_and_client() |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
366 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
|
367 try: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
368 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
|
369 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
|
370 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
|
371 # 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
|
372 if (e.message == "Server doesn't support the replay command" |
59
430af23bef4a
Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents:
51
diff
changeset
|
373 or e.apr_err == 170003 |
51
fd5aadd552c8
Catch other varieties of the server not having replay.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents:
50
diff
changeset
|
374 or e.message == 'The requested report is unknown.' |
fd5aadd552c8
Catch other varieties of the server not having replay.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents:
50
diff
changeset
|
375 or e.apr_err == 200007): |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
376 raise SubversionRepoCanNotReplay, ('This Subversion server ' |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
377 '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
|
378 else: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
379 raise |
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_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
|
382 deleted=True, ignore_type=False): |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
383 """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
|
384 """ |
89
edeec6829d80
SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents:
87
diff
changeset
|
385 if not self.hasdiff3: |
edeec6829d80
SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents:
87
diff
changeset
|
386 raise SubversionRepoCanNotDiff() |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
387 # 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
|
388 # 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
|
389 self.init_ra_and_client() |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
390 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
391 assert path[0] != '/' |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
392 url = self.svn_url + '/' + path |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
393 url2 = url |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
394 if other_path is not None: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
395 url2 = self.svn_url + '/' + other_path |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
396 if other_rev is None: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
397 other_rev = revision - 1 |
81
85dcea81f22b
SubversionRepo: close files before rmtree() in diff3
Patrick Mezard <pmezard@gmail.com>
parents:
77
diff
changeset
|
398 old_cwd = os.getcwd() |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
399 tmpdir = tempfile.mkdtemp('svnwrap_temp') |
89
edeec6829d80
SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents:
87
diff
changeset
|
400 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
|
401 try: |
a31968146f3c
svnwrap: Fix leakage of temp dirs by using try/finally blocks.
Augie Fackler <durin42@gmail.com>
parents:
63
diff
changeset
|
402 # 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
|
403 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
|
404 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
|
405 out = open(out_path, 'w') |
edeec6829d80
SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents:
87
diff
changeset
|
406 err = open(error_path, 'w') |
81
85dcea81f22b
SubversionRepo: close files before rmtree() in diff3
Patrick Mezard <pmezard@gmail.com>
parents:
77
diff
changeset
|
407 try: |
85dcea81f22b
SubversionRepo: close files before rmtree() in diff3
Patrick Mezard <pmezard@gmail.com>
parents:
77
diff
changeset
|
408 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
|
409 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
|
410 self.client_context, self.pool) |
89
edeec6829d80
SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents:
87
diff
changeset
|
411 except core.SubversionException, e: |
edeec6829d80
SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents:
87
diff
changeset
|
412 # "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
|
413 # This error happens systematically under Windows, possibly |
edeec6829d80
SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents:
87
diff
changeset
|
414 # 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
|
415 if e.apr_err != 720006: |
edeec6829d80
SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents:
87
diff
changeset
|
416 raise |
edeec6829d80
SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents:
87
diff
changeset
|
417 self.hasdiff3 = False |
edeec6829d80
SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents:
87
diff
changeset
|
418 raise SubversionRepoCanNotDiff() |
edeec6829d80
SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents:
87
diff
changeset
|
419 out.close() |
edeec6829d80
SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents:
87
diff
changeset
|
420 err.close() |
edeec6829d80
SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents:
87
diff
changeset
|
421 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
|
422 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
|
423 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
|
424 return diff |
a31968146f3c
svnwrap: Fix leakage of temp dirs by using try/finally blocks.
Augie Fackler <durin42@gmail.com>
parents:
63
diff
changeset
|
425 finally: |
89
edeec6829d80
SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents:
87
diff
changeset
|
426 if out: out.close() |
edeec6829d80
SubversionRepo: remember svn.diff3() does not work
Patrick Mezard <pmezard@gmail.com>
parents:
87
diff
changeset
|
427 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
|
428 shutil.rmtree(tmpdir) |
81
85dcea81f22b
SubversionRepo: close files before rmtree() in diff3
Patrick Mezard <pmezard@gmail.com>
parents:
77
diff
changeset
|
429 os.chdir(old_cwd) |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
430 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
431 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
|
432 """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
|
433 |
6c62bd201785
SubversionRepo: make get_file() return the file mode
Patrick Mezard <pmezard@gmail.com>
parents:
75
diff
changeset
|
434 Content is raw svn content, symlinks content is still prefixed |
6c62bd201785
SubversionRepo: make get_file() return the file mode
Patrick Mezard <pmezard@gmail.com>
parents:
75
diff
changeset
|
435 by 'link '. Mode is 'x' if file is executable, 'l' if a symlink, |
6c62bd201785
SubversionRepo: make get_file() return the file mode
Patrick Mezard <pmezard@gmail.com>
parents:
75
diff
changeset
|
436 the empty string otherwise. If the file does not exist at this |
6c62bd201785
SubversionRepo: make get_file() return the file mode
Patrick Mezard <pmezard@gmail.com>
parents:
75
diff
changeset
|
437 revision, raise IOError. |
6c62bd201785
SubversionRepo: make get_file() return the file mode
Patrick Mezard <pmezard@gmail.com>
parents:
75
diff
changeset
|
438 """ |
6c62bd201785
SubversionRepo: make get_file() return the file mode
Patrick Mezard <pmezard@gmail.com>
parents:
75
diff
changeset
|
439 mode = '' |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
440 out = cStringIO.StringIO() |
66
a31968146f3c
svnwrap: Fix leakage of temp dirs by using try/finally blocks.
Augie Fackler <durin42@gmail.com>
parents:
63
diff
changeset
|
441 try: |
76
6c62bd201785
SubversionRepo: make get_file() return the file mode
Patrick Mezard <pmezard@gmail.com>
parents:
75
diff
changeset
|
442 info = ra.get_file(self.ra, path, revision, out) |
6c62bd201785
SubversionRepo: make get_file() return the file mode
Patrick Mezard <pmezard@gmail.com>
parents:
75
diff
changeset
|
443 if isinstance(info, list): |
6c62bd201785
SubversionRepo: make get_file() return the file mode
Patrick Mezard <pmezard@gmail.com>
parents:
75
diff
changeset
|
444 info = info[-1] |
6c62bd201785
SubversionRepo: make get_file() return the file mode
Patrick Mezard <pmezard@gmail.com>
parents:
75
diff
changeset
|
445 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
|
446 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
|
447 except core.SubversionException, e: |
450d5d9d3b80
SubversionRepo: do not use temporary file in get_file()
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
448 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
|
449 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
|
450 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
|
451 raise IOError() |
450d5d9d3b80
SubversionRepo: do not use temporary file in get_file()
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
452 raise |
450d5d9d3b80
SubversionRepo: do not use temporary file in get_file()
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
453 data = out.getvalue() |
76
6c62bd201785
SubversionRepo: make get_file() return the file mode
Patrick Mezard <pmezard@gmail.com>
parents:
75
diff
changeset
|
454 return data, mode |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
455 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
456 def proplist(self, path, revision, recurse=False): |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
457 if path[-1] == '/': |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
458 path = path[:-1] |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
459 if path[0] == '/': |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
460 path = path[1:] |
75
cca31b6b1318
SubversionRepo: add optrev() to help generate client API revisions
Patrick Mezard <pmezard@gmail.com>
parents:
74
diff
changeset
|
461 rev = optrev(revision) |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
462 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
|
463 self.client_context, self.pool)) |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
464 pl2 = {} |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
465 for key, value in pl.iteritems(): |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
466 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
|
467 return pl2 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
468 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
469 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
|
470 rev = optrev(revision) |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
471 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
|
472 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
|
473 self.client_context, self.pool) |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
474 |
77
ed3dd5bf45da
fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents:
76
diff
changeset
|
475 def list_files(self, dirpath, revision): |
ed3dd5bf45da
fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents:
76
diff
changeset
|
476 """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
|
477 |
ed3dd5bf45da
fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents:
76
diff
changeset
|
478 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
|
479 '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
|
480 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
|
481 revision. |
ed3dd5bf45da
fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents:
76
diff
changeset
|
482 """ |
ed3dd5bf45da
fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents:
76
diff
changeset
|
483 dirpath = dirpath.strip('/') |
ed3dd5bf45da
fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents:
76
diff
changeset
|
484 pool = core.Pool() |
ed3dd5bf45da
fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents:
76
diff
changeset
|
485 rpath = '/'.join([self.svn_url, dirpath]).strip('/') |
ed3dd5bf45da
fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents:
76
diff
changeset
|
486 rev = optrev(revision) |
ed3dd5bf45da
fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents:
76
diff
changeset
|
487 try: |
ed3dd5bf45da
fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents:
76
diff
changeset
|
488 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
|
489 except core.SubversionException, e: |
ed3dd5bf45da
fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents:
76
diff
changeset
|
490 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
|
491 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
|
492 raise |
ed3dd5bf45da
fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents:
76
diff
changeset
|
493 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
|
494 kind = _svntypes.get(e.kind) |
77
ed3dd5bf45da
fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents:
76
diff
changeset
|
495 yield path, kind |
ed3dd5bf45da
fetch_command: bypass export3() and checkout manually
Patrick Mezard <pmezard@gmail.com>
parents:
76
diff
changeset
|
496 |
87
b033d74be76b
fetch_command: in stupid non-diffy mode, take changed paths in account
Patrick Mezard <pmezard@gmail.com>
parents:
83
diff
changeset
|
497 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
|
498 """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
|
499 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
|
500 """ |
b033d74be76b
fetch_command: in stupid non-diffy mode, take changed paths in account
Patrick Mezard <pmezard@gmail.com>
parents:
83
diff
changeset
|
501 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
|
502 return _svntypes.get(kind) |