eric6/Plugins/VcsPlugins/vcsPySvn/subversion.py

changeset 7774
9eed155411f0
parent 7759
51aa6c6b66f7
child 7775
4a1db75550bd
equal deleted inserted replaced
7773:fe42bd17d4fe 7774:9eed155411f0
12 import shutil 12 import shutil
13 import time 13 import time
14 from urllib.parse import quote 14 from urllib.parse import quote
15 15
16 from PyQt5.QtCore import ( 16 from PyQt5.QtCore import (
17 Qt, QMutexLocker, pyqtSignal, QRegExp, QDateTime, QCoreApplication 17 pyqtSignal, Qt, QRegExp, QDateTime, QCoreApplication
18 ) 18 )
19 from PyQt5.QtWidgets import QLineEdit, QDialog, QInputDialog, QApplication 19 from PyQt5.QtWidgets import QLineEdit, QDialog, QInputDialog, QApplication
20 20
21 from E5Gui.E5Application import e5App 21 from E5Gui.E5Application import e5App
22 from E5Gui import E5MessageBox 22 from E5Gui import E5MessageBox
23
24 from E5Utilities.E5MutexLocker import E5MutexLocker
23 25
24 from VCS.VersionControl import VersionControl 26 from VCS.VersionControl import VersionControl
25 27
26 import pysvn 28 import pysvn
27 29
299 except OSError: 301 except OSError:
300 if os.path.isdir(tmpDir): 302 if os.path.isdir(tmpDir):
301 shutil.rmtree(tmpDir, True) 303 shutil.rmtree(tmpDir, True)
302 return False, False 304 return False, False
303 305
304 locker = QMutexLocker(self.vcsExecutionMutex)
305 cwd = os.getcwd() 306 cwd = os.getcwd()
306 os.chdir(os.path.join(tmpDir, project)) 307 os.chdir(os.path.join(tmpDir, project))
307 opts = self.options['global'] 308 opts = self.options['global']
308 recurse = "--non-recursive" not in opts 309 recurse = "--non-recursive" not in opts
309 url = self.__svnURL(vcsDir) 310 url = self.__svnURL(vcsDir)
314 "import{0} --message {1} .".format( 315 "import{0} --message {1} .".format(
315 (not recurse) and " --non-recursive" or "", msg), 316 (not recurse) and " --non-recursive" or "", msg),
316 client) 317 client)
317 QApplication.processEvents() 318 QApplication.processEvents()
318 try: 319 try:
319 rev = client.import_(".", url, msg, recurse, ignore=True) 320 with E5MutexLocker(self.vcsExecutionMutex):
321 rev = client.import_(".", url, msg, recurse, ignore=True)
320 status = True 322 status = True
321 except pysvn.ClientError as e: 323 except pysvn.ClientError as e:
322 status = False 324 status = False
323 rev = None 325 rev = None
324 if not noDialog: 326 if not noDialog:
325 dlg.showError(e.args[0]) 327 dlg.showError(e.args[0])
326 locker.unlock()
327 if not noDialog: 328 if not noDialog:
328 rev and dlg.showMessage(self.tr("Imported revision {0}.\n") 329 rev and dlg.showMessage(self.tr("Imported revision {0}.\n")
329 .format(rev.number)) 330 .format(rev.number))
330 dlg.finish() 331 dlg.finish()
331 dlg.exec() 332 dlg.exec()
389 "checkout{0} {1} {2}".format( 390 "checkout{0} {1} {2}".format(
390 (not recurse) and " --non-recursive" or "", 391 (not recurse) and " --non-recursive" or "",
391 url, projectDir), 392 url, projectDir),
392 client) 393 client)
393 QApplication.processEvents() 394 QApplication.processEvents()
394 locker = QMutexLocker(self.vcsExecutionMutex)
395 try: 395 try:
396 client.checkout(url, projectDir, recurse) 396 with E5MutexLocker(self.vcsExecutionMutex):
397 client.checkout(url, projectDir, recurse)
397 status = True 398 status = True
398 except pysvn.ClientError as e: 399 except pysvn.ClientError as e:
399 status = False 400 status = False
400 if not noDialog: 401 if not noDialog:
401 dlg.showError(e.args[0]) 402 dlg.showError(e.args[0])
402 locker.unlock()
403 if not noDialog: 403 if not noDialog:
404 dlg.finish() 404 dlg.finish()
405 dlg.exec() 405 dlg.exec()
406 return status 406 return status
407 407
455 "export --force{0} {1} {2}".format( 455 "export --force{0} {1} {2}".format(
456 (not recurse) and " --non-recursive" or "", 456 (not recurse) and " --non-recursive" or "",
457 url, projectDir), 457 url, projectDir),
458 client) 458 client)
459 QApplication.processEvents() 459 QApplication.processEvents()
460 locker = QMutexLocker(self.vcsExecutionMutex)
461 try: 460 try:
462 client.export(url, projectDir, force=True, recurse=recurse) 461 with E5MutexLocker(self.vcsExecutionMutex):
462 client.export(url, projectDir, force=True, recurse=recurse)
463 status = True 463 status = True
464 except pysvn.ClientError as e: 464 except pysvn.ClientError as e:
465 status = False 465 status = False
466 dlg.showError(e.args[0]) 466 dlg.showError(e.args[0])
467 locker.unlock()
468 dlg.finish() 467 dlg.finish()
469 dlg.exec() 468 dlg.exec()
470 return status 469 return status
471 470
472 def vcsCommit(self, name, message, noDialog=False): 471 def vcsCommit(self, name, message, noDialog=False):
565 self.svnGetReposName(dname).startswith('http') or 564 self.svnGetReposName(dname).startswith('http') or
566 self.svnGetReposName(dname).startswith('svn') 565 self.svnGetReposName(dname).startswith('svn')
567 ): 566 ):
568 noDialog = False 567 noDialog = False
569 568
570 locker = QMutexLocker(self.vcsExecutionMutex)
571 cwd = os.getcwd() 569 cwd = os.getcwd()
572 os.chdir(dname) 570 os.chdir(dname)
573 opts = self.options['global'] + self.options['commit'] 571 opts = self.options['global'] + self.options['commit']
574 recurse = "--non-recursive" not in opts 572 recurse = "--non-recursive" not in opts
575 keeplocks = "--keep-locks" in opts 573 keeplocks = "--keep-locks" in opts
585 " --changelist ".join([""] + changelists) or "", 583 " --changelist ".join([""] + changelists) or "",
586 msg, " ".join(fnames)), 584 msg, " ".join(fnames)),
587 client) 585 client)
588 QApplication.processEvents() 586 QApplication.processEvents()
589 try: 587 try:
590 if changelists: 588 with E5MutexLocker(self.vcsExecutionMutex):
591 rev = client.checkin(fnames, msg, 589 if changelists:
592 recurse=recurse, keep_locks=keeplocks, 590 rev = client.checkin(fnames, msg,
593 keep_changelist=keepChangelists, 591 recurse=recurse, keep_locks=keeplocks,
594 changelists=changelists) 592 keep_changelist=keepChangelists,
595 else: 593 changelists=changelists)
596 rev = client.checkin(fnames, msg, 594 else:
597 recurse=recurse, keep_locks=keeplocks) 595 rev = client.checkin(fnames, msg,
596 recurse=recurse, keep_locks=keeplocks)
598 except pysvn.ClientError as e: 597 except pysvn.ClientError as e:
599 rev = None 598 rev = None
600 if not noDialog: 599 if not noDialog:
601 dlg.showError(e.args[0]) 600 dlg.showError(e.args[0])
602 locker.unlock()
603 if not noDialog: 601 if not noDialog:
604 rev and dlg.showMessage(self.tr("Committed revision {0}.") 602 rev and dlg.showMessage(self.tr("Committed revision {0}.")
605 .format(rev.number)) 603 .format(rev.number))
606 dlg.finish() 604 dlg.finish()
607 dlg.exec() 605 dlg.exec()
624 dname, fnames = self.splitPathList(name) 622 dname, fnames = self.splitPathList(name)
625 else: 623 else:
626 dname, fname = self.splitPath(name) 624 dname, fname = self.splitPath(name)
627 fnames = [fname] 625 fnames = [fname]
628 626
629 locker = QMutexLocker(self.vcsExecutionMutex)
630 cwd = os.getcwd() 627 cwd = os.getcwd()
631 os.chdir(dname) 628 os.chdir(dname)
632 opts = self.options['global'] + self.options['update'] 629 opts = self.options['global'] + self.options['update']
633 recurse = "--non-recursive" not in opts 630 recurse = "--non-recursive" not in opts
634 client = self.getClient() 631 client = self.getClient()
639 (not recurse) and " --non-recursive" or "", 636 (not recurse) and " --non-recursive" or "",
640 " ".join(fnames)), 637 " ".join(fnames)),
641 client) 638 client)
642 QApplication.processEvents() 639 QApplication.processEvents()
643 try: 640 try:
644 client.update(fnames, recurse) 641 with E5MutexLocker(self.vcsExecutionMutex):
642 client.update(fnames, recurse)
645 except pysvn.ClientError as e: 643 except pysvn.ClientError as e:
646 dlg.showError(e.args[0]) 644 dlg.showError(e.args[0])
647 locker.unlock()
648 if not noDialog: 645 if not noDialog:
649 dlg.finish() 646 dlg.finish()
650 dlg.exec() 647 dlg.exec()
651 res = dlg.hasAddOrDelete() 648 res = dlg.hasAddOrDelete()
652 else: 649 else:
733 names.extend(tree2) 730 names.extend(tree2)
734 names.extend(name) 731 names.extend(name)
735 else: 732 else:
736 names.append(name) 733 names.append(name)
737 734
738 locker = QMutexLocker(self.vcsExecutionMutex)
739 cwd = os.getcwd() 735 cwd = os.getcwd()
740 os.chdir(wdir) 736 os.chdir(wdir)
741 opts = self.options['global'] + self.options['add'] 737 opts = self.options['global'] + self.options['add']
742 recurse = False 738 recurse = False
743 force = "--force" in opts or noDialog 739 force = "--force" in opts or noDialog
752 noignore and " --no-ignore" or "", 748 noignore and " --no-ignore" or "",
753 " ".join(names)), 749 " ".join(names)),
754 client) 750 client)
755 QApplication.processEvents() 751 QApplication.processEvents()
756 try: 752 try:
757 client.add(names, recurse=recurse, force=force, 753 with E5MutexLocker(self.vcsExecutionMutex):
758 ignore=not noignore) 754 client.add(names, recurse=recurse, force=force,
755 ignore=not noignore)
759 except pysvn.ClientError as e: 756 except pysvn.ClientError as e:
760 if not noDialog: 757 if not noDialog:
761 dlg.showError(e.args[0]) 758 dlg.showError(e.args[0])
762 locker.unlock()
763 if not noDialog: 759 if not noDialog:
764 dlg.finish() 760 dlg.finish()
765 dlg.exec() 761 dlg.exec()
766 os.chdir(cwd) 762 os.chdir(cwd)
767 763
844 if isinstance(path, list): 840 if isinstance(path, list):
845 names.extend(path) 841 names.extend(path)
846 else: 842 else:
847 names.append(path) 843 names.append(path)
848 844
849 locker = QMutexLocker(self.vcsExecutionMutex)
850 cwd = os.getcwd() 845 cwd = os.getcwd()
851 os.chdir(dname) 846 os.chdir(dname)
852 opts = self.options['global'] + self.options['add'] 847 opts = self.options['global'] + self.options['add']
853 recurse = True 848 recurse = True
854 force = "--force" in opts 849 force = "--force" in opts
861 ignore and " --ignore" or "", 856 ignore and " --ignore" or "",
862 " ".join(names)), 857 " ".join(names)),
863 client) 858 client)
864 QApplication.processEvents() 859 QApplication.processEvents()
865 try: 860 try:
866 client.add(names, recurse=recurse, force=force, ignore=ignore) 861 with E5MutexLocker(self.vcsExecutionMutex):
862 client.add(names, recurse=recurse, force=force, ignore=ignore)
867 except pysvn.ClientError as e: 863 except pysvn.ClientError as e:
868 dlg.showError(e.args[0]) 864 dlg.showError(e.args[0])
869 locker.unlock()
870 dlg.finish() 865 dlg.finish()
871 dlg.exec() 866 dlg.exec()
872 os.chdir(cwd) 867 os.chdir(cwd)
873 868
874 def vcsRemove(self, name, project=False, noDialog=False): 869 def vcsRemove(self, name, project=False, noDialog=False):
897 "remove{0} {1}".format( 892 "remove{0} {1}".format(
898 force and " --force" or "", 893 force and " --force" or "",
899 " ".join(name)), 894 " ".join(name)),
900 client) 895 client)
901 QApplication.processEvents() 896 QApplication.processEvents()
902 locker = QMutexLocker(self.vcsExecutionMutex)
903 try: 897 try:
904 client.remove(name, force=force) 898 with E5MutexLocker(self.vcsExecutionMutex):
899 client.remove(name, force=force)
905 res = True 900 res = True
906 except pysvn.ClientError as e: 901 except pysvn.ClientError as e:
907 res = False 902 res = False
908 if not noDialog: 903 if not noDialog:
909 dlg.showError(e.args[0]) 904 dlg.showError(e.args[0])
910 locker.unlock()
911 if not noDialog: 905 if not noDialog:
912 dlg.finish() 906 dlg.finish()
913 dlg.exec() 907 dlg.exec()
914 908
915 return res 909 return res
962 force and " --force" or "", 956 force and " --force" or "",
963 log and (" --message {0}".format(log)) or "", 957 log and (" --message {0}".format(log)) or "",
964 name, target), 958 name, target),
965 client, log=log) 959 client, log=log)
966 QApplication.processEvents() 960 QApplication.processEvents()
967 locker = QMutexLocker(self.vcsExecutionMutex)
968 try: 961 try:
969 client.move(name, target, force=force) 962 with E5MutexLocker(self.vcsExecutionMutex):
963 client.move(name, target, force=force)
970 res = True 964 res = True
971 except pysvn.ClientError as e: 965 except pysvn.ClientError as e:
972 res = False 966 res = False
973 if not noDialog: 967 if not noDialog:
974 dlg.showError(e.args[0]) 968 dlg.showError(e.args[0])
975 locker.unlock()
976 if not noDialog: 969 if not noDialog:
977 dlg.finish() 970 dlg.finish()
978 dlg.exec() 971 dlg.exec()
979 if res and not rx_prot.exactMatch(target): 972 if res and not rx_prot.exactMatch(target):
980 if target.startswith(project.getProjectPath()): 973 if target.startswith(project.getProjectPath()):
1102 self.tr('Tagging {0} in the Subversion repository') 1095 self.tr('Tagging {0} in the Subversion repository')
1103 .format(name), 1096 .format(name),
1104 "copy --message {0} {1} {2}".format(log, reposURL, url), 1097 "copy --message {0} {1} {2}".format(log, reposURL, url),
1105 client, log=log) 1098 client, log=log)
1106 QApplication.processEvents() 1099 QApplication.processEvents()
1107 locker = QMutexLocker(self.vcsExecutionMutex)
1108 try: 1100 try:
1109 rev = client.copy(reposURL, url) 1101 with E5MutexLocker(self.vcsExecutionMutex):
1102 rev = client.copy(reposURL, url)
1110 except pysvn.ClientError as e: 1103 except pysvn.ClientError as e:
1111 dlg.showError(e.args[0]) 1104 dlg.showError(e.args[0])
1112 locker.unlock()
1113 else: 1105 else:
1114 log = 'Deleted tag <{0}>'.format(self.tagName) 1106 log = 'Deleted tag <{0}>'.format(self.tagName)
1115 dlg = SvnDialog( 1107 dlg = SvnDialog(
1116 self.tr('Tagging {0} in the Subversion repository') 1108 self.tr('Tagging {0} in the Subversion repository')
1117 .format(name), 1109 .format(name),
1118 "remove --message {0} {1}".format(log, url), 1110 "remove --message {0} {1}".format(log, url),
1119 client, log=log) 1111 client, log=log)
1120 QApplication.processEvents() 1112 QApplication.processEvents()
1121 locker = QMutexLocker(self.vcsExecutionMutex)
1122 try: 1113 try:
1123 rev = client.remove(url) 1114 with E5MutexLocker(self.vcsExecutionMutex):
1115 rev = client.remove(url)
1124 except pysvn.ClientError as e: 1116 except pysvn.ClientError as e:
1125 dlg.showError(e.args[0]) 1117 dlg.showError(e.args[0])
1126 locker.unlock()
1127 rev and dlg.showMessage( 1118 rev and dlg.showMessage(
1128 self.tr("Revision {0}.\n").format(rev.number)) 1119 self.tr("Revision {0}.\n").format(rev.number))
1129 dlg.finish() 1120 dlg.finish()
1130 dlg.exec() 1121 dlg.exec()
1131 1122
1168 "revert {0} {1}".format( 1159 "revert {0} {1}".format(
1169 (not recurse) and " --non-recursive" or "", 1160 (not recurse) and " --non-recursive" or "",
1170 " ".join(name)), 1161 " ".join(name)),
1171 client) 1162 client)
1172 QApplication.processEvents() 1163 QApplication.processEvents()
1173 locker = QMutexLocker(self.vcsExecutionMutex)
1174 try: 1164 try:
1175 client.revert(name, recurse) 1165 with E5MutexLocker(self.vcsExecutionMutex):
1166 client.revert(name, recurse)
1176 except pysvn.ClientError as e: 1167 except pysvn.ClientError as e:
1177 dlg.showError(e.args[0]) 1168 dlg.showError(e.args[0])
1178 locker.unlock()
1179 dlg.finish() 1169 dlg.finish()
1180 dlg.exec() 1170 dlg.exec()
1181 self.checkVCSStatus() 1171 self.checkVCSStatus()
1182 1172
1183 def vcsSwitch(self, name): 1173 def vcsSwitch(self, name):
1244 client = self.getClient() 1234 client = self.getClient()
1245 dlg = SvnDialog(self.tr('Switching to {0}').format(tn), 1235 dlg = SvnDialog(self.tr('Switching to {0}').format(tn),
1246 "switch {0} {1}".format(url, name), 1236 "switch {0} {1}".format(url, name),
1247 client) 1237 client)
1248 QApplication.processEvents() 1238 QApplication.processEvents()
1249 locker = QMutexLocker(self.vcsExecutionMutex)
1250 try: 1239 try:
1251 rev = client.switch(name, url) 1240 with E5MutexLocker(self.vcsExecutionMutex):
1241 rev = client.switch(name, url)
1252 dlg.showMessage(self.tr("Revision {0}.\n").format(rev.number)) 1242 dlg.showMessage(self.tr("Revision {0}.\n").format(rev.number))
1253 except pysvn.ClientError as e: 1243 except pysvn.ClientError as e:
1254 dlg.showError(e.args[0]) 1244 dlg.showError(e.args[0])
1255 locker.unlock()
1256 dlg.finish() 1245 dlg.finish()
1257 dlg.exec() 1246 dlg.exec()
1258 res = dlg.hasAddOrDelete() 1247 res = dlg.hasAddOrDelete()
1259 self.checkVCSStatus() 1248 self.checkVCSStatus()
1260 return res 1249 return res
1284 self.mergeList[1].remove(urlrev2) 1273 self.mergeList[1].remove(urlrev2)
1285 self.mergeList[1].insert(0, urlrev2) 1274 self.mergeList[1].insert(0, urlrev2)
1286 1275
1287 rx_rev = QRegExp('\\d+|HEAD|head') 1276 rx_rev = QRegExp('\\d+|HEAD|head')
1288 1277
1289 locker = QMutexLocker(self.vcsExecutionMutex)
1290 cwd = os.getcwd() 1278 cwd = os.getcwd()
1291 os.chdir(dname) 1279 os.chdir(dname)
1292 recurse = "--non-recursive" not in opts 1280 recurse = "--non-recursive" not in opts
1293 if rx_rev.exactMatch(urlrev1): 1281 if rx_rev.exactMatch(urlrev1):
1294 if urlrev1 in ["HEAD", "head"]: 1282 if urlrev1 in ["HEAD", "head"]:
1353 "{0}{1}".format(url2, rev2 and ("@" + rev2) or ""), 1341 "{0}{1}".format(url2, rev2 and ("@" + rev2) or ""),
1354 fname), 1342 fname),
1355 client) 1343 client)
1356 QApplication.processEvents() 1344 QApplication.processEvents()
1357 try: 1345 try:
1358 client.merge(url1, revision1, url2, revision2, fname, 1346 with E5MutexLocker(self.vcsExecutionMutex):
1359 recurse=recurse, force=force) 1347 client.merge(url1, revision1, url2, revision2, fname,
1348 recurse=recurse, force=force)
1360 except pysvn.ClientError as e: 1349 except pysvn.ClientError as e:
1361 dlg.showError(e.args[0]) 1350 dlg.showError(e.args[0])
1362 locker.unlock()
1363 dlg.finish() 1351 dlg.finish()
1364 dlg.exec() 1352 dlg.exec()
1365 os.chdir(cwd) 1353 os.chdir(cwd)
1366 1354
1367 def vcsRegisteredState(self, name): 1355 def vcsRegisteredState(self, name):
1494 client.callback_ssl_server_trust_prompt = ( 1482 client.callback_ssl_server_trust_prompt = (
1495 mixin._clientSslServerTrustPromptCallback 1483 mixin._clientSslServerTrustPromptCallback
1496 ) 1484 )
1497 1485
1498 try: 1486 try:
1499 locker = QMutexLocker(self.vcsExecutionMutex) 1487 with E5MutexLocker(self.vcsExecutionMutex):
1500 allFiles = client.status(dname, recurse=True, get_all=True, 1488 allFiles = client.status(dname, recurse=True, get_all=True,
1501 ignore=True, update=False) 1489 ignore=True, update=False)
1502 locker.unlock()
1503 dirs = [x for x in names.keys() if os.path.isdir(x)] 1490 dirs = [x for x in names.keys() if os.path.isdir(x)]
1504 for file in allFiles: 1491 for file in allFiles:
1505 name = os.path.normcase(file.path) 1492 name = os.path.normcase(file.path)
1506 if self.__isVersioned(file): 1493 if self.__isVersioned(file):
1507 if name in names: 1494 if name in names:
1528 dirs.remove(d) 1515 dirs.remove(d)
1529 break 1516 break
1530 else: 1517 else:
1531 self.statusCache[name] = self.canBeAdded 1518 self.statusCache[name] = self.canBeAdded
1532 except pysvn.ClientError: 1519 except pysvn.ClientError:
1533 locker.unlock() # ignore pysvn errors 1520 # ignore pysvn errors
1521 pass
1534 1522
1535 return names 1523 return names
1536 1524
1537 def __vcsAllRegisteredStates_wc(self, names, dname, shortcut=True): 1525 def __vcsAllRegisteredStates_wc(self, names, dname, shortcut=True):
1538 """ 1526 """
1574 client.callback_ssl_server_trust_prompt = ( 1562 client.callback_ssl_server_trust_prompt = (
1575 mixin._clientSslServerTrustPromptCallback 1563 mixin._clientSslServerTrustPromptCallback
1576 ) 1564 )
1577 1565
1578 try: 1566 try:
1579 locker = QMutexLocker(self.vcsExecutionMutex) 1567 with E5MutexLocker(self.vcsExecutionMutex):
1580 allFiles = client.status(dname, recurse=True, get_all=True, 1568 allFiles = client.status(dname, recurse=True, get_all=True,
1581 ignore=True, update=False) 1569 ignore=True, update=False)
1582 locker.unlock()
1583 for file in allFiles: 1570 for file in allFiles:
1584 name = os.path.normcase(file.path) 1571 name = os.path.normcase(file.path)
1585 if self.__isVersioned(file): 1572 if self.__isVersioned(file):
1586 if name in names: 1573 if name in names:
1587 names[name] = self.canBeCommitted 1574 names[name] = self.canBeCommitted
1588 self.statusCache[name] = self.canBeCommitted 1575 self.statusCache[name] = self.canBeCommitted
1589 else: 1576 else:
1590 self.statusCache[name] = self.canBeAdded 1577 self.statusCache[name] = self.canBeAdded
1591 except pysvn.ClientError: 1578 except pysvn.ClientError:
1592 locker.unlock() # ignore pysvn errors 1579 # ignore pysvn errors
1580 pass
1593 1581
1594 return names 1582 return names
1595 1583
1596 def __isVersioned(self, status): 1584 def __isVersioned(self, status):
1597 """ 1585 """
1650 client = self.getClient() 1638 client = self.getClient()
1651 dlg = SvnDialog(self.tr('Cleaning up {0}').format(name), 1639 dlg = SvnDialog(self.tr('Cleaning up {0}').format(name),
1652 "cleanup {0}".format(name), 1640 "cleanup {0}".format(name),
1653 client) 1641 client)
1654 QApplication.processEvents() 1642 QApplication.processEvents()
1655 locker = QMutexLocker(self.vcsExecutionMutex)
1656 try: 1643 try:
1657 client.cleanup(name) 1644 with E5MutexLocker(self.vcsExecutionMutex):
1645 client.cleanup(name)
1658 except pysvn.ClientError as e: 1646 except pysvn.ClientError as e:
1659 dlg.showError(e.args[0]) 1647 dlg.showError(e.args[0])
1660 locker.unlock()
1661 dlg.finish() 1648 dlg.finish()
1662 dlg.exec() 1649 dlg.exec()
1663 1650
1664 def vcsCommandLine(self, name): 1651 def vcsCommandLine(self, name):
1665 """ 1652 """
1777 1764
1778 @param path local path to get the svn repository path for (string) 1765 @param path local path to get the svn repository path for (string)
1779 @return string with the repository path URL 1766 @return string with the repository path URL
1780 """ 1767 """
1781 client = pysvn.Client() 1768 client = pysvn.Client()
1782 locker = QMutexLocker(self.vcsExecutionMutex)
1783 try: 1769 try:
1784 entry = client.info(path) 1770 with E5MutexLocker(self.vcsExecutionMutex):
1771 entry = client.info(path)
1785 url = entry.url 1772 url = entry.url
1786 except pysvn.ClientError: 1773 except pysvn.ClientError:
1787 url = "" 1774 url = ""
1788 locker.unlock()
1789 return url 1775 return url
1790 1776
1791 def svnResolve(self, name): 1777 def svnResolve(self, name):
1792 """ 1778 """
1793 Public method used to resolve conflicts of a file/directory. 1779 Public method used to resolve conflicts of a file/directory.
1798 dname, fnames = self.splitPathList(name) 1784 dname, fnames = self.splitPathList(name)
1799 else: 1785 else:
1800 dname, fname = self.splitPath(name) 1786 dname, fname = self.splitPath(name)
1801 fnames = [fname] 1787 fnames = [fname]
1802 1788
1803 locker = QMutexLocker(self.vcsExecutionMutex)
1804 cwd = os.getcwd() 1789 cwd = os.getcwd()
1805 os.chdir(dname) 1790 os.chdir(dname)
1806 opts = self.options['global'] 1791 opts = self.options['global']
1807 recurse = "--non-recursive" not in opts 1792 recurse = "--non-recursive" not in opts
1808 client = self.getClient() 1793 client = self.getClient()
1811 (not recurse) and " --non-recursive" or "", 1796 (not recurse) and " --non-recursive" or "",
1812 " ".join(fnames)), 1797 " ".join(fnames)),
1813 client) 1798 client)
1814 QApplication.processEvents() 1799 QApplication.processEvents()
1815 try: 1800 try:
1816 for name in fnames: 1801 with E5MutexLocker(self.vcsExecutionMutex):
1817 client.resolved(name, recurse=recurse) 1802 for name in fnames:
1803 client.resolved(name, recurse=recurse)
1818 except pysvn.ClientError as e: 1804 except pysvn.ClientError as e:
1819 dlg.showError(e.args[0]) 1805 dlg.showError(e.args[0])
1820 locker.unlock()
1821 dlg.finish() 1806 dlg.finish()
1822 dlg.exec() 1807 dlg.exec()
1823 os.chdir(cwd) 1808 os.chdir(cwd)
1824 self.checkVCSStatus() 1809 self.checkVCSStatus()
1825 1810
1850 "copy{0} {1} {2}".format( 1835 "copy{0} {1} {2}".format(
1851 log and (" --message {0}".format(log)) or "", 1836 log and (" --message {0}".format(log)) or "",
1852 name, target), 1837 name, target),
1853 client, log=log) 1838 client, log=log)
1854 QApplication.processEvents() 1839 QApplication.processEvents()
1855 locker = QMutexLocker(self.vcsExecutionMutex)
1856 try: 1840 try:
1857 client.copy(name, target) 1841 with E5MutexLocker(self.vcsExecutionMutex):
1842 client.copy(name, target)
1858 res = True 1843 res = True
1859 except pysvn.ClientError as e: 1844 except pysvn.ClientError as e:
1860 res = False 1845 res = False
1861 dlg.showError(e.args[0]) 1846 dlg.showError(e.args[0])
1862 locker.unlock()
1863 dlg.finish() 1847 dlg.finish()
1864 dlg.exec() 1848 dlg.exec()
1865 if ( 1849 if (
1866 res and 1850 res and
1867 not rx_prot.exactMatch(target) and 1851 not rx_prot.exactMatch(target) and
1911 dname, fnames = self.splitPathList(name) 1895 dname, fnames = self.splitPathList(name)
1912 else: 1896 else:
1913 dname, fname = self.splitPath(name) 1897 dname, fname = self.splitPath(name)
1914 fnames = [fname] 1898 fnames = [fname]
1915 1899
1916 locker = QMutexLocker(self.vcsExecutionMutex)
1917 cwd = os.getcwd() 1900 cwd = os.getcwd()
1918 os.chdir(dname) 1901 os.chdir(dname)
1919 opts = self.options['global'] 1902 opts = self.options['global']
1920 skipchecks = "--skip-checks" in opts 1903 skipchecks = "--skip-checks" in opts
1921 client = self.getClient() 1904 client = self.getClient()
1927 propName, propValue, 1910 propName, propValue,
1928 " ".join(fnames)), 1911 " ".join(fnames)),
1929 client) 1912 client)
1930 QApplication.processEvents() 1913 QApplication.processEvents()
1931 try: 1914 try:
1932 for name in fnames: 1915 with E5MutexLocker(self.vcsExecutionMutex):
1933 client.propset(propName, propValue, name, 1916 for name in fnames:
1934 recurse=recurse, skip_checks=skipchecks) 1917 client.propset(propName, propValue, name,
1918 recurse=recurse, skip_checks=skipchecks)
1935 except pysvn.ClientError as e: 1919 except pysvn.ClientError as e:
1936 dlg.showError(e.args[0]) 1920 dlg.showError(e.args[0])
1937 locker.unlock()
1938 dlg.showMessage(self.tr("Property set.")) 1921 dlg.showMessage(self.tr("Property set."))
1939 dlg.finish() 1922 dlg.finish()
1940 dlg.exec() 1923 dlg.exec()
1941 os.chdir(cwd) 1924 os.chdir(cwd)
1942 1925
1964 dname, fnames = self.splitPathList(name) 1947 dname, fnames = self.splitPathList(name)
1965 else: 1948 else:
1966 dname, fname = self.splitPath(name) 1949 dname, fname = self.splitPath(name)
1967 fnames = [fname] 1950 fnames = [fname]
1968 1951
1969 locker = QMutexLocker(self.vcsExecutionMutex)
1970 cwd = os.getcwd() 1952 cwd = os.getcwd()
1971 os.chdir(dname) 1953 os.chdir(dname)
1972 opts = self.options['global'] 1954 opts = self.options['global']
1973 skipchecks = "--skip-checks" in opts 1955 skipchecks = "--skip-checks" in opts
1974 client = self.getClient() 1956 client = self.getClient()
1979 skipchecks and " --skip-checks" or "", 1961 skipchecks and " --skip-checks" or "",
1980 propName, " ".join(fnames)), 1962 propName, " ".join(fnames)),
1981 client) 1963 client)
1982 QApplication.processEvents() 1964 QApplication.processEvents()
1983 try: 1965 try:
1984 for name in fnames: 1966 with E5MutexLocker(self.vcsExecutionMutex):
1985 client.propdel(propName, name, 1967 for name in fnames:
1986 recurse=recurse, skip_checks=skipchecks) 1968 client.propdel(propName, name,
1969 recurse=recurse, skip_checks=skipchecks)
1987 except pysvn.ClientError as e: 1970 except pysvn.ClientError as e:
1988 dlg.showError(e.args[0]) 1971 dlg.showError(e.args[0])
1989 locker.unlock()
1990 dlg.showMessage(self.tr("Property deleted.")) 1972 dlg.showMessage(self.tr("Property deleted."))
1991 dlg.finish() 1973 dlg.finish()
1992 dlg.exec() 1974 dlg.exec()
1993 os.chdir(cwd) 1975 os.chdir(cwd)
1994 1976
2272 dname, fnames = self.splitPathList(name) 2254 dname, fnames = self.splitPathList(name)
2273 else: 2255 else:
2274 dname, fname = self.splitPath(name) 2256 dname, fname = self.splitPath(name)
2275 fnames = [fname] 2257 fnames = [fname]
2276 2258
2277 locker = QMutexLocker(self.vcsExecutionMutex)
2278 cwd = os.getcwd() 2259 cwd = os.getcwd()
2279 os.chdir(dname) 2260 os.chdir(dname)
2280 client = self.getClient() 2261 client = self.getClient()
2281 dlg = SvnDialog( 2262 dlg = SvnDialog(
2282 self.tr('Locking in the Subversion repository'), 2263 self.tr('Locking in the Subversion repository'),
2285 comment and (" --message {0}".format(comment)) or "", 2266 comment and (" --message {0}".format(comment)) or "",
2286 " ".join(fnames)), 2267 " ".join(fnames)),
2287 client, parent=parent) 2268 client, parent=parent)
2288 QApplication.processEvents() 2269 QApplication.processEvents()
2289 try: 2270 try:
2290 client.lock(fnames, comment, force=stealIt) 2271 with E5MutexLocker(self.vcsExecutionMutex):
2272 client.lock(fnames, comment, force=stealIt)
2291 except pysvn.ClientError as e: 2273 except pysvn.ClientError as e:
2292 dlg.showError(e.args[0]) 2274 dlg.showError(e.args[0])
2293 except AttributeError as e: 2275 except AttributeError as e:
2294 dlg.showError(str(e)) 2276 dlg.showError(str(e))
2295 locker.unlock()
2296 dlg.finish() 2277 dlg.finish()
2297 dlg.exec() 2278 dlg.exec()
2298 os.chdir(cwd) 2279 os.chdir(cwd)
2299 2280
2300 def svnUnlock(self, name, breakIt=False, parent=None): 2281 def svnUnlock(self, name, breakIt=False, parent=None):
2311 dname, fnames = self.splitPathList(name) 2292 dname, fnames = self.splitPathList(name)
2312 else: 2293 else:
2313 dname, fname = self.splitPath(name) 2294 dname, fname = self.splitPath(name)
2314 fnames = [fname] 2295 fnames = [fname]
2315 2296
2316 locker = QMutexLocker(self.vcsExecutionMutex)
2317 cwd = os.getcwd() 2297 cwd = os.getcwd()
2318 os.chdir(dname) 2298 os.chdir(dname)
2319 client = self.getClient() 2299 client = self.getClient()
2320 dlg = SvnDialog( 2300 dlg = SvnDialog(
2321 self.tr('Unlocking in the Subversion repository'), 2301 self.tr('Unlocking in the Subversion repository'),
2322 "unlock{0} {1}".format(breakIt and " --force" or "", 2302 "unlock{0} {1}".format(breakIt and " --force" or "",
2323 " ".join(fnames)), 2303 " ".join(fnames)),
2324 client, parent=parent) 2304 client, parent=parent)
2325 QApplication.processEvents() 2305 QApplication.processEvents()
2326 try: 2306 try:
2327 client.unlock(fnames, force=breakIt) 2307 with E5MutexLocker(self.vcsExecutionMutex):
2308 client.unlock(fnames, force=breakIt)
2328 except pysvn.ClientError as e: 2309 except pysvn.ClientError as e:
2329 dlg.showError(e.args[0]) 2310 dlg.showError(e.args[0])
2330 except AttributeError as e: 2311 except AttributeError as e:
2331 dlg.showError(str(e)) 2312 dlg.showError(str(e))
2332 locker.unlock()
2333 dlg.finish() 2313 dlg.finish()
2334 dlg.exec() 2314 dlg.exec()
2335 os.chdir(cwd) 2315 os.chdir(cwd)
2336 2316
2337 def svnInfo(self, projectPath, name): 2317 def svnInfo(self, projectPath, name):
2363 msg = "relocate {0} {1} {2}".format(currUrl, newUrl, 2343 msg = "relocate {0} {1} {2}".format(currUrl, newUrl,
2364 projectPath) 2344 projectPath)
2365 client = self.getClient() 2345 client = self.getClient()
2366 dlg = SvnDialog(self.tr('Relocating'), msg, client) 2346 dlg = SvnDialog(self.tr('Relocating'), msg, client)
2367 QApplication.processEvents() 2347 QApplication.processEvents()
2368 locker = QMutexLocker(self.vcsExecutionMutex)
2369 try: 2348 try:
2370 if inside: 2349 with E5MutexLocker(self.vcsExecutionMutex):
2371 client.switch(projectPath, newUrl) 2350 if inside:
2372 else: 2351 client.switch(projectPath, newUrl)
2373 client.relocate(currUrl, newUrl, projectPath, recurse=True) 2352 else:
2353 client.relocate(currUrl, newUrl, projectPath,
2354 recurse=True)
2374 except pysvn.ClientError as e: 2355 except pysvn.ClientError as e:
2375 dlg.showError(e.args[0]) 2356 dlg.showError(e.args[0])
2376 locker.unlock()
2377 dlg.finish() 2357 dlg.finish()
2378 dlg.exec() 2358 dlg.exec()
2379 2359
2380 def svnRepoBrowser(self, projectPath=None): 2360 def svnRepoBrowser(self, projectPath=None):
2381 """ 2361 """
2419 dlg = SvnDialog( 2399 dlg = SvnDialog(
2420 self.tr('Remove from changelist'), 2400 self.tr('Remove from changelist'),
2421 "changelist --remove {0}".format(" ".join(names)), 2401 "changelist --remove {0}".format(" ".join(names)),
2422 client) 2402 client)
2423 QApplication.processEvents() 2403 QApplication.processEvents()
2424 locker = QMutexLocker(self.vcsExecutionMutex)
2425 try: 2404 try:
2426 for name in names: 2405 with E5MutexLocker(self.vcsExecutionMutex):
2427 client.remove_from_changelists(name) 2406 for name in names:
2407 client.remove_from_changelists(name)
2428 except pysvn.ClientError as e: 2408 except pysvn.ClientError as e:
2429 dlg.showError(e.args[0]) 2409 dlg.showError(e.args[0])
2430 locker.unlock()
2431 dlg.finish() 2410 dlg.finish()
2432 dlg.exec() 2411 dlg.exec()
2433 2412
2434 def svnAddToChangelist(self, names): 2413 def svnAddToChangelist(self, names):
2435 """ 2414 """
2456 dlg = SvnDialog( 2435 dlg = SvnDialog(
2457 self.tr('Add to changelist'), 2436 self.tr('Add to changelist'),
2458 "changelist {0}".format(" ".join(names)), 2437 "changelist {0}".format(" ".join(names)),
2459 client) 2438 client)
2460 QApplication.processEvents() 2439 QApplication.processEvents()
2461 locker = QMutexLocker(self.vcsExecutionMutex)
2462 try: 2440 try:
2463 for name in names: 2441 with E5MutexLocker(self.vcsExecutionMutex):
2464 client.add_to_changelist(name, clname, 2442 for name in names:
2465 depth=pysvn.depth.infinity) 2443 client.add_to_changelist(
2444 name, clname, depth=pysvn.depth.infinity)
2466 except pysvn.ClientError as e: 2445 except pysvn.ClientError as e:
2467 dlg.showError(e.args[0]) 2446 dlg.showError(e.args[0])
2468 locker.unlock()
2469 dlg.finish() 2447 dlg.finish()
2470 dlg.exec() 2448 dlg.exec()
2471 2449
2472 def svnShowChangelists(self, path): 2450 def svnShowChangelists(self, path):
2473 """ 2451 """
2489 """ 2467 """
2490 changelists = [] 2468 changelists = []
2491 client = self.getClient() 2469 client = self.getClient()
2492 if hasattr(client, 'get_changelist'): 2470 if hasattr(client, 'get_changelist'):
2493 ppath = e5App().getObject("Project").getProjectPath() 2471 ppath = e5App().getObject("Project").getProjectPath()
2494 locker = QMutexLocker(self.vcsExecutionMutex)
2495 try: 2472 try:
2496 entries = client.get_changelist(ppath, 2473 with E5MutexLocker(self.vcsExecutionMutex):
2497 depth=pysvn.depth.infinity) 2474 entries = client.get_changelist(
2475 ppath, depth=pysvn.depth.infinity)
2498 for entry in entries: 2476 for entry in entries:
2499 changelist = entry[1] 2477 changelist = entry[1]
2500 if changelist not in changelists: 2478 if changelist not in changelists:
2501 changelists.append(changelist) 2479 changelists.append(changelist)
2502 except pysvn.ClientError: 2480 except pysvn.ClientError:
2503 pass 2481 pass
2504 locker.unlock()
2505 2482
2506 return changelists 2483 return changelists
2507 2484
2508 def svnUpgrade(self, path): 2485 def svnUpgrade(self, path):
2509 """ 2486 """
2515 dlg = SvnDialog( 2492 dlg = SvnDialog(
2516 self.tr('Upgrade'), 2493 self.tr('Upgrade'),
2517 "upgrade {0}".format(path), 2494 "upgrade {0}".format(path),
2518 client) 2495 client)
2519 QApplication.processEvents() 2496 QApplication.processEvents()
2520 locker = QMutexLocker(self.vcsExecutionMutex)
2521 try: 2497 try:
2522 client.upgrade(path) 2498 with E5MutexLocker(self.vcsExecutionMutex):
2499 client.upgrade(path)
2523 except pysvn.ClientError as e: 2500 except pysvn.ClientError as e:
2524 dlg.showError(e.args[0]) 2501 dlg.showError(e.args[0])
2525 locker.unlock()
2526 dlg.finish() 2502 dlg.finish()
2527 dlg.exec() 2503 dlg.exec()
2528 2504
2529 ########################################################################### 2505 ###########################################################################
2530 ## Private Subversion specific methods are below. 2506 ## Private Subversion specific methods are below.

eric ide

mercurial