Show More
@@ -0,0 +1,72 b'' | |||
|
1 | #!/bin/sh | |
|
2 | ||
|
3 | "$TESTDIR/hghave" svn || exit 80 | |
|
4 | ||
|
5 | escapedwd=$(pwd | \ | |
|
6 | python -c \ | |
|
7 | "import sys,urllib; print urllib.pathname2url(sys.stdin.read().strip())" | |
|
8 | ) | |
|
9 | filterpath="sed s+$escapedwd+/root+" | |
|
10 | ||
|
11 | echo % create subversion repo | |
|
12 | ||
|
13 | SVNREPO="file://$escapedwd/svn-repo" | |
|
14 | WCROOT="$(pwd)/svn-wc" | |
|
15 | svnadmin create svn-repo | |
|
16 | svn co $SVNREPO svn-wc | |
|
17 | cd svn-wc | |
|
18 | echo alpha > alpha | |
|
19 | svn add alpha | |
|
20 | svn ci -m 'Add alpha' | |
|
21 | cd .. | |
|
22 | ||
|
23 | echo % create hg repo | |
|
24 | ||
|
25 | rm -rf sub | |
|
26 | mkdir sub | |
|
27 | cd sub | |
|
28 | hg init t | |
|
29 | cd t | |
|
30 | ||
|
31 | echo % first revision, no sub | |
|
32 | echo a > a | |
|
33 | hg ci -Am0 | |
|
34 | ||
|
35 | echo % add first svn sub | |
|
36 | echo "s = [svn]$SVNREPO" >> .hgsub | |
|
37 | svn co --quiet $SVNREPO s | |
|
38 | hg add .hgsub | |
|
39 | hg ci -m1 | |
|
40 | echo % debugsub | |
|
41 | hg debugsub | $filterpath | |
|
42 | ||
|
43 | echo | |
|
44 | echo % change file in svn and hg, commit | |
|
45 | echo a >> a | |
|
46 | echo alpha >> s/alpha | |
|
47 | hg commit -m 'Message!' | |
|
48 | hg debugsub | $filterpath | |
|
49 | ||
|
50 | echo | |
|
51 | echo a > s/a | |
|
52 | echo % should be empty despite change to s/a | |
|
53 | hg st | |
|
54 | ||
|
55 | echo | |
|
56 | echo % add a commit from svn | |
|
57 | pushd "$WCROOT" > /dev/null | |
|
58 | svn up | |
|
59 | echo xyz >> alpha | |
|
60 | svn ci -m 'amend a from svn' | |
|
61 | popd > /dev/null | |
|
62 | echo % this commit from hg will fail | |
|
63 | echo zzz >> s/alpha | |
|
64 | hg ci -m 'amend alpha from hg' | |
|
65 | ||
|
66 | echo | |
|
67 | echo % clone | |
|
68 | cd .. | |
|
69 | hg clone t tc | |
|
70 | cd tc | |
|
71 | echo % debugsub in clone | |
|
72 | hg debugsub | $filterpath |
@@ -0,0 +1,48 b'' | |||
|
1 | % create subversion repo | |
|
2 | Checked out revision 0. | |
|
3 | A alpha | |
|
4 | Adding alpha | |
|
5 | Transmitting file data . | |
|
6 | Committed revision 1. | |
|
7 | % create hg repo | |
|
8 | % first revision, no sub | |
|
9 | adding a | |
|
10 | % add first svn sub | |
|
11 | committing subrepository s | |
|
12 | % debugsub | |
|
13 | path s | |
|
14 | source file:///root/svn-repo | |
|
15 | revision 1 | |
|
16 | ||
|
17 | % change file in svn and hg, commit | |
|
18 | committing subrepository s | |
|
19 | Sending s/alpha | |
|
20 | Transmitting file data . | |
|
21 | Committed revision 2. | |
|
22 | At revision 2. | |
|
23 | path s | |
|
24 | source file:///root/svn-repo | |
|
25 | revision 2 | |
|
26 | ||
|
27 | % should be empty despite change to s/a | |
|
28 | ||
|
29 | % add a commit from svn | |
|
30 | U alpha | |
|
31 | Updated to revision 2. | |
|
32 | Sending alpha | |
|
33 | Transmitting file data . | |
|
34 | Committed revision 3. | |
|
35 | % this commit from hg will fail | |
|
36 | committing subrepository s | |
|
37 | abort: svn: Commit failed (details follow): | |
|
38 | svn: File '/alpha' is out of date | |
|
39 | ||
|
40 | % clone | |
|
41 | updating to branch default | |
|
42 | A s/alpha | |
|
43 | Checked out revision 2. | |
|
44 | 3 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
45 | % debugsub in clone | |
|
46 | path s | |
|
47 | source file:///root/svn-repo | |
|
48 | revision 2 |
@@ -5,7 +5,7 b'' | |||
|
5 | 5 | # This software may be used and distributed according to the terms of the |
|
6 | 6 | # GNU General Public License version 2, incorporated herein by reference. |
|
7 | 7 | |
|
8 | import errno, os | |
|
8 | import errno, os, re | |
|
9 | 9 | from i18n import _ |
|
10 | 10 | import config, util, node, error |
|
11 | 11 | hg = None |
@@ -250,6 +250,88 b' class hgsubrepo(object):' | |||
|
250 | 250 | other = hg.repository(self._repo.ui, dsturl) |
|
251 | 251 | self._repo.push(other, force) |
|
252 | 252 | |
|
253 | class svnsubrepo(object): | |
|
254 | def __init__(self, ctx, path, state): | |
|
255 | self._path = path | |
|
256 | self._state = state | |
|
257 | self._ctx = ctx | |
|
258 | self._ui = ctx._repo.ui | |
|
259 | ||
|
260 | def _svncommand(self, commands): | |
|
261 | cmd = ['svn'] + commands + [self._path] | |
|
262 | cmd = [util.shellquote(arg) for arg in cmd] | |
|
263 | cmd = util.quotecommand(' '.join(cmd)) | |
|
264 | write, read, err = util.popen3(cmd) | |
|
265 | retdata = read.read() | |
|
266 | err = err.read().strip() | |
|
267 | if err: | |
|
268 | raise util.Abort(err) | |
|
269 | return retdata | |
|
270 | ||
|
271 | def _wcrev(self): | |
|
272 | info = self._svncommand(['info']) | |
|
273 | mat = re.search('Revision: ([\d]+)\n', info) | |
|
274 | if not mat: | |
|
275 | return 0 | |
|
276 | return mat.groups()[0] | |
|
277 | ||
|
278 | def _url(self): | |
|
279 | info = self._svncommand(['info']) | |
|
280 | mat = re.search('URL: ([^\n]+)\n', info) | |
|
281 | if not mat: | |
|
282 | return 0 | |
|
283 | return mat.groups()[0] | |
|
284 | ||
|
285 | def _wcclean(self): | |
|
286 | status = self._svncommand(['status']) | |
|
287 | status = '\n'.join([s for s in status.splitlines() if s[0] != '?']) | |
|
288 | if status.strip(): | |
|
289 | return False | |
|
290 | return True | |
|
291 | ||
|
292 | def dirty(self): | |
|
293 | if self._wcrev() == self._state[1] and self._wcclean(): | |
|
294 | return False | |
|
295 | return True | |
|
296 | ||
|
297 | def commit(self, text, user, date): | |
|
298 | # user and date are out of our hands since svn is centralized | |
|
299 | if self._wcclean(): | |
|
300 | return self._wcrev() | |
|
301 | commitinfo = self._svncommand(['commit', '-m', text]) | |
|
302 | self._ui.status(commitinfo) | |
|
303 | newrev = re.search('Committed revision ([\d]+).', commitinfo) | |
|
304 | if not newrev: | |
|
305 | raise util.Abort(commitinfo.splitlines()[-1]) | |
|
306 | newrev = newrev.groups()[0] | |
|
307 | self._ui.status(self._svncommand(['update', '-r', newrev])) | |
|
308 | return newrev | |
|
309 | ||
|
310 | def remove(self): | |
|
311 | if self.dirty(): | |
|
312 | self._repo.ui.warn('Not removing repo %s because' | |
|
313 | 'it has changes.\n' % self._path) | |
|
314 | return | |
|
315 | self._repo.ui.note('removing subrepo %s\n' % self._path) | |
|
316 | shutil.rmtree(self._ctx.repo.join(self._path)) | |
|
317 | ||
|
318 | def get(self, state): | |
|
319 | status = self._svncommand(['checkout', state[0], '--revision', state[1]]) | |
|
320 | if not re.search('Checked out revision [\d]+.', status): | |
|
321 | raise util.Abort(status.splitlines()[-1]) | |
|
322 | self._ui.status(status) | |
|
323 | ||
|
324 | def merge(self, state): | |
|
325 | old = int(self._state[1]) | |
|
326 | new = int(state[1]) | |
|
327 | if new > old: | |
|
328 | self.get(state) | |
|
329 | ||
|
330 | def push(self, force): | |
|
331 | # nothing for svn | |
|
332 | pass | |
|
333 | ||
|
253 | 334 | types = { |
|
254 | 335 | 'hg': hgsubrepo, |
|
336 | 'svn': svnsubrepo, | |
|
255 | 337 | } |
General Comments 0
You need to be logged in to leave comments.
Login now