comparison mercurial/subrepo.py @ 10178:cd477be6f2fc

subrepo: Subversion support
author Augie Fackler <durin42@gmail.com>
date Thu, 31 Dec 2009 13:16:03 -0600
parents 5ca0d220ae21
children 572dd10fa308
comparison
equal deleted inserted replaced
10177:5ca0d220ae21 10178:cd477be6f2fc
3 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com> 3 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
4 # 4 #
5 # This software may be used and distributed according to the terms of the 5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2, incorporated herein by reference. 6 # GNU General Public License version 2, incorporated herein by reference.
7 7
8 import errno, os 8 import errno, os, re
9 from i18n import _ 9 from i18n import _
10 import config, util, node, error 10 import config, util, node, error
11 hg = None 11 hg = None
12 12
13 nullstate = ('', '', 'empty') 13 nullstate = ('', '', 'empty')
248 self._repo.ui.status(_('pushing subrepo %s\n') % self._path) 248 self._repo.ui.status(_('pushing subrepo %s\n') % self._path)
249 dsturl = _abssource(self._repo, True) 249 dsturl = _abssource(self._repo, True)
250 other = hg.repository(self._repo.ui, dsturl) 250 other = hg.repository(self._repo.ui, dsturl)
251 self._repo.push(other, force) 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 types = { 334 types = {
254 'hg': hgsubrepo, 335 'hg': hgsubrepo,
336 'svn': svnsubrepo,
255 } 337 }