83 ] |
83 ] |
84 |
84 |
85 self.commandHistory = [] |
85 self.commandHistory = [] |
86 self.wdHistory = [] |
86 self.wdHistory = [] |
87 |
87 |
88 if pysvn.version >= (1, 4, 3, 0) and "SVN_ASP_DOT_NET_HACK" in os.environ: |
88 if pysvn.version >= (1, 4, 3, 0) and \ |
|
89 "SVN_ASP_DOT_NET_HACK" in os.environ: |
89 self.adminDir = '_svn' |
90 self.adminDir = '_svn' |
90 else: |
91 else: |
91 self.adminDir = '.svn' |
92 self.adminDir = '.svn' |
92 |
93 |
93 self.log = None |
94 self.log = None |
133 client.exception_style = 1 |
135 client.exception_style = 1 |
134 client.set_auth_cache(authCache) |
136 client.set_auth_cache(authCache) |
135 |
137 |
136 return client |
138 return client |
137 |
139 |
138 ############################################################################ |
140 ########################################################################### |
139 ## Methods of the VCS interface |
141 ## Methods of the VCS interface |
140 ############################################################################ |
142 ########################################################################### |
141 |
143 |
142 def vcsShutdown(self): |
144 def vcsShutdown(self): |
143 """ |
145 """ |
144 Public method used to shutdown the Subversion interface. |
146 Public method used to shutdown the Subversion interface. |
145 """ |
147 """ |
186 """ |
189 """ |
187 return True |
190 return True |
188 |
191 |
189 def vcsConvertProject(self, vcsDataDict, project): |
192 def vcsConvertProject(self, vcsDataDict, project): |
190 """ |
193 """ |
191 Public method to convert an uncontrolled project to a version controlled project. |
194 Public method to convert an uncontrolled project to a version |
|
195 controlled project. |
192 |
196 |
193 @param vcsDataDict dictionary of data required for the conversion |
197 @param vcsDataDict dictionary of data required for the conversion |
194 @param project reference to the project object |
198 @param project reference to the project object |
195 """ |
199 """ |
196 success = self.vcsImport(vcsDataDict, project.ppath)[0] |
200 success = self.vcsImport(vcsDataDict, project.ppath)[0] |
197 if not success: |
201 if not success: |
198 E5MessageBox.critical(self.__ui, |
202 E5MessageBox.critical(self.__ui, |
199 self.trUtf8("Create project in repository"), |
203 self.trUtf8("Create project in repository"), |
200 self.trUtf8("""The project could not be created in the repository.""" |
204 self.trUtf8( |
201 """ Maybe the given repository doesn't exist or the""" |
205 """The project could not be created in the repository.""" |
202 """ repository server is down.""")) |
206 """ Maybe the given repository doesn't exist or the""" |
|
207 """ repository server is down.""")) |
203 else: |
208 else: |
204 cwdIsPpath = False |
209 cwdIsPpath = False |
205 if os.getcwd() == project.ppath: |
210 if os.getcwd() == project.ppath: |
206 os.chdir(os.path.dirname(project.ppath)) |
211 os.chdir(os.path.dirname(project.ppath)) |
207 cwdIsPpath = True |
212 cwdIsPpath = True |
217 if not os.path.isfile(pfn): |
222 if not os.path.isfile(pfn): |
218 pfn += "z" |
223 pfn += "z" |
219 if not os.path.isfile(pfn): |
224 if not os.path.isfile(pfn): |
220 E5MessageBox.critical(self.__ui, |
225 E5MessageBox.critical(self.__ui, |
221 self.trUtf8("New project"), |
226 self.trUtf8("New project"), |
222 self.trUtf8("""The project could not be checked out of the""" |
227 self.trUtf8( |
223 """ repository.<br />""" |
228 """The project could not be checked out of the""" |
224 """Restoring the original contents.""")) |
229 """ repository.<br />""" |
|
230 """Restoring the original contents.""")) |
225 if os.getcwd() == project.ppath: |
231 if os.getcwd() == project.ppath: |
226 os.chdir(os.path.dirname(project.ppath)) |
232 os.chdir(os.path.dirname(project.ppath)) |
227 cwdIsPpath = True |
233 cwdIsPpath = True |
228 else: |
234 else: |
229 cwdIsPpath = False |
235 cwdIsPpath = False |
239 project.closeProject(noSave=True) |
245 project.closeProject(noSave=True) |
240 project.openProject(pfn) |
246 project.openProject(pfn) |
241 |
247 |
242 def vcsImport(self, vcsDataDict, projectDir, noDialog=False): |
248 def vcsImport(self, vcsDataDict, projectDir, noDialog=False): |
243 """ |
249 """ |
244 Public method used to import the project into the Subversion repository. |
250 Public method used to import the project into the Subversion |
|
251 repository. |
245 |
252 |
246 @param vcsDataDict dictionary of data required for the import |
253 @param vcsDataDict dictionary of data required for the import |
247 @param projectDir project directory (string) |
254 @param projectDir project directory (string) |
248 @param noDialog flag indicating quiet operations |
255 @param noDialog flag indicating quiet operations |
249 @return flag indicating an execution without errors (boolean) |
256 @return flag indicating an execution without errors (boolean) |
268 os.makedirs(tmpDir) |
275 os.makedirs(tmpDir) |
269 if self.otherData["standardLayout"]: |
276 if self.otherData["standardLayout"]: |
270 os.mkdir(os.path.join(tmpDir, project)) |
277 os.mkdir(os.path.join(tmpDir, project)) |
271 os.mkdir(os.path.join(tmpDir, project, 'branches')) |
278 os.mkdir(os.path.join(tmpDir, project, 'branches')) |
272 os.mkdir(os.path.join(tmpDir, project, 'tags')) |
279 os.mkdir(os.path.join(tmpDir, project, 'tags')) |
273 shutil.copytree(projectDir, os.path.join(tmpDir, project, 'trunk')) |
280 shutil.copytree( |
|
281 projectDir, os.path.join(tmpDir, project, 'trunk')) |
274 else: |
282 else: |
275 shutil.copytree(projectDir, os.path.join(tmpDir, project)) |
283 shutil.copytree(projectDir, os.path.join(tmpDir, project)) |
276 except OSError as e: |
284 except OSError as e: |
277 if os.path.isdir(tmpDir): |
285 if os.path.isdir(tmpDir): |
278 shutil.rmtree(tmpDir, True) |
286 shutil.rmtree(tmpDir, True) |
284 opts = self.options['global'] |
292 opts = self.options['global'] |
285 recurse = "--non-recursive" not in opts |
293 recurse = "--non-recursive" not in opts |
286 url = self.__svnURL(vcsDir) |
294 url = self.__svnURL(vcsDir) |
287 client = self.getClient() |
295 client = self.getClient() |
288 if not noDialog: |
296 if not noDialog: |
289 dlg = \ |
297 dlg = SvnDialog( |
290 SvnDialog(self.trUtf8('Importing project into Subversion repository'), |
298 self.trUtf8('Importing project into Subversion repository'), |
291 "import{0} --message {1} .".format( |
299 "import{0} --message {1} .".format( |
292 (not recurse) and " --non-recursive" or "", |
300 (not recurse) and " --non-recursive" or "", msg), |
293 msg), |
301 client) |
294 client) |
|
295 QApplication.processEvents() |
302 QApplication.processEvents() |
296 try: |
303 try: |
297 rev = client.import_(".", url, msg, recurse, ignore=True) |
304 rev = client.import_(".", url, msg, recurse, ignore=True) |
298 status = True |
305 status = True |
299 except pysvn.ClientError as e: |
306 except pysvn.ClientError as e: |
312 shutil.rmtree(tmpDir, True) |
319 shutil.rmtree(tmpDir, True) |
313 return status, False |
320 return status, False |
314 |
321 |
315 def vcsCheckout(self, vcsDataDict, projectDir, noDialog=False): |
322 def vcsCheckout(self, vcsDataDict, projectDir, noDialog=False): |
316 """ |
323 """ |
317 Public method used to check the project out of the Subversion repository. |
324 Public method used to check the project out of the Subversion |
|
325 repository. |
318 |
326 |
319 @param vcsDataDict dictionary of data required for the checkout |
327 @param vcsDataDict dictionary of data required for the checkout |
320 @param projectDir project directory to create (string) |
328 @param projectDir project directory to create (string) |
321 @param noDialog flag indicating quiet operations |
329 @param noDialog flag indicating quiet operations |
322 @return flag indicating an execution without errors (boolean) |
330 @return flag indicating an execution without errors (boolean) |
334 |
342 |
335 if self.otherData["standardLayout"]: |
343 if self.otherData["standardLayout"]: |
336 if tag is None or tag == '': |
344 if tag is None or tag == '': |
337 svnUrl = '{0}/trunk'.format(vcsDir) |
345 svnUrl = '{0}/trunk'.format(vcsDir) |
338 else: |
346 else: |
339 if not tag.startswith('tags') and not tag.startswith('branches'): |
347 if not tag.startswith('tags') and \ |
|
348 not tag.startswith('branches'): |
340 type_, ok = QInputDialog.getItem( |
349 type_, ok = QInputDialog.getItem( |
341 None, |
350 None, |
342 self.trUtf8("Subversion Checkout"), |
351 self.trUtf8("Subversion Checkout"), |
343 self.trUtf8("The tag must be a normal tag (tags) or" |
352 self.trUtf8("The tag must be a normal tag (tags) or" |
344 " a branch tag (branches)." |
353 " a branch tag (branches)." |
355 opts = self.options['global'] + self.options['checkout'] |
364 opts = self.options['global'] + self.options['checkout'] |
356 recurse = "--non-recursive" not in opts |
365 recurse = "--non-recursive" not in opts |
357 url = self.__svnURL(svnUrl) |
366 url = self.__svnURL(svnUrl) |
358 client = self.getClient() |
367 client = self.getClient() |
359 if not noDialog: |
368 if not noDialog: |
360 dlg = \ |
369 dlg = SvnDialog( |
361 SvnDialog(self.trUtf8('Checking project out of Subversion repository'), |
370 self.trUtf8('Checking project out of Subversion repository'), |
362 "checkout{0} {1} {2}".format( |
371 "checkout{0} {1} {2}".format( |
363 (not recurse) and " --non-recursive" or "", |
372 (not recurse) and " --non-recursive" or "", |
364 url, projectDir), |
373 url, projectDir), |
365 client) |
374 client) |
366 QApplication.processEvents() |
375 QApplication.processEvents() |
367 locker = QMutexLocker(self.vcsExecutionMutex) |
376 locker = QMutexLocker(self.vcsExecutionMutex) |
368 try: |
377 try: |
369 client.checkout(url, projectDir, recurse) |
378 client.checkout(url, projectDir, recurse) |
370 status = True |
379 status = True |
378 dlg.exec_() |
387 dlg.exec_() |
379 return status |
388 return status |
380 |
389 |
381 def vcsExport(self, vcsDataDict, projectDir): |
390 def vcsExport(self, vcsDataDict, projectDir): |
382 """ |
391 """ |
383 Public method used to export a directory from the Subversion repository. |
392 Public method used to export a directory from the Subversion |
|
393 repository. |
384 |
394 |
385 @param vcsDataDict dictionary of data required for the checkout |
395 @param vcsDataDict dictionary of data required for the checkout |
386 @param projectDir project directory to create (string) |
396 @param projectDir project directory to create (string) |
387 @return flag indicating an execution without errors (boolean) |
397 @return flag indicating an execution without errors (boolean) |
388 """ |
398 """ |
396 |
406 |
397 if self.otherData["standardLayout"]: |
407 if self.otherData["standardLayout"]: |
398 if tag is None or tag == '': |
408 if tag is None or tag == '': |
399 svnUrl = '{0}/trunk'.format(vcsDir) |
409 svnUrl = '{0}/trunk'.format(vcsDir) |
400 else: |
410 else: |
401 if not tag.startswith('tags') and not tag.startswith('branches'): |
411 if not tag.startswith('tags') and \ |
|
412 not tag.startswith('branches'): |
402 type_, ok = QInputDialog.getItem( |
413 type_, ok = QInputDialog.getItem( |
403 None, |
414 None, |
404 self.trUtf8("Subversion Export"), |
415 self.trUtf8("Subversion Export"), |
405 self.trUtf8("The tag must be a normal tag (tags) or" |
416 self.trUtf8("The tag must be a normal tag (tags) or" |
406 " a branch tag (branches)." |
417 " a branch tag (branches)." |
416 |
427 |
417 opts = self.options['global'] |
428 opts = self.options['global'] |
418 recurse = "--non-recursive" not in opts |
429 recurse = "--non-recursive" not in opts |
419 url = self.__svnURL(svnUrl) |
430 url = self.__svnURL(svnUrl) |
420 client = self.getClient() |
431 client = self.getClient() |
421 dlg = \ |
432 dlg = SvnDialog( |
422 SvnDialog(self.trUtf8('Exporting project from Subversion repository'), |
433 self.trUtf8('Exporting project from Subversion repository'), |
423 "export --force{0} {1} {2}".format( |
434 "export --force{0} {1} {2}".format( |
424 (not recurse) and " --non-recursive" or "", |
435 (not recurse) and " --non-recursive" or "", |
425 url, projectDir), |
436 url, projectDir), |
426 client) |
437 client) |
427 QApplication.processEvents() |
438 QApplication.processEvents() |
428 locker = QMutexLocker(self.vcsExecutionMutex) |
439 locker = QMutexLocker(self.vcsExecutionMutex) |
429 try: |
440 try: |
430 client.export(url, projectDir, force=True, recurse=recurse) |
441 client.export(url, projectDir, force=True, recurse=recurse) |
431 status = True |
442 status = True |
437 dlg.exec_() |
448 dlg.exec_() |
438 return status |
449 return status |
439 |
450 |
440 def vcsCommit(self, name, message, noDialog=False): |
451 def vcsCommit(self, name, message, noDialog=False): |
441 """ |
452 """ |
442 Public method used to make the change of a file/directory permanent in the |
453 Public method used to make the change of a file/directory permanent |
443 Subversion repository. |
454 in the Subversion repository. |
444 |
455 |
445 @param name file/directory name to be committed (string or list of strings) |
456 @param name file/directory name to be committed (string or |
|
457 list of strings) |
446 @param message message for this operation (string) |
458 @param message message for this operation (string) |
447 @param noDialog flag indicating quiet operations |
459 @param noDialog flag indicating quiet operations |
448 """ |
460 """ |
449 if not noDialog and not message: |
461 if not noDialog and not message: |
450 # call CommitDialog and get message from there |
462 # call CommitDialog and get message from there |
451 if self.__commitDialog is None: |
463 if self.__commitDialog is None: |
452 from .SvnCommitDialog import SvnCommitDialog |
464 from .SvnCommitDialog import SvnCommitDialog |
453 self.__commitDialog = SvnCommitDialog(self.svnGetChangelists(), self.__ui) |
465 self.__commitDialog = SvnCommitDialog( |
|
466 self.svnGetChangelists(), self.__ui) |
454 self.__commitDialog.accepted.connect(self.__vcsCommit_Step2) |
467 self.__commitDialog.accepted.connect(self.__vcsCommit_Step2) |
455 self.__commitDialog.show() |
468 self.__commitDialog.show() |
456 self.__commitDialog.raise_() |
469 self.__commitDialog.raise_() |
457 self.__commitDialog.activateWindow() |
470 self.__commitDialog.activateWindow() |
458 |
471 |
481 for nam in nameList: |
494 for nam in nameList: |
482 # check for commit of the project |
495 # check for commit of the project |
483 if os.path.isdir(nam): |
496 if os.path.isdir(nam): |
484 project = e5App().getObject("Project") |
497 project = e5App().getObject("Project") |
485 if nam == project.getProjectPath(): |
498 if nam == project.getProjectPath(): |
486 ok &= project.checkAllScriptsDirty(reportSyntaxErrors=True) and \ |
499 ok &= project.checkAllScriptsDirty( |
|
500 reportSyntaxErrors=True) and \ |
487 project.checkDirty() |
501 project.checkDirty() |
488 continue |
502 continue |
489 elif os.path.isfile(nam): |
503 elif os.path.isfile(nam): |
490 editor = e5App().getObject("ViewManager").getOpenEditor(nam) |
504 editor = e5App().getObject("ViewManager")\ |
|
505 .getOpenEditor(nam) |
491 if editor: |
506 if editor: |
492 ok &= editor.checkDirty() |
507 ok &= editor.checkDirty() |
493 if not ok: |
508 if not ok: |
494 break |
509 break |
495 |
510 |
496 if not ok: |
511 if not ok: |
497 res = E5MessageBox.yesNo(self.__ui, |
512 res = E5MessageBox.yesNo(self.__ui, |
498 self.trUtf8("Commit Changes"), |
513 self.trUtf8("Commit Changes"), |
499 self.trUtf8("""The commit affects files, that have unsaved""" |
514 self.trUtf8( |
500 """ changes. Shall the commit be continued?"""), |
515 """The commit affects files, that have unsaved""" |
|
516 """ changes. Shall the commit be continued?"""), |
501 icon=E5MessageBox.Warning) |
517 icon=E5MessageBox.Warning) |
502 if not res: |
518 if not res: |
503 return |
519 return |
504 |
520 |
505 if self.__commitDialog is not None: |
521 if self.__commitDialog is not None: |
506 msg = self.__commitDialog.logMessage() |
522 msg = self.__commitDialog.logMessage() |
507 if self.__commitDialog.hasChangelists(): |
523 if self.__commitDialog.hasChangelists(): |
508 changelists, keepChangelists = self.__commitDialog.changelistsData() |
524 changelists, keepChangelists = \ |
|
525 self.__commitDialog.changelistsData() |
509 else: |
526 else: |
510 changelists, keepChangelists = [], False |
527 changelists, keepChangelists = [], False |
511 ## self.__commitDialog.accepted.disconnect(self.__vcsCommit_Step2) |
|
512 self.__commitDialog.deleteLater() |
528 self.__commitDialog.deleteLater() |
513 self.__commitDialog = None |
529 self.__commitDialog = None |
514 else: |
530 else: |
515 changelists, keepChangelists = [], False |
531 changelists, keepChangelists = [], False |
516 |
532 |
533 opts = self.options['global'] + self.options['commit'] |
549 opts = self.options['global'] + self.options['commit'] |
534 recurse = "--non-recursive" not in opts |
550 recurse = "--non-recursive" not in opts |
535 keeplocks = "--keep-locks" in opts |
551 keeplocks = "--keep-locks" in opts |
536 client = self.getClient() |
552 client = self.getClient() |
537 if not noDialog: |
553 if not noDialog: |
538 dlg = \ |
554 dlg = SvnDialog( |
539 SvnDialog(self.trUtf8('Commiting changes to Subversion repository'), |
555 self.trUtf8('Commiting changes to Subversion repository'), |
540 "commit{0}{1}{2}{3} --message {4} {5}".format( |
556 "commit{0}{1}{2}{3} --message {4} {5}".format( |
541 (not recurse) and " --non-recursive" or "", |
557 (not recurse) and " --non-recursive" or "", |
542 keeplocks and " --keep-locks" or "", |
558 keeplocks and " --keep-locks" or "", |
543 keepChangelists and " --keep-changelists" or "", |
559 keepChangelists and " --keep-changelists" or "", |
544 changelists and \ |
560 changelists and \ |
545 " --changelist ".join([""] + changelists) or "", |
561 " --changelist ".join([""] + changelists) or "", |
546 msg, " ".join(fnames)), |
562 msg, " ".join(fnames)), |
547 client) |
563 client) |
548 QApplication.processEvents() |
564 QApplication.processEvents() |
549 try: |
565 try: |
550 if changelists: |
566 if changelists: |
551 rev = client.checkin(fnames, msg, |
567 rev = client.checkin(fnames, msg, |
552 recurse=recurse, keep_locks=keeplocks, |
568 recurse=recurse, keep_locks=keeplocks, |
569 self.committed.emit() |
585 self.committed.emit() |
570 self.checkVCSStatus() |
586 self.checkVCSStatus() |
571 |
587 |
572 def vcsUpdate(self, name, noDialog=False): |
588 def vcsUpdate(self, name, noDialog=False): |
573 """ |
589 """ |
574 Public method used to update a file/directory with the Subversion repository. |
590 Public method used to update a file/directory with the Subversion |
575 |
591 repository. |
576 @param name file/directory name to be updated (string or list of strings) |
592 |
|
593 @param name file/directory name to be updated (string or list of |
|
594 strings) |
577 @param noDialog flag indicating quiet operations (boolean) |
595 @param noDialog flag indicating quiet operations (boolean) |
578 @return flag indicating, that the update contained an add |
596 @return flag indicating, that the update contained an add |
579 or delete (boolean) |
597 or delete (boolean) |
580 """ |
598 """ |
581 if isinstance(name, list): |
599 if isinstance(name, list): |
589 os.chdir(dname) |
607 os.chdir(dname) |
590 opts = self.options['global'] + self.options['update'] |
608 opts = self.options['global'] + self.options['update'] |
591 recurse = "--non-recursive" not in opts |
609 recurse = "--non-recursive" not in opts |
592 client = self.getClient() |
610 client = self.getClient() |
593 if not noDialog: |
611 if not noDialog: |
594 dlg = \ |
612 dlg = SvnDialog( |
595 SvnDialog(self.trUtf8('Synchronizing with the Subversion repository'), |
613 self.trUtf8('Synchronizing with the Subversion repository'), |
596 "update{0} {1}".format( |
614 "update{0} {1}".format( |
597 (not recurse) and " --non-recursive" or "", |
615 (not recurse) and " --non-recursive" or "", |
598 " ".join(fnames)), |
616 " ".join(fnames)), |
599 client) |
617 client) |
600 QApplication.processEvents() |
618 QApplication.processEvents() |
601 try: |
619 try: |
602 client.update(fnames, recurse) |
620 client.update(fnames, recurse) |
603 except pysvn.ClientError as e: |
621 except pysvn.ClientError as e: |
604 dlg.showError(e.args[0]) |
622 dlg.showError(e.args[0]) |
613 self.checkVCSStatus() |
631 self.checkVCSStatus() |
614 return res |
632 return res |
615 |
633 |
616 def vcsAdd(self, name, isDir=False, noDialog=False): |
634 def vcsAdd(self, name, isDir=False, noDialog=False): |
617 """ |
635 """ |
618 Public method used to add a file/directory to the Subversion repository. |
636 Public method used to add a file/directory to the Subversion |
|
637 repository. |
619 |
638 |
620 @param name file/directory name to be added (string) |
639 @param name file/directory name to be added (string) |
621 @param isDir flag indicating name is a directory (boolean) |
640 @param isDir flag indicating name is a directory (boolean) |
622 @param noDialog flag indicating quiet operations (boolean) |
641 @param noDialog flag indicating quiet operations (boolean) |
623 """ |
642 """ |
640 repodir = os.path.dirname(repodir) |
659 repodir = os.path.dirname(repodir) |
641 if os.path.splitdrive(repodir)[1] == os.sep: |
660 if os.path.splitdrive(repodir)[1] == os.sep: |
642 return # oops, project is not version controlled |
661 return # oops, project is not version controlled |
643 while os.path.normcase(dname) != os.path.normcase(repodir) and \ |
662 while os.path.normcase(dname) != os.path.normcase(repodir) and \ |
644 (os.path.normcase(dname) not in self.statusCache or \ |
663 (os.path.normcase(dname) not in self.statusCache or \ |
645 self.statusCache[os.path.normcase(dname)] == self.canBeAdded): |
664 self.statusCache[os.path.normcase(dname)] == |
646 # add directories recursively, if they aren't in the repository already |
665 self.canBeAdded): |
|
666 # add directories recursively, if they aren't in the |
|
667 # repository already |
647 tree.insert(-1, dname) |
668 tree.insert(-1, dname) |
648 dname = os.path.dirname(dname) |
669 dname = os.path.dirname(dname) |
649 wdir = dname |
670 wdir = dname |
650 else: |
671 else: |
651 while not os.path.exists(os.path.join(dname, self.adminDir)): |
672 while not os.path.exists(os.path.join(dname, self.adminDir)): |
652 # add directories recursively, if they aren't in the repository already |
673 # add directories recursively, if they aren't in the |
|
674 # repository already |
653 tree.insert(-1, dname) |
675 tree.insert(-1, dname) |
654 dname = os.path.dirname(dname) |
676 dname = os.path.dirname(dname) |
655 wdir = dname |
677 wdir = dname |
656 names.extend(tree) |
678 names.extend(tree) |
657 |
679 |
659 tree2 = [] |
681 tree2 = [] |
660 for n in name: |
682 for n in name: |
661 d = os.path.dirname(n) |
683 d = os.path.dirname(n) |
662 if self.__wcng: |
684 if self.__wcng: |
663 repodir = d |
685 repodir = d |
664 while not os.path.isdir(os.path.join(repodir, self.adminDir)): |
686 while not os.path.isdir( |
|
687 os.path.join(repodir, self.adminDir)): |
665 repodir = os.path.dirname(repodir) |
688 repodir = os.path.dirname(repodir) |
666 if os.path.splitdrive(repodir)[1] == os.sep: |
689 if os.path.splitdrive(repodir)[1] == os.sep: |
667 return # oops, project is not version controlled |
690 return # oops, project is not version controlled |
668 while os.path.normcase(d) != os.path.normcase(repodir) and \ |
691 while os.path.normcase(d) != \ |
|
692 os.path.normcase(repodir) and \ |
669 (d not in tree2 + tree) and \ |
693 (d not in tree2 + tree) and \ |
670 (os.path.normcase(d) not in self.statusCache or \ |
694 (os.path.normcase(d) not in self.statusCache or \ |
671 self.statusCache[os.path.normcase(d)] == self.canBeAdded): |
695 self.statusCache[os.path.normcase(d)] == |
|
696 self.canBeAdded): |
672 tree2.append(d) |
697 tree2.append(d) |
673 d = os.path.dirname(d) |
698 d = os.path.dirname(d) |
674 else: |
699 else: |
675 while not os.path.exists(os.path.join(d, self.adminDir)): |
700 while not os.path.exists(os.path.join(d, self.adminDir)): |
676 if d in tree2 + tree: |
701 if d in tree2 + tree: |
690 recurse = False |
715 recurse = False |
691 force = "--force" in opts or noDialog |
716 force = "--force" in opts or noDialog |
692 noignore = "--no-ignore" in opts |
717 noignore = "--no-ignore" in opts |
693 client = self.getClient() |
718 client = self.getClient() |
694 if not noDialog: |
719 if not noDialog: |
695 dlg = \ |
720 dlg = SvnDialog( |
696 SvnDialog( |
721 self.trUtf8('Adding files/directories to the Subversion' |
697 self.trUtf8('Adding files/directories to the Subversion repository'), |
722 ' repository'), |
698 "add --non-recursive{0}{1} {2}".format( |
723 "add --non-recursive{0}{1} {2}".format( |
699 force and " --force" or "", |
724 force and " --force" or "", |
700 noignore and " --no-ignore" or "", |
725 noignore and " --no-ignore" or "", |
701 " ".join(names)), |
726 " ".join(names)), |
702 client) |
727 client) |
703 QApplication.processEvents() |
728 QApplication.processEvents() |
704 try: |
729 try: |
705 client.add(names, recurse=recurse, force=force, ignore=not noignore) |
730 client.add(names, recurse=recurse, force=force, |
|
731 ignore=not noignore) |
706 except pysvn.ClientError as e: |
732 except pysvn.ClientError as e: |
707 if not noDialog: |
733 if not noDialog: |
708 dlg.showError(e.args[0]) |
734 dlg.showError(e.args[0]) |
709 locker.unlock() |
735 locker.unlock() |
710 if not noDialog: |
736 if not noDialog: |
722 """ |
748 """ |
723 self.vcsAdd(name, isDir) |
749 self.vcsAdd(name, isDir) |
724 |
750 |
725 def vcsAddTree(self, path): |
751 def vcsAddTree(self, path): |
726 """ |
752 """ |
727 Public method to add a directory tree rooted at path to the Subversion repository. |
753 Public method to add a directory tree rooted at path to the Subversion |
728 |
754 repository. |
729 @param path root directory of the tree to be added (string or list of strings)) |
755 |
|
756 @param path root directory of the tree to be added (string or list of |
|
757 strings)) |
730 """ |
758 """ |
731 tree = [] |
759 tree = [] |
732 if isinstance(path, list): |
760 if isinstance(path, list): |
733 dname, fnames = self.splitPathList(path) |
761 dname, fnames = self.splitPathList(path) |
734 for n in path: |
762 for n in path: |
735 d = os.path.dirname(n) |
763 d = os.path.dirname(n) |
736 if self.__wcng: |
764 if self.__wcng: |
737 repodir = d |
765 repodir = d |
738 while not os.path.isdir(os.path.join(repodir, self.adminDir)): |
766 while not os.path.isdir( |
|
767 os.path.join(repodir, self.adminDir)): |
739 repodir = os.path.dirname(repodir) |
768 repodir = os.path.dirname(repodir) |
740 if os.path.splitdrive(repodir)[1] == os.sep: |
769 if os.path.splitdrive(repodir)[1] == os.sep: |
741 return # oops, project is not version controlled |
770 return # oops, project is not version controlled |
742 while os.path.normcase(d) != os.path.normcase(repodir) and \ |
771 while os.path.normcase(d) != \ |
|
772 os.path.normcase(repodir) and \ |
743 (d not in tree) and \ |
773 (d not in tree) and \ |
744 (os.path.normcase(d) not in self.statusCache or \ |
774 (os.path.normcase(d) not in self.statusCache or \ |
745 self.statusCache[os.path.normcase(d)] == self.canBeAdded): |
775 self.statusCache[os.path.normcase(d)] == |
|
776 self.canBeAdded): |
746 tree.append(d) |
777 tree.append(d) |
747 d = os.path.dirname(d) |
778 d = os.path.dirname(d) |
748 else: |
779 else: |
749 while not os.path.exists(os.path.join(d, self.adminDir)): |
780 while not os.path.exists(os.path.join(d, self.adminDir)): |
750 # add directories recursively, |
781 # add directories recursively, |
760 repodir = dname |
791 repodir = dname |
761 while not os.path.isdir(os.path.join(repodir, self.adminDir)): |
792 while not os.path.isdir(os.path.join(repodir, self.adminDir)): |
762 repodir = os.path.dirname(repodir) |
793 repodir = os.path.dirname(repodir) |
763 if os.path.splitdrive(repodir)[1] == os.sep: |
794 if os.path.splitdrive(repodir)[1] == os.sep: |
764 return # oops, project is not version controlled |
795 return # oops, project is not version controlled |
765 while os.path.normcase(dname) != os.path.normcase(repodir) and \ |
796 while os.path.normcase(dname) != \ |
|
797 os.path.normcase(repodir) and \ |
766 (os.path.normcase(dname) not in self.statusCache or \ |
798 (os.path.normcase(dname) not in self.statusCache or \ |
767 self.statusCache[os.path.normcase(dname)] == self.canBeAdded): |
799 self.statusCache[os.path.normcase(dname)] == |
768 # add directories recursively, if they aren't in the repository already |
800 self.canBeAdded): |
|
801 # add directories recursively, if they aren't in the |
|
802 # repository already |
769 tree.insert(-1, dname) |
803 tree.insert(-1, dname) |
770 dname = os.path.dirname(dname) |
804 dname = os.path.dirname(dname) |
771 else: |
805 else: |
772 while not os.path.exists(os.path.join(dname, self.adminDir)): |
806 while not os.path.exists(os.path.join(dname, self.adminDir)): |
773 # add directories recursively, |
807 # add directories recursively, |
789 opts = self.options['global'] + self.options['add'] |
823 opts = self.options['global'] + self.options['add'] |
790 recurse = True |
824 recurse = True |
791 force = "--force" in opts |
825 force = "--force" in opts |
792 ignore = "--ignore" in opts |
826 ignore = "--ignore" in opts |
793 client = self.getClient() |
827 client = self.getClient() |
794 dlg = \ |
828 dlg = SvnDialog( |
795 SvnDialog( |
829 self.trUtf8('Adding directory trees to the Subversion repository'), |
796 self.trUtf8('Adding directory trees to the Subversion repository'), |
830 "add{0}{1} {2}".format( |
797 "add{0}{1} {2}".format( |
831 force and " --force" or "", |
798 force and " --force" or "", |
832 ignore and " --ignore" or "", |
799 ignore and " --ignore" or "", |
833 " ".join(names)), |
800 " ".join(names)), |
834 client) |
801 client) |
|
802 QApplication.processEvents() |
835 QApplication.processEvents() |
803 try: |
836 try: |
804 client.add(names, recurse=recurse, force=force, ignore=ignore) |
837 client.add(names, recurse=recurse, force=force, ignore=ignore) |
805 except pysvn.ClientError as e: |
838 except pysvn.ClientError as e: |
806 dlg.showError(e.args[0]) |
839 dlg.showError(e.args[0]) |
809 dlg.exec_() |
842 dlg.exec_() |
810 os.chdir(cwd) |
843 os.chdir(cwd) |
811 |
844 |
812 def vcsRemove(self, name, project=False, noDialog=False): |
845 def vcsRemove(self, name, project=False, noDialog=False): |
813 """ |
846 """ |
814 Public method used to remove a file/directory from the Subversion repository. |
847 Public method used to remove a file/directory from the Subversion |
|
848 repository. |
815 |
849 |
816 The default operation is to remove the local copy as well. |
850 The default operation is to remove the local copy as well. |
817 |
851 |
818 @param name file/directory name to be removed (string or list of strings)) |
852 @param name file/directory name to be removed (string or list of |
819 @param project flag indicating deletion of a project tree (boolean) (not needed) |
853 strings)) |
|
854 @param project flag indicating deletion of a project tree (boolean) |
|
855 (not needed) |
820 @param noDialog flag indicating quiet operations |
856 @param noDialog flag indicating quiet operations |
821 @return flag indicating successfull operation (boolean) |
857 @return flag indicating successfull operation (boolean) |
822 """ |
858 """ |
823 if not isinstance(name, list): |
859 if not isinstance(name, list): |
824 name = [name] |
860 name = [name] |
825 opts = self.options['global'] + self.options['remove'] |
861 opts = self.options['global'] + self.options['remove'] |
826 force = "--force" in opts or noDialog |
862 force = "--force" in opts or noDialog |
827 client = self.getClient() |
863 client = self.getClient() |
828 if not noDialog: |
864 if not noDialog: |
829 dlg = \ |
865 dlg = SvnDialog( |
830 SvnDialog( |
866 self.trUtf8('Removing files/directories from the Subversion' |
831 self.trUtf8('Removing files/directories from the Subversion repository'), |
867 ' repository'), |
832 "remove{0} {1}".format( |
868 "remove{0} {1}".format( |
833 force and " --force" or "", |
869 force and " --force" or "", |
834 " ".join(name)), |
870 " ".join(name)), |
835 client) |
871 client) |
836 QApplication.processEvents() |
872 QApplication.processEvents() |
837 locker = QMutexLocker(self.vcsExecutionMutex) |
873 locker = QMutexLocker(self.vcsExecutionMutex) |
838 try: |
874 try: |
839 client.remove(name, force=force) |
875 client.remove(name, force=force) |
840 res = True |
876 res = True |
947 """ |
983 """ |
948 Public method used to view the difference of a file/directory to the |
984 Public method used to view the difference of a file/directory to the |
949 Subversion repository. |
985 Subversion repository. |
950 |
986 |
951 If name is a directory and is the project directory, all project files |
987 If name is a directory and is the project directory, all project files |
952 are saved first. If name is a file (or list of files), which is/are being edited |
988 are saved first. If name is a file (or list of files), which is/are |
953 and has unsaved modification, they can be saved or the operation may be aborted. |
989 being edited and has unsaved modification, they can be saved or the |
|
990 operation may be aborted. |
954 |
991 |
955 @param name file/directory name to be diffed (string) |
992 @param name file/directory name to be diffed (string) |
956 """ |
993 """ |
957 if isinstance(name, list): |
994 if isinstance(name, list): |
958 names = name[:] |
995 names = name[:] |
998 |
1035 |
999 reposURL = self.svnGetReposName(dname) |
1036 reposURL = self.svnGetReposName(dname) |
1000 if reposURL is None: |
1037 if reposURL is None: |
1001 E5MessageBox.critical(self.__ui, |
1038 E5MessageBox.critical(self.__ui, |
1002 self.trUtf8("Subversion Error"), |
1039 self.trUtf8("Subversion Error"), |
1003 self.trUtf8("""The URL of the project repository could not be""" |
1040 self.trUtf8( |
1004 """ retrieved from the working copy. The tag operation will""" |
1041 """The URL of the project repository could not be""" |
1005 """ be aborted""")) |
1042 """ retrieved from the working copy. The tag operation""" |
|
1043 """ will be aborted""")) |
1006 return |
1044 return |
1007 |
1045 |
1008 if self.otherData["standardLayout"]: |
1046 if self.otherData["standardLayout"]: |
1009 url = None |
1047 url = None |
1010 else: |
1048 else: |
1032 |
1070 |
1033 reposRoot = rx_base.cap(1) |
1071 reposRoot = rx_base.cap(1) |
1034 if tagOp in [1, 4]: |
1072 if tagOp in [1, 4]: |
1035 url = '{0}/tags/{1}'.format(reposRoot, urllib.parse.quote(tag)) |
1073 url = '{0}/tags/{1}'.format(reposRoot, urllib.parse.quote(tag)) |
1036 elif tagOp in [2, 8]: |
1074 elif tagOp in [2, 8]: |
1037 url = '{0}/branches/{1}'.format(reposRoot, urllib.parse.quote(tag)) |
1075 url = '{0}/branches/{1}'.format( |
|
1076 reposRoot, urllib.parse.quote(tag)) |
1038 else: |
1077 else: |
1039 url = self.__svnURL(tag) |
1078 url = self.__svnURL(tag) |
1040 |
1079 |
1041 self.tagName = tag |
1080 self.tagName = tag |
1042 client = self.getClient() |
1081 client = self.getClient() |
1043 rev = None |
1082 rev = None |
1044 if tagOp in [1, 2]: |
1083 if tagOp in [1, 2]: |
1045 log = 'Created tag <{0}>'.format(self.tagName) |
1084 log = 'Created tag <{0}>'.format(self.tagName) |
1046 dlg = \ |
1085 dlg = SvnDialog( |
1047 SvnDialog( |
1086 self.trUtf8('Tagging {0} in the Subversion repository') |
1048 self.trUtf8('Tagging {0} in the Subversion repository').format(name), |
1087 .format(name), |
1049 "copy --message {0} {1} {2}".format(log, reposURL, url), |
1088 "copy --message {0} {1} {2}".format(log, reposURL, url), |
1050 client, log=log) |
1089 client, log=log) |
1051 QApplication.processEvents() |
1090 QApplication.processEvents() |
1052 locker = QMutexLocker(self.vcsExecutionMutex) |
1091 locker = QMutexLocker(self.vcsExecutionMutex) |
1053 try: |
1092 try: |
1054 rev = client.copy(reposURL, url) |
1093 rev = client.copy(reposURL, url) |
1055 except pysvn.ClientError as e: |
1094 except pysvn.ClientError as e: |
1056 dlg.showError(e.args[0]) |
1095 dlg.showError(e.args[0]) |
1057 locker.unlock() |
1096 locker.unlock() |
1058 else: |
1097 else: |
1059 log = 'Deleted tag <{0}>'.format(self.tagName) |
1098 log = 'Deleted tag <{0}>'.format(self.tagName) |
1060 dlg = \ |
1099 dlg = SvnDialog( |
1061 SvnDialog( |
1100 self.trUtf8('Tagging {0} in the Subversion repository') |
1062 self.trUtf8('Tagging {0} in the Subversion repository').format(name), |
1101 .format(name), |
1063 "remove --message {0} {1}".format(log, url), |
1102 "remove --message {0} {1}".format(log, url), |
1064 client, log=log) |
1103 client, log=log) |
1065 QApplication.processEvents() |
1104 QApplication.processEvents() |
1066 locker = QMutexLocker(self.vcsExecutionMutex) |
1105 locker = QMutexLocker(self.vcsExecutionMutex) |
1067 try: |
1106 try: |
1068 rev = client.remove(url) |
1107 rev = client.remove(url) |
1069 except pysvn.ClientError as e: |
1108 except pysvn.ClientError as e: |
1087 recurse = True |
1126 recurse = True |
1088 |
1127 |
1089 project = e5App().getObject("Project") |
1128 project = e5App().getObject("Project") |
1090 names = [project.getRelativePath(nam) for nam in name] |
1129 names = [project.getRelativePath(nam) for nam in name] |
1091 if names[0]: |
1130 if names[0]: |
1092 from UI.DeleteFilesConfirmationDialog import DeleteFilesConfirmationDialog |
1131 from UI.DeleteFilesConfirmationDialog import \ |
|
1132 DeleteFilesConfirmationDialog |
1093 dia = DeleteFilesConfirmationDialog(self.parent(), |
1133 dia = DeleteFilesConfirmationDialog(self.parent(), |
1094 self.trUtf8("Revert changes"), |
1134 self.trUtf8("Revert changes"), |
1095 self.trUtf8("Do you really want to revert all changes to these files" |
1135 self.trUtf8( |
1096 " or directories?"), |
1136 "Do you really want to revert all changes to these files" |
|
1137 " or directories?"), |
1097 name) |
1138 name) |
1098 yes = dia.exec_() == QDialog.Accepted |
1139 yes = dia.exec_() == QDialog.Accepted |
1099 else: |
1140 else: |
1100 yes = E5MessageBox.yesNo(None, |
1141 yes = E5MessageBox.yesNo(None, |
1101 self.trUtf8("Revert changes"), |
1142 self.trUtf8("Revert changes"), |
1102 self.trUtf8("""Do you really want to revert all changes of""" |
1143 self.trUtf8("""Do you really want to revert all changes of""" |
1103 """ the project?""")) |
1144 """ the project?""")) |
1104 if yes: |
1145 if yes: |
1105 client = self.getClient() |
1146 client = self.getClient() |
1106 dlg = \ |
1147 dlg = SvnDialog( |
1107 SvnDialog(self.trUtf8('Reverting changes'), |
1148 self.trUtf8('Reverting changes'), |
1108 "revert {0} {1}".format((not recurse) and " --non-recursive" or "", |
1149 "revert {0} {1}".format( |
1109 " ".join(name)), |
1150 (not recurse) and " --non-recursive" or "", |
1110 client) |
1151 " ".join(name)), |
|
1152 client) |
1111 QApplication.processEvents() |
1153 QApplication.processEvents() |
1112 locker = QMutexLocker(self.vcsExecutionMutex) |
1154 locker = QMutexLocker(self.vcsExecutionMutex) |
1113 try: |
1155 try: |
1114 client.revert(name, recurse) |
1156 client.revert(name, recurse) |
1115 except pysvn.ClientError as e: |
1157 except pysvn.ClientError as e: |
1131 |
1173 |
1132 reposURL = self.svnGetReposName(dname) |
1174 reposURL = self.svnGetReposName(dname) |
1133 if reposURL is None: |
1175 if reposURL is None: |
1134 E5MessageBox.critical(self.__ui, |
1176 E5MessageBox.critical(self.__ui, |
1135 self.trUtf8("Subversion Error"), |
1177 self.trUtf8("Subversion Error"), |
1136 self.trUtf8("""The URL of the project repository could not be""" |
1178 self.trUtf8( |
1137 """ retrieved from the working copy. The switch operation will""" |
1179 """The URL of the project repository could not be""" |
1138 """ be aborted""")) |
1180 """ retrieved from the working copy. The switch""" |
|
1181 """ operation will be aborted""")) |
1139 return False |
1182 return False |
1140 |
1183 |
1141 if self.otherData["standardLayout"]: |
1184 if self.otherData["standardLayout"]: |
1142 url = None |
1185 url = None |
1143 else: |
1186 else: |
1166 reposRoot = rx_base.cap(1) |
1209 reposRoot = rx_base.cap(1) |
1167 tn = tag |
1210 tn = tag |
1168 if tagType == 1: |
1211 if tagType == 1: |
1169 url = '{0}/tags/{1}'.format(reposRoot, urllib.parse.quote(tag)) |
1212 url = '{0}/tags/{1}'.format(reposRoot, urllib.parse.quote(tag)) |
1170 elif tagType == 2: |
1213 elif tagType == 2: |
1171 url = '{0}/branches/{1}'.format(reposRoot, urllib.parse.quote(tag)) |
1214 url = '{0}/branches/{1}'.format( |
|
1215 reposRoot, urllib.parse.quote(tag)) |
1172 elif tagType == 4: |
1216 elif tagType == 4: |
1173 url = '{0}/trunk'.format(reposRoot) |
1217 url = '{0}/trunk'.format(reposRoot) |
1174 tn = 'HEAD' |
1218 tn = 'HEAD' |
1175 else: |
1219 else: |
1176 url = self.__svnURL(tag) |
1220 url = self.__svnURL(tag) |
1203 """ |
1247 """ |
1204 dname, fname = self.splitPath(name) |
1248 dname, fname = self.splitPath(name) |
1205 |
1249 |
1206 opts = self.options['global'] |
1250 opts = self.options['global'] |
1207 from .SvnMergeDialog import SvnMergeDialog |
1251 from .SvnMergeDialog import SvnMergeDialog |
1208 dlg = SvnMergeDialog(self.mergeList[0], self.mergeList[1], self.mergeList[2], |
1252 dlg = SvnMergeDialog(self.mergeList[0], self.mergeList[1], |
1209 "--force" in opts) |
1253 self.mergeList[2], "--force" in opts) |
1210 if dlg.exec_() == QDialog.Accepted: |
1254 if dlg.exec_() == QDialog.Accepted: |
1211 urlrev1, urlrev2, target, force = dlg.getParameters() |
1255 urlrev1, urlrev2, target, force = dlg.getParameters() |
1212 else: |
1256 else: |
1213 return |
1257 return |
1214 |
1258 |
1229 if rx_rev.exactMatch(urlrev1): |
1273 if rx_rev.exactMatch(urlrev1): |
1230 if urlrev1 in ["HEAD", "head"]: |
1274 if urlrev1 in ["HEAD", "head"]: |
1231 revision1 = pysvn.Revision(pysvn.opt_revision_kind.head) |
1275 revision1 = pysvn.Revision(pysvn.opt_revision_kind.head) |
1232 rev1 = "HEAD" |
1276 rev1 = "HEAD" |
1233 else: |
1277 else: |
1234 revision1 = \ |
1278 revision1 = pysvn.Revision( |
1235 pysvn.Revision(pysvn.opt_revision_kind.number, int(urlrev1)) |
1279 pysvn.opt_revision_kind.number, int(urlrev1)) |
1236 rev1 = urlrev1 |
1280 rev1 = urlrev1 |
1237 if urlrev2 in ["HEAD", "head"]: |
1281 if urlrev2 in ["HEAD", "head"]: |
1238 revision2 = pysvn.Revision(pysvn.opt_revision_kind.head) |
1282 revision2 = pysvn.Revision(pysvn.opt_revision_kind.head) |
1239 rev2 = "HEAD" |
1283 rev2 = "HEAD" |
1240 else: |
1284 else: |
1241 revision2 = \ |
1285 revision2 = pysvn.Revision( |
1242 pysvn.Revision(pysvn.opt_revision_kind.number, int(urlrev2)) |
1286 pysvn.opt_revision_kind.number, int(urlrev2)) |
1243 rev2 = urlrev2 |
1287 rev2 = urlrev2 |
1244 if not target: |
1288 if not target: |
1245 url1 = name |
1289 url1 = name |
1246 url2 = name |
1290 url2 = name |
1247 else: |
1291 else: |
1257 url1, rev = urlrev1.split("@") |
1301 url1, rev = urlrev1.split("@") |
1258 if rev in ["HEAD", "head"]: |
1302 if rev in ["HEAD", "head"]: |
1259 revision1 = pysvn.Revision(pysvn.opt_revision_kind.head) |
1303 revision1 = pysvn.Revision(pysvn.opt_revision_kind.head) |
1260 rev1 = "HEAD" |
1304 rev1 = "HEAD" |
1261 else: |
1305 else: |
1262 revision1 = \ |
1306 revision1 = pysvn.Revision( |
1263 pysvn.Revision(pysvn.opt_revision_kind.number, int(rev)) |
1307 pysvn.opt_revision_kind.number, int(rev)) |
1264 rev1 = rev |
1308 rev1 = rev |
1265 else: |
1309 else: |
1266 url1 = urlrev1 |
1310 url1 = urlrev1 |
1267 revision1 = pysvn.Revision(pysvn.opt_revision_kind.unspecified) |
1311 revision1 = pysvn.Revision(pysvn.opt_revision_kind.unspecified) |
1268 rev1 = "" |
1312 rev1 = "" |
1270 url2, rev = urlrev2.split("@") |
1314 url2, rev = urlrev2.split("@") |
1271 if rev in ["HEAD", "head"]: |
1315 if rev in ["HEAD", "head"]: |
1272 revision2 = pysvn.Revision(pysvn.opt_revision_kind.head) |
1316 revision2 = pysvn.Revision(pysvn.opt_revision_kind.head) |
1273 rev2 = "HEAD" |
1317 rev2 = "HEAD" |
1274 else: |
1318 else: |
1275 revision2 = \ |
1319 revision2 = pysvn.Revision( |
1276 pysvn.Revision(pysvn.opt_revision_kind.number, int(rev)) |
1320 pysvn.opt_revision_kind.number, int(rev)) |
1277 rev2 = rev |
1321 rev2 = rev |
1278 else: |
1322 else: |
1279 url2 = urlrev2 |
1323 url2 = urlrev2 |
1280 revision2 = pysvn.Revision(pysvn.opt_revision_kind.unspecified) |
1324 revision2 = pysvn.Revision(pysvn.opt_revision_kind.unspecified) |
1281 rev2 = "" |
1325 rev2 = "" |
1315 |
1359 |
1316 def __vcsRegisteredState_wcng(self, name): |
1360 def __vcsRegisteredState_wcng(self, name): |
1317 """ |
1361 """ |
1318 Private method used to get the registered state of a file in the vcs. |
1362 Private method used to get the registered state of a file in the vcs. |
1319 |
1363 |
1320 This is the variant for subversion installations using the new working copy |
1364 This is the variant for subversion installations using the new |
1321 meta-data format. |
1365 working copy meta-data format. |
1322 |
1366 |
1323 @param name filename to check (string) |
1367 @param name filename to check (string) |
1324 @return a combination of canBeCommited and canBeAdded |
1368 @return a combination of canBeCommited and canBeAdded |
1325 """ |
1369 """ |
1326 if name.endswith(os.sep): |
1370 if name.endswith(os.sep): |
1344 |
1388 |
1345 def __vcsRegisteredState_wc(self, name): |
1389 def __vcsRegisteredState_wc(self, name): |
1346 """ |
1390 """ |
1347 Private method used to get the registered state of a file in the vcs. |
1391 Private method used to get the registered state of a file in the vcs. |
1348 |
1392 |
1349 This is the variant for subversion installations using the old working copy |
1393 This is the variant for subversion installations using the old working |
1350 meta-data format. |
1394 copy meta-data format. |
1351 |
1395 |
1352 @param name filename to check (string) |
1396 @param name filename to check (string) |
1353 @return a combination of canBeCommited and canBeAdded |
1397 @return a combination of canBeCommited and canBeAdded |
1354 """ |
1398 """ |
1355 dname, fname = self.splitPath(name) |
1399 dname, fname = self.splitPath(name) |
1368 else: |
1412 else: |
1369 return self.canBeAdded |
1413 return self.canBeAdded |
1370 |
1414 |
1371 def vcsAllRegisteredStates(self, names, dname, shortcut=True): |
1415 def vcsAllRegisteredStates(self, names, dname, shortcut=True): |
1372 """ |
1416 """ |
1373 Public method used to get the registered states of a number of files in the vcs. |
1417 Public method used to get the registered states of a number of files |
1374 |
1418 in the vcs. |
1375 <b>Note:</b> If a shortcut is to be taken, the code will only check, if the named |
1419 |
1376 directory has been scanned already. If so, it is assumed, that the states for |
1420 <b>Note:</b> If a shortcut is to be taken, the code will only check, |
1377 all files has been populated by the previous run. |
1421 if the named directory has been scanned already. If so, it is assumed, |
|
1422 that the states for all files has been populated by the previous run. |
1378 |
1423 |
1379 @param names dictionary with all filenames to be checked as keys |
1424 @param names dictionary with all filenames to be checked as keys |
1380 @param dname directory to check in (string) |
1425 @param dname directory to check in (string) |
1381 @param shortcut flag indicating a shortcut should be taken (boolean) |
1426 @param shortcut flag indicating a shortcut should be taken (boolean) |
1382 @return the received dictionary completed with a combination of |
1427 @return the received dictionary completed with a combination of |
1387 else: |
1432 else: |
1388 return self.__vcsAllRegisteredStates_wc(names, dname, shortcut) |
1433 return self.__vcsAllRegisteredStates_wc(names, dname, shortcut) |
1389 |
1434 |
1390 def __vcsAllRegisteredStates_wcng(self, names, dname, shortcut=True): |
1435 def __vcsAllRegisteredStates_wcng(self, names, dname, shortcut=True): |
1391 """ |
1436 """ |
1392 Private method used to get the registered states of a number of files in the vcs. |
1437 Private method used to get the registered states of a number of files |
1393 |
1438 in the vcs. |
1394 This is the variant for subversion installations using the new working copy |
1439 |
1395 meta-data format. |
1440 This is the variant for subversion installations using the new working |
1396 |
1441 copy meta-data format. |
1397 <b>Note:</b> If a shortcut is to be taken, the code will only check, if the named |
1442 |
1398 directory has been scanned already. If so, it is assumed, that the states for |
1443 <b>Note:</b> If a shortcut is to be taken, the code will only check, |
1399 all files has been populated by the previous run. |
1444 if the named directory has been scanned already. If so, it is assumed, |
|
1445 that the states for all files has been populated by the previous run. |
1400 |
1446 |
1401 @param names dictionary with all filenames to be checked as keys |
1447 @param names dictionary with all filenames to be checked as keys |
1402 @param dname directory to check in (string) |
1448 @param dname directory to check in (string) |
1403 @param shortcut flag indicating a shortcut should be taken (boolean) |
1449 @param shortcut flag indicating a shortcut should be taken (boolean) |
1404 @return the received dictionary completed with a combination of |
1450 @return the received dictionary completed with a combination of |
1464 |
1510 |
1465 return names |
1511 return names |
1466 |
1512 |
1467 def __vcsAllRegisteredStates_wc(self, names, dname, shortcut=True): |
1513 def __vcsAllRegisteredStates_wc(self, names, dname, shortcut=True): |
1468 """ |
1514 """ |
1469 Private method used to get the registered states of a number of files in the vcs. |
1515 Private method used to get the registered states of a number of files |
1470 |
1516 in the VCS. |
1471 This is the variant for subversion installations using the old working copy |
1517 |
1472 meta-data format. |
1518 This is the variant for subversion installations using the old working |
1473 |
1519 copy meta-data format. |
1474 <b>Note:</b> If a shortcut is to be taken, the code will only check, if the named |
1520 |
1475 directory has been scanned already. If so, it is assumed, that the states for |
1521 <b>Note:</b> If a shortcut is to be taken, the code will only check, |
1476 all files has been populated by the previous run. |
1522 if the named directory has been scanned already. If so, it is assumed, |
|
1523 that the states for all files has been populated by the previous run. |
1477 |
1524 |
1478 @param names dictionary with all filenames to be checked as keys |
1525 @param names dictionary with all filenames to be checked as keys |
1479 @param dname directory to check in (string) |
1526 @param dname directory to check in (string) |
1480 @param shortcut flag indicating a shortcut should be taken (boolean) |
1527 @param shortcut flag indicating a shortcut should be taken (boolean) |
1481 @return the received dictionary completed with a combination of |
1528 @return the received dictionary completed with a combination of |
1530 |
1577 |
1531 def vcsInitConfig(self, project): |
1578 def vcsInitConfig(self, project): |
1532 """ |
1579 """ |
1533 Public method to initialize the VCS configuration. |
1580 Public method to initialize the VCS configuration. |
1534 |
1581 |
1535 This method ensures, that eric specific files and directories are ignored. |
1582 This method ensures, that eric specific files and directories are |
|
1583 ignored. |
1536 |
1584 |
1537 @param project reference to the project (Project) |
1585 @param project reference to the project (Project) |
1538 """ |
1586 """ |
1539 configPath = getConfigPath() |
1587 configPath = getConfigPath() |
1540 if os.path.exists(configPath): |
1588 if os.path.exists(configPath): |
1606 """ |
1654 """ |
1607 Public method to get a dialog to enter repository info. |
1655 Public method to get a dialog to enter repository info. |
1608 |
1656 |
1609 @param project reference to the project object |
1657 @param project reference to the project object |
1610 @param archive name of the project in the repository (string) |
1658 @param archive name of the project in the repository (string) |
1611 @param editable flag indicating that the project name is editable (boolean) |
1659 @param editable flag indicating that the project name is editable |
|
1660 (boolean) |
1612 @param parent parent widget (QWidget) |
1661 @param parent parent widget (QWidget) |
|
1662 @return reference to the instantiated options dialog (SvnOptionsDialog) |
1613 """ |
1663 """ |
1614 from .SvnOptionsDialog import SvnOptionsDialog |
1664 from .SvnOptionsDialog import SvnOptionsDialog |
1615 return SvnOptionsDialog(self, project, parent) |
1665 return SvnOptionsDialog(self, project, parent) |
1616 |
1666 |
1617 def vcsNewProjectOptionsDialog(self, parent=None): |
1667 def vcsNewProjectOptionsDialog(self, parent=None): |
1618 """ |
1668 """ |
1619 Public method to get a dialog to enter repository info for getting a new project. |
1669 Public method to get a dialog to enter repository info for getting a |
|
1670 new project. |
1620 |
1671 |
1621 @param parent parent widget (QWidget) |
1672 @param parent parent widget (QWidget) |
|
1673 @return reference to the instantiated options dialog |
|
1674 (SvnNewProjectOptionsDialog) |
1622 """ |
1675 """ |
1623 from .SvnNewProjectOptionsDialog import SvnNewProjectOptionsDialog |
1676 from .SvnNewProjectOptionsDialog import SvnNewProjectOptionsDialog |
1624 return SvnNewProjectOptionsDialog(self, parent) |
1677 return SvnNewProjectOptionsDialog(self, parent) |
1625 |
1678 |
1626 def vcsRepositoryInfos(self, ppath): |
1679 def vcsRepositoryInfos(self, ppath): |
1659 ".".join([str(v) for v in pysvn.svn_version[:3]]), |
1712 ".".join([str(v) for v in pysvn.svn_version[:3]]), |
1660 apiVersion, |
1713 apiVersion, |
1661 entry.url, |
1714 entry.url, |
1662 entry.revision.number, |
1715 entry.revision.number, |
1663 entry.commit_revision.number, |
1716 entry.commit_revision.number, |
1664 time.strftime("%Y-%m-%d", time.localtime(entry.commit_time)), |
1717 time.strftime( |
1665 time.strftime("%H:%M:%S %Z", time.localtime(entry.commit_time)), |
1718 "%Y-%m-%d", time.localtime(entry.commit_time)), |
|
1719 time.strftime( |
|
1720 "%H:%M:%S %Z", time.localtime(entry.commit_time)), |
1666 entry.commit_author |
1721 entry.commit_author |
1667 ) |
1722 ) |
1668 |
1723 |
1669 ############################################################################ |
1724 ########################################################################### |
1670 ## Public Subversion specific methods are below. |
1725 ## Public Subversion specific methods are below. |
1671 ############################################################################ |
1726 ########################################################################### |
1672 |
1727 |
1673 def svnGetReposName(self, path): |
1728 def svnGetReposName(self, path): |
1674 """ |
1729 """ |
1675 Public method used to retrieve the URL of the subversion repository path. |
1730 Public method used to retrieve the URL of the subversion repository |
|
1731 path. |
1676 |
1732 |
1677 @param path local path to get the svn repository path for (string) |
1733 @param path local path to get the svn repository path for (string) |
1678 @return string with the repository path URL |
1734 @return string with the repository path URL |
1679 """ |
1735 """ |
1680 client = pysvn.Client() |
1736 client = pysvn.Client() |
1797 if dlg.exec_() == QDialog.Accepted: |
1853 if dlg.exec_() == QDialog.Accepted: |
1798 propName, propValue, recurse = dlg.getData() |
1854 propName, propValue, recurse = dlg.getData() |
1799 if not propName: |
1855 if not propName: |
1800 E5MessageBox.critical(self.__ui, |
1856 E5MessageBox.critical(self.__ui, |
1801 self.trUtf8("Subversion Set Property"), |
1857 self.trUtf8("Subversion Set Property"), |
1802 self.trUtf8("""You have to supply a property name. Aborting.""")) |
1858 self.trUtf8( |
|
1859 """You have to supply a property name. Aborting.""")) |
1803 return |
1860 return |
1804 |
1861 |
1805 if isinstance(name, list): |
1862 if isinstance(name, list): |
1806 dname, fnames = self.splitPathList(name) |
1863 dname, fnames = self.splitPathList(name) |
1807 else: |
1864 else: |
1849 propName, recurse = dlg.getData() |
1906 propName, recurse = dlg.getData() |
1850 |
1907 |
1851 if not propName: |
1908 if not propName: |
1852 E5MessageBox.critical(self.__ui, |
1909 E5MessageBox.critical(self.__ui, |
1853 self.trUtf8("Subversion Delete Property"), |
1910 self.trUtf8("Subversion Delete Property"), |
1854 self.trUtf8("""You have to supply a property name. Aborting.""")) |
1911 self.trUtf8( |
|
1912 """You have to supply a property name. Aborting.""")) |
1855 return |
1913 return |
1856 |
1914 |
1857 if isinstance(name, list): |
1915 if isinstance(name, list): |
1858 dname, fnames = self.splitPathList(name) |
1916 dname, fnames = self.splitPathList(name) |
1859 else: |
1917 else: |
1902 res = self.tagbranchList.start(path, tags) |
1960 res = self.tagbranchList.start(path, tags) |
1903 if res: |
1961 if res: |
1904 if tags: |
1962 if tags: |
1905 self.tagsList = self.tagbranchList.getTagList() |
1963 self.tagsList = self.tagbranchList.getTagList() |
1906 if not self.showedTags: |
1964 if not self.showedTags: |
1907 self.allTagsBranchesList = self.allTagsBranchesList + self.tagsList |
1965 self.allTagsBranchesList = \ |
|
1966 self.allTagsBranchesList + self.tagsList |
1908 self.showedTags = True |
1967 self.showedTags = True |
1909 elif not tags: |
1968 elif not tags: |
1910 self.branchesList = self.tagbranchList.getTagList() |
1969 self.branchesList = self.tagbranchList.getTagList() |
1911 if not self.showedBranches: |
1970 if not self.showedBranches: |
1912 self.allTagsBranchesList = self.allTagsBranchesList + self.branchesList |
1971 self.allTagsBranchesList = \ |
|
1972 self.allTagsBranchesList + self.branchesList |
1913 self.showedBranches = True |
1973 self.showedBranches = True |
1914 |
1974 |
1915 def svnBlame(self, name): |
1975 def svnBlame(self, name): |
1916 """ |
1976 """ |
1917 Public method to show the output of the svn blame command. |
1977 Public method to show the output of the svn blame command. |
1928 """ |
1988 """ |
1929 Public method used to view the difference of a file/directory to the |
1989 Public method used to view the difference of a file/directory to the |
1930 Subversion repository. |
1990 Subversion repository. |
1931 |
1991 |
1932 If name is a directory and is the project directory, all project files |
1992 If name is a directory and is the project directory, all project files |
1933 are saved first. If name is a file (or list of files), which is/are being edited |
1993 are saved first. If name is a file (or list of files), which is/are |
1934 and has unsaved modification, they can be saved or the operation may be aborted. |
1994 being edited and has unsaved modification, they can be saved or the |
|
1995 operation may be aborted. |
1935 |
1996 |
1936 This method gives the chance to enter the revisions to be compared. |
1997 This method gives the chance to enter the revisions to be compared. |
1937 |
1998 |
1938 @param name file/directory name to be diffed (string) |
1999 @param name file/directory name to be diffed (string) |
1939 """ |
2000 """ |
1964 """ |
2025 """ |
1965 Public method used to view the difference of a file/directory of two |
2026 Public method used to view the difference of a file/directory of two |
1966 repository URLs. |
2027 repository URLs. |
1967 |
2028 |
1968 If name is a directory and is the project directory, all project files |
2029 If name is a directory and is the project directory, all project files |
1969 are saved first. If name is a file (or list of files), which is/are being edited |
2030 are saved first. If name is a file (or list of files), which is/are |
1970 and has unsaved modification, they can be saved or the operation may be aborted. |
2031 being edited and has unsaved modification, they can be saved or the |
|
2032 operation may be aborted. |
1971 |
2033 |
1972 This method gives the chance to enter the revisions to be compared. |
2034 This method gives the chance to enter the revisions to be compared. |
1973 |
2035 |
1974 @param name file/directory name to be diffed (string) |
2036 @param name file/directory name to be diffed (string) |
1975 """ |
2037 """ |
1988 return |
2050 return |
1989 |
2051 |
1990 dname = self.splitPath(names[0])[0] |
2052 dname = self.splitPath(names[0])[0] |
1991 |
2053 |
1992 from .SvnUrlSelectionDialog import SvnUrlSelectionDialog |
2054 from .SvnUrlSelectionDialog import SvnUrlSelectionDialog |
1993 dlg = SvnUrlSelectionDialog(self, self.tagsList, self.branchesList, dname) |
2055 dlg = SvnUrlSelectionDialog(self, self.tagsList, self.branchesList, |
|
2056 dname) |
1994 if dlg.exec_() == QDialog.Accepted: |
2057 if dlg.exec_() == QDialog.Accepted: |
1995 urls, summary = dlg.getURLs() |
2058 urls, summary = dlg.getURLs() |
1996 from .SvnDiffDialog import SvnDiffDialog |
2059 from .SvnDiffDialog import SvnDiffDialog |
1997 self.diff = SvnDiffDialog(self) |
2060 self.diff = SvnDiffDialog(self) |
1998 self.diff.show() |
2061 self.diff.show() |
1999 QApplication.processEvents() |
2062 QApplication.processEvents() |
2000 self.diff.start(name, urls=urls, summary=summary) |
2063 self.diff.start(name, urls=urls, summary=summary) |
2001 |
2064 |
2002 def __svnGetFileForRevision(self, name, rev=""): |
2065 def __svnGetFileForRevision(self, name, rev=""): |
2003 """ |
2066 """ |
2004 Private method to get a file for a specific revision from the repository. |
2067 Private method to get a file for a specific revision from the |
|
2068 repository. |
2005 |
2069 |
2006 @param name file name to get from the repository (string) |
2070 @param name file name to get from the repository (string) |
2007 @keyparam rev revision to retrieve (integer or string) |
2071 @keyparam rev revision to retrieve (integer or string) |
2008 @return contents of the file (string) and an error message (string) |
2072 @return contents of the file (string) and an error message (string) |
2009 """ |
2073 """ |
2012 |
2076 |
2013 client = self.getClient() |
2077 client = self.getClient() |
2014 try: |
2078 try: |
2015 if rev: |
2079 if rev: |
2016 if isinstance(rev, int) or rev.isdecimal(): |
2080 if isinstance(rev, int) or rev.isdecimal(): |
2017 rev = pysvn.Revision(pysvn.opt_revision_kind.number, int(rev)) |
2081 rev = pysvn.Revision( |
|
2082 pysvn.opt_revision_kind.number, int(rev)) |
2018 elif rev.startswith("{"): |
2083 elif rev.startswith("{"): |
2019 dateStr = rev[1:-1] |
2084 dateStr = rev[1:-1] |
2020 secs = QDateTime.fromString(dateStr, Qt.ISODate).toTime_t() |
2085 secs = QDateTime.fromString(dateStr, Qt.ISODate).toTime_t() |
2021 rev = pysvn.Revision(pysvn.opt_revision_kind.date, secs) |
2086 rev = pysvn.Revision(pysvn.opt_revision_kind.date, secs) |
2022 elif rev == "HEAD": |
2087 elif rev == "HEAD": |
2040 |
2105 |
2041 return output, error |
2106 return output, error |
2042 |
2107 |
2043 def svnSbsDiff(self, name, extended=False, revisions=None): |
2108 def svnSbsDiff(self, name, extended=False, revisions=None): |
2044 """ |
2109 """ |
2045 Public method used to view the difference of a file to the Mercurial repository |
2110 Public method used to view the difference of a file to the Mercurial |
2046 side-by-side. |
2111 repository side-by-side. |
2047 |
2112 |
2048 @param name file name to be diffed (string) |
2113 @param name file name to be diffed (string) |
2049 @keyparam extended flag indicating the extended variant (boolean) |
2114 @keyparam extended flag indicating the extended variant (boolean) |
2050 @keyparam revisions tuple of two revisions (tuple of strings) |
2115 @keyparam revisions tuple of two revisions (tuple of strings) |
|
2116 @exception ValueError raised to indicate an invalid name parameter type |
2051 """ |
2117 """ |
2052 if isinstance(name, list): |
2118 if isinstance(name, list): |
2053 raise ValueError("Wrong parameter type") |
2119 raise ValueError("Wrong parameter type") |
2054 |
2120 |
2055 if extended: |
2121 if extended: |
2089 f1.close() |
2155 f1.close() |
2090 name2 = name |
2156 name2 = name |
2091 except IOError: |
2157 except IOError: |
2092 E5MessageBox.critical(self.__ui, |
2158 E5MessageBox.critical(self.__ui, |
2093 self.trUtf8("Subversion Side-by-Side Difference"), |
2159 self.trUtf8("Subversion Side-by-Side Difference"), |
2094 self.trUtf8("""<p>The file <b>{0}</b> could not be read.</p>""") |
2160 self.trUtf8( |
|
2161 """<p>The file <b>{0}</b> could not be read.</p>""") |
2095 .format(name)) |
2162 .format(name)) |
2096 return |
2163 return |
2097 |
2164 |
2098 if self.sbsDiff is None: |
2165 if self.sbsDiff is None: |
2099 from UI.CompareDialog import CompareDialog |
2166 from UI.CompareDialog import CompareDialog |
2117 |
2184 |
2118 def svnLock(self, name, stealIt=False, parent=None): |
2185 def svnLock(self, name, stealIt=False, parent=None): |
2119 """ |
2186 """ |
2120 Public method used to lock a file in the Subversion repository. |
2187 Public method used to lock a file in the Subversion repository. |
2121 |
2188 |
2122 @param name file/directory name to be locked (string or list of strings) |
2189 @param name file/directory name to be locked (string or list of |
|
2190 strings) |
2123 @param stealIt flag indicating a forced operation (boolean) |
2191 @param stealIt flag indicating a forced operation (boolean) |
2124 @param parent reference to the parent object of the subversion dialog (QWidget) |
2192 @param parent reference to the parent object of the subversion dialog |
|
2193 (QWidget) |
2125 """ |
2194 """ |
2126 comment, ok = QInputDialog.getText( |
2195 comment, ok = QInputDialog.getText( |
2127 None, |
2196 None, |
2128 self.trUtf8("Subversion Lock"), |
2197 self.trUtf8("Subversion Lock"), |
2129 self.trUtf8("Enter lock comment"), |
2198 self.trUtf8("Enter lock comment"), |
2164 |
2233 |
2165 def svnUnlock(self, name, breakIt=False, parent=None): |
2234 def svnUnlock(self, name, breakIt=False, parent=None): |
2166 """ |
2235 """ |
2167 Public method used to unlock a file in the Subversion repository. |
2236 Public method used to unlock a file in the Subversion repository. |
2168 |
2237 |
2169 @param name file/directory name to be unlocked (string or list of strings) |
2238 @param name file/directory name to be unlocked (string or list of |
|
2239 strings) |
2170 @param breakIt flag indicating a forced operation (boolean) |
2240 @param breakIt flag indicating a forced operation (boolean) |
2171 @param parent reference to the parent object of the subversion dialog (QWidget) |
2241 @param parent reference to the parent object of the subversion dialog |
|
2242 (QWidget) |
2172 """ |
2243 """ |
2173 if isinstance(name, list): |
2244 if isinstance(name, list): |
2174 dname, fnames = self.splitPathList(name) |
2245 dname, fnames = self.splitPathList(name) |
2175 else: |
2246 else: |
2176 dname, fname = self.splitPath(name) |
2247 dname, fname = self.splitPath(name) |
2223 if dlg.exec_() == QDialog.Accepted: |
2294 if dlg.exec_() == QDialog.Accepted: |
2224 newUrl, inside = dlg.getData() |
2295 newUrl, inside = dlg.getData() |
2225 if inside: |
2296 if inside: |
2226 msg = "switch {0} {1}".format(newUrl, projectPath) |
2297 msg = "switch {0} {1}".format(newUrl, projectPath) |
2227 else: |
2298 else: |
2228 msg = "relocate {0} {1} {2}".format(currUrl, newUrl, projectPath) |
2299 msg = "relocate {0} {1} {2}".format(currUrl, newUrl, |
|
2300 projectPath) |
2229 client = self.getClient() |
2301 client = self.getClient() |
2230 dlg = \ |
2302 dlg = \ |
2231 SvnDialog(self.trUtf8('Relocating'), msg, client) |
2303 SvnDialog(self.trUtf8('Relocating'), msg, client) |
2232 QApplication.processEvents() |
2304 QApplication.processEvents() |
2233 locker = QMutexLocker(self.vcsExecutionMutex) |
2305 locker = QMutexLocker(self.vcsExecutionMutex) |
2321 client) |
2393 client) |
2322 QApplication.processEvents() |
2394 QApplication.processEvents() |
2323 locker = QMutexLocker(self.vcsExecutionMutex) |
2395 locker = QMutexLocker(self.vcsExecutionMutex) |
2324 try: |
2396 try: |
2325 for name in names: |
2397 for name in names: |
2326 client.add_to_changelist(name, clname, depth=pysvn.depth.infinity) |
2398 client.add_to_changelist(name, clname, |
|
2399 depth=pysvn.depth.infinity) |
2327 except pysvn.ClientError as e: |
2400 except pysvn.ClientError as e: |
2328 dlg.showError(e.args[0]) |
2401 dlg.showError(e.args[0]) |
2329 locker.unlock() |
2402 locker.unlock() |
2330 dlg.finish() |
2403 dlg.finish() |
2331 dlg.exec_() |
2404 dlg.exec_() |
2352 client = self.getClient() |
2425 client = self.getClient() |
2353 if hasattr(client, 'get_changelist'): |
2426 if hasattr(client, 'get_changelist'): |
2354 ppath = e5App().getObject("Project").getProjectPath() |
2427 ppath = e5App().getObject("Project").getProjectPath() |
2355 locker = QMutexLocker(self.vcsExecutionMutex) |
2428 locker = QMutexLocker(self.vcsExecutionMutex) |
2356 try: |
2429 try: |
2357 entries = client.get_changelist(ppath, depth=pysvn.depth.infinity) |
2430 entries = client.get_changelist(ppath, |
|
2431 depth=pysvn.depth.infinity) |
2358 for entry in entries: |
2432 for entry in entries: |
2359 changelist = entry[1] |
2433 changelist = entry[1] |
2360 if changelist not in changelists: |
2434 if changelist not in changelists: |
2361 changelists.append(changelist) |
2435 changelists.append(changelist) |
2362 except pysvn.ClientError: |
2436 except pysvn.ClientError: |
2363 pass |
2437 pass |
2364 locker.unlock() |
2438 locker.unlock() |
2365 |
2439 |
2366 return changelists |
2440 return changelists |
2367 |
2441 |
2368 ############################################################################ |
2442 ########################################################################### |
2369 ## Private Subversion specific methods are below. |
2443 ## Private Subversion specific methods are below. |
2370 ############################################################################ |
2444 ########################################################################### |
2371 |
2445 |
2372 def __svnURL(self, url): |
2446 def __svnURL(self, url): |
2373 """ |
2447 """ |
2374 Private method to format a url for subversion. |
2448 Private method to format a url for subversion. |
2375 |
2449 |
2380 url = url.split(':', 2) |
2454 url = url.split(':', 2) |
2381 if len(url) == 3: |
2455 if len(url) == 3: |
2382 scheme = url[0] |
2456 scheme = url[0] |
2383 host = url[1] |
2457 host = url[1] |
2384 port, path = url[2].split("/", 1) |
2458 port, path = url[2].split("/", 1) |
2385 return "{0}:{1}:{2}/{3}".format(scheme, host, port, urllib.parse.quote(path)) |
2459 return "{0}:{1}:{2}/{3}".format(scheme, host, port, |
|
2460 urllib.parse.quote(path)) |
2386 else: |
2461 else: |
2387 scheme = url[0] |
2462 scheme = url[0] |
2388 if scheme == "file": |
2463 if scheme == "file": |
2389 return "{0}:{1}".format(scheme, urllib.parse.quote(url[1])) |
2464 return "{0}:{1}".format(scheme, urllib.parse.quote(url[1])) |
2390 else: |
2465 else: |
2391 try: |
2466 try: |
2392 host, path = url[1][2:].split("/", 1) |
2467 host, path = url[1][2:].split("/", 1) |
2393 except ValueError: |
2468 except ValueError: |
2394 host = url[1][2:] |
2469 host = url[1][2:] |
2395 path = "" |
2470 path = "" |
2396 return "{0}://{1}/{2}".format(scheme, host, urllib.parse.quote(path)) |
2471 return "{0}://{1}/{2}".format(scheme, host, |
|
2472 urllib.parse.quote(path)) |
2397 |
2473 |
2398 def svnNormalizeURL(self, url): |
2474 def svnNormalizeURL(self, url): |
2399 """ |
2475 """ |
2400 Public method to normalize a url for subversion. |
2476 Public method to normalize a url for subversion. |
2401 |
2477 |
2414 url = url[:-1] |
2490 url = url[:-1] |
2415 if not url.startswith("/") and url[1] in [":", "|"]: |
2491 if not url.startswith("/") and url[1] in [":", "|"]: |
2416 url = "/{0}".format(url) |
2492 url = "/{0}".format(url) |
2417 return "{0}://{1}".format(protocol, url) |
2493 return "{0}://{1}".format(protocol, url) |
2418 |
2494 |
2419 ############################################################################ |
2495 ########################################################################### |
2420 ## Methods to get the helper objects are below. |
2496 ## Methods to get the helper objects are below. |
2421 ############################################################################ |
2497 ########################################################################### |
2422 |
2498 |
2423 def vcsGetProjectBrowserHelper(self, browser, project, isTranslationsBrowser=False): |
2499 def vcsGetProjectBrowserHelper(self, browser, project, |
2424 """ |
2500 isTranslationsBrowser=False): |
2425 Public method to instanciate a helper object for the different project browsers. |
2501 """ |
|
2502 Public method to instanciate a helper object for the different |
|
2503 project browsers. |
2426 |
2504 |
2427 @param browser reference to the project browser object |
2505 @param browser reference to the project browser object |
2428 @param project reference to the project object |
2506 @param project reference to the project object |
2429 @param isTranslationsBrowser flag indicating, the helper is requested for the |
2507 @param isTranslationsBrowser flag indicating, the helper is requested |
2430 translations browser (this needs some special treatment) |
2508 for the translations browser (this needs some special treatment) |
2431 @return the project browser helper object |
2509 @return the project browser helper object |
2432 """ |
2510 """ |
2433 from .ProjectBrowserHelper import SvnProjectBrowserHelper |
2511 from .ProjectBrowserHelper import SvnProjectBrowserHelper |
2434 return SvnProjectBrowserHelper(self, browser, project, isTranslationsBrowser) |
2512 return SvnProjectBrowserHelper(self, browser, project, |
|
2513 isTranslationsBrowser) |
2435 |
2514 |
2436 def vcsGetProjectHelper(self, project): |
2515 def vcsGetProjectHelper(self, project): |
2437 """ |
2516 """ |
2438 Public method to instanciate a helper object for the project. |
2517 Public method to instanciate a helper object for the project. |
2439 |
2518 |
2441 @return the project helper object |
2520 @return the project helper object |
2442 """ |
2521 """ |
2443 helper = self.__plugin.getProjectHelper() |
2522 helper = self.__plugin.getProjectHelper() |
2444 helper.setObjects(self, project) |
2523 helper.setObjects(self, project) |
2445 self.__wcng = \ |
2524 self.__wcng = \ |
2446 os.path.exists(os.path.join(project.getProjectPath(), ".svn", "format")) or \ |
2525 os.path.exists( |
2447 os.path.exists(os.path.join(project.getProjectPath(), "_svn", "format")) |
2526 os.path.join(project.getProjectPath(), ".svn", "format")) or \ |
|
2527 os.path.exists( |
|
2528 os.path.join(project.getProjectPath(), "_svn", "format")) |
2448 return helper |
2529 return helper |
2449 |
2530 |
2450 ############################################################################ |
2531 ########################################################################### |
2451 ## Status Monitor Thread methods |
2532 ## Status Monitor Thread methods |
2452 ############################################################################ |
2533 ########################################################################### |
2453 |
2534 |
2454 def _createStatusMonitorThread(self, interval, project): |
2535 def _createStatusMonitorThread(self, interval, project): |
2455 """ |
2536 """ |
2456 Protected method to create an instance of the VCS status monitor thread. |
2537 Protected method to create an instance of the VCS status monitor |
2457 |
2538 thread. |
|
2539 |
|
2540 @param interval check interval for the monitor thread in seconds |
|
2541 (integer) |
2458 @param project reference to the project object |
2542 @param project reference to the project object |
2459 @param interval check interval for the monitor thread in seconds (integer) |
|
2460 @return reference to the monitor thread (QThread) |
2543 @return reference to the monitor thread (QThread) |
2461 """ |
2544 """ |
2462 from .SvnStatusMonitorThread import SvnStatusMonitorThread |
2545 from .SvnStatusMonitorThread import SvnStatusMonitorThread |
2463 return SvnStatusMonitorThread(interval, project, self) |
2546 return SvnStatusMonitorThread(interval, project, self) |