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