|
61 | 61 | from diffuse.vcs.hg import Hg |
62 | 62 | from diffuse.vcs.mtn import Mtn |
63 | 63 | from diffuse.vcs.rcs import Rcs |
| 64 | +from diffuse.vcs.svn import Svn |
64 | 65 |
|
65 | 66 | if not hasattr(__builtins__, 'WindowsError'): |
66 | 67 | # define 'WindowsError' so 'except' statements will work on all platforms |
|
70 | 71 | # this is sorted based upon frequency to speed up code for stripping whitespace |
71 | 72 | whitespace = ' \t\n\r\x0b\x0c' |
72 | 73 |
|
73 | | -# escape special glob characters |
74 | | -def globEscape(s): |
75 | | - m = dict([ (c, f'[{c}]') for c in '[]?*' ]) |
76 | | - return ''.join([ m.get(c, c) for c in s ]) |
77 | | - |
78 | 74 | # colour resources |
79 | 75 | class Colour: |
80 | 76 | def __init__(self, r, g, b, a=1.0): |
@@ -495,7 +491,7 @@ def parse(self, file_name): |
495 | 491 | if args[0] == 'import' and len(args) == 2: |
496 | 492 | path = os.path.expanduser(args[1]) |
497 | 493 | # relative paths are relative to the parsed file |
498 | | - path = os.path.join(globEscape(os.path.dirname(file_name)), path) |
| 494 | + path = os.path.join(utils.globEscape(os.path.dirname(file_name)), path) |
499 | 495 | paths = glob.glob(path) |
500 | 496 | if len(paths) == 0: |
501 | 497 | paths = [ path ] |
@@ -1290,242 +1286,10 @@ def _get_rcs_repo(path, prefs): |
1290 | 1286 | # the user specified an invalid folder name |
1291 | 1287 | pass |
1292 | 1288 |
|
1293 | | -# Subversion support |
1294 | | -# SVK support subclasses from this |
1295 | | -class _Svn: |
1296 | | - def __init__(self, root): |
1297 | | - self.root = root |
1298 | | - self.url = None |
1299 | | - |
1300 | | - def _getVcs(self): |
1301 | | - return 'svn' |
1302 | | - |
1303 | | - def _getURLPrefix(self): |
1304 | | - return 'URL: ' |
1305 | | - |
1306 | | - def _parseStatusLine(self, s): |
1307 | | - if len(s) < 8 or s[0] not in 'ACDMR': |
1308 | | - return |
1309 | | - # subversion 1.6 adds a new column |
1310 | | - k = 7 |
1311 | | - if k < len(s) and s[k] == ' ': |
1312 | | - k += 1 |
1313 | | - return s[0], s[k:] |
1314 | | - |
1315 | | - def _getPreviousRevision(self, rev): |
1316 | | - if rev is None: |
1317 | | - return 'BASE' |
1318 | | - m = int(rev) |
1319 | | - if m > 1: |
1320 | | - return str(m - 1) |
1321 | | - |
1322 | | - def _getURL(self, prefs): |
1323 | | - if self.url is None: |
1324 | | - vcs, prefix = self._getVcs(), self._getURLPrefix() |
1325 | | - n = len(prefix) |
1326 | | - args = [ prefs.getString(vcs + '_bin'), 'info' ] |
1327 | | - for s in utils.popenReadLines(self.root, args, prefs, vcs + '_bash'): |
1328 | | - if s.startswith(prefix): |
1329 | | - self.url = s[n:] |
1330 | | - break |
1331 | | - return self.url |
1332 | | - |
1333 | | - def getFileTemplate(self, prefs, name): |
1334 | | - # FIXME: verify this |
1335 | | - # merge conflict |
1336 | | - escaped_name = globEscape(name) |
1337 | | - left = glob.glob(escaped_name + '.merge-left.r*') |
1338 | | - right = glob.glob(escaped_name + '.merge-right.r*') |
1339 | | - if len(left) > 0 and len(right) > 0: |
1340 | | - return [ (left[-1], None), (name, None), (right[-1], None) ] |
1341 | | - # update conflict |
1342 | | - left = sorted(glob.glob(escaped_name + '.r*')) |
1343 | | - right = glob.glob(escaped_name + '.mine') |
1344 | | - right.extend(glob.glob(escaped_name + '.working')) |
1345 | | - if len(left) > 0 and len(right) > 0: |
1346 | | - return [ (left[-1], None), (name, None), (right[0], None) ] |
1347 | | - # default case |
1348 | | - return [ (name, self._getPreviousRevision(None)), (name, None) ] |
1349 | | - |
1350 | | - def _getCommitTemplate(self, prefs, rev, names): |
1351 | | - result = [] |
1352 | | - try: |
1353 | | - prev = self._getPreviousRevision(rev) |
1354 | | - except ValueError: |
1355 | | - utils.logError(_('Error parsing revision %s.') % (rev, )) |
1356 | | - return result |
1357 | | - |
1358 | | - # build command |
1359 | | - vcs = self._getVcs() |
1360 | | - vcs_bin, vcs_bash = prefs.getString(vcs + '_bin'), vcs + '_bash' |
1361 | | - if rev is None: |
1362 | | - args = [ vcs_bin, 'status', '-q' ] |
1363 | | - else: |
1364 | | - args = [ vcs_bin, 'diff', '--summarize', '-c', rev ] |
1365 | | - # build list of interesting files |
1366 | | - pwd, isabs = os.path.abspath(os.curdir), False |
1367 | | - for name in names: |
1368 | | - isabs |= os.path.isabs(name) |
1369 | | - if rev is None: |
1370 | | - args.append(utils.safeRelativePath(self.root, name, prefs, vcs + '_cygwin')) |
1371 | | - # run command |
1372 | | - fs = FolderSet(names) |
1373 | | - modified, added, removed = {}, set(), set() |
1374 | | - for s in utils.popenReadLines(self.root, args, prefs, vcs_bash): |
1375 | | - status = self._parseStatusLine(s) |
1376 | | - if status is None: |
1377 | | - continue |
1378 | | - v, k = status |
1379 | | - rel = prefs.convertToNativePath(k) |
1380 | | - k = os.path.join(self.root, rel) |
1381 | | - if fs.contains(k): |
1382 | | - if v == 'D': |
1383 | | - # deleted file or directory |
1384 | | - # the contents of deleted folders are not reported |
1385 | | - # by "svn diff --summarize -c <rev>" |
1386 | | - removed.add(rel) |
1387 | | - elif v == 'A': |
1388 | | - # new file or directory |
1389 | | - added.add(rel) |
1390 | | - elif v == 'M': |
1391 | | - # modified file or merge conflict |
1392 | | - k = os.path.join(self.root, k) |
1393 | | - if not isabs: |
1394 | | - k = utils.relpath(pwd, k) |
1395 | | - modified[k] = [ (k, prev), (k, rev) ] |
1396 | | - elif v == 'C': |
1397 | | - # merge conflict |
1398 | | - modified[k] = self.getFileTemplate(prefs, k) |
1399 | | - elif v == 'R': |
1400 | | - # replaced file |
1401 | | - removed.add(rel) |
1402 | | - added.add(rel) |
1403 | | - # look for files in the added items |
1404 | | - if rev is None: |
1405 | | - m, added = added, {} |
1406 | | - for k in m: |
1407 | | - if not os.path.isdir(k): |
1408 | | - # confirmed as added file |
1409 | | - k = os.path.join(self.root, k) |
1410 | | - if not isabs: |
1411 | | - k = utils.relpath(pwd, k) |
1412 | | - added[k] = [ (None, None), (k, None) ] |
1413 | | - else: |
1414 | | - m = {} |
1415 | | - for k in added: |
1416 | | - d, b = os.path.dirname(k), os.path.basename(k) |
1417 | | - if d not in m: |
1418 | | - m[d] = set() |
1419 | | - m[d].add(b) |
1420 | | - # remove items we can easily determine to be directories |
1421 | | - for k in m.keys(): |
1422 | | - d = os.path.dirname(k) |
1423 | | - if d in m: |
1424 | | - m[d].discard(os.path.basename(k)) |
1425 | | - if not m[d]: |
1426 | | - del m[d] |
1427 | | - # determine which are directories |
1428 | | - added = {} |
1429 | | - for p, v in m.items(): |
1430 | | - for s in utils.popenReadLines(self.root, [ vcs_bin, 'list', '-r', rev, '{}/{}'.format(self._getURL(prefs), p.replace(os.sep, '/')) ], prefs, vcs_bash): |
1431 | | - if s in v: |
1432 | | - # confirmed as added file |
1433 | | - k = os.path.join(self.root, os.path.join(p, s)) |
1434 | | - if not isabs: |
1435 | | - k = utils.relpath(pwd, k) |
1436 | | - added[k] = [ (None, None), (k, rev) ] |
1437 | | - # determine if removed items are files or directories |
1438 | | - if prev == 'BASE': |
1439 | | - m, removed = removed, {} |
1440 | | - for k in m: |
1441 | | - if not os.path.isdir(k): |
1442 | | - # confirmed item as file |
1443 | | - k = os.path.join(self.root, k) |
1444 | | - if not isabs: |
1445 | | - k = utils.relpath(pwd, k) |
1446 | | - removed[k] = [ (k, prev), (None, None) ] |
1447 | | - else: |
1448 | | - m = {} |
1449 | | - for k in removed: |
1450 | | - d, b = os.path.dirname(k), os.path.basename(k) |
1451 | | - if d not in m: |
1452 | | - m[d] = set() |
1453 | | - m[d].add(b) |
1454 | | - removed_dir, removed = set(), {} |
1455 | | - for p, v in m.items(): |
1456 | | - for s in utils.popenReadLines(self.root, [ vcs_bin, 'list', '-r', prev, '{}/{}'.format(self._getURL(prefs), p.replace(os.sep, '/')) ], prefs, vcs_bash): |
1457 | | - if s.endswith('/'): |
1458 | | - s = s[:-1] |
1459 | | - if s in v: |
1460 | | - # confirmed item as directory |
1461 | | - removed_dir.add(os.path.join(p, s)) |
1462 | | - else: |
1463 | | - if s in v: |
1464 | | - # confirmed item as file |
1465 | | - k = os.path.join(self.root, os.path.join(p, s)) |
1466 | | - if not isabs: |
1467 | | - k = utils.relpath(pwd, k) |
1468 | | - removed[k] = [ (k, prev), (None, None) ] |
1469 | | - # recursively find all unreported removed files |
1470 | | - while removed_dir: |
1471 | | - tmp = removed_dir |
1472 | | - removed_dir = set() |
1473 | | - for p in tmp: |
1474 | | - for s in utils.popenReadLines(self.root, [ vcs_bin, 'list', '-r', prev, '{}/{}'.format(self._getURL(prefs), p.replace(os.sep, '/')) ], prefs, vcs_bash): |
1475 | | - if s.endswith('/'): |
1476 | | - # confirmed item as directory |
1477 | | - removed_dir.add(os.path.join(p, s[:-1])) |
1478 | | - else: |
1479 | | - # confirmed item as file |
1480 | | - k = os.path.join(self.root, os.path.join(p, s)) |
1481 | | - if not isabs: |
1482 | | - k = utils.relpath(pwd, k) |
1483 | | - removed[k] = [ (k, prev), (None, None) ] |
1484 | | - # sort the results |
1485 | | - r = set() |
1486 | | - for m in removed, added, modified: |
1487 | | - r.update(m.keys()) |
1488 | | - for k in sorted(r): |
1489 | | - for m in removed, added, modified: |
1490 | | - if k in m: |
1491 | | - result.append(m[k]) |
1492 | | - return result |
1493 | | - |
1494 | | - def getCommitTemplate(self, prefs, rev, names): |
1495 | | - return self._getCommitTemplate(prefs, rev, names) |
1496 | | - |
1497 | | - def getFolderTemplate(self, prefs, names): |
1498 | | - return self._getCommitTemplate(prefs, None, names) |
1499 | | - |
1500 | | - def getRevision(self, prefs, name, rev): |
1501 | | - vcs_bin = prefs.getString('svn_bin') |
1502 | | - if rev in [ 'BASE', 'COMMITTED', 'PREV' ]: |
1503 | | - return utils.popenRead( |
1504 | | - self.root, |
1505 | | - [ |
1506 | | - vcs_bin, |
1507 | | - 'cat', |
1508 | | - '{}@{}'.format(utils.safeRelativePath(self.root, name, prefs, 'svn_cygwin'), rev) |
1509 | | - ], |
1510 | | - prefs, |
1511 | | - 'svn_bash') |
1512 | | - return utils.popenRead( |
1513 | | - self.root, |
1514 | | - [ |
1515 | | - vcs_bin, |
1516 | | - 'cat', |
1517 | | - '{}/{}@{}'.format( |
1518 | | - self._getURL(prefs), |
1519 | | - utils.relpath(self.root, os.path.abspath(name)).replace(os.sep, '/'), |
1520 | | - rev) |
1521 | | - ], |
1522 | | - prefs, |
1523 | | - 'svn_bash') |
1524 | | - |
1525 | 1289 | def _get_svn_repo(path, prefs): |
1526 | 1290 | p = _find_parent_dir_with(path, '.svn') |
1527 | 1291 | if p: |
1528 | | - return _Svn(p) |
| 1292 | + return Svn(p) |
1529 | 1293 |
|
1530 | 1294 | class _Svk(_Svn): |
1531 | 1295 | def __init__(self, root): |
|
0 commit comments