Plugins/VcsPlugins/vcsSubversion/subversion.py

changeset 1576
72e5b4b8bad7
parent 1509
c0b5e693b0eb
child 1588
dccffd13be8d
equal deleted inserted replaced
1572:5900e71055ea 1576:72e5b4b8bad7
125 self.statusCache = {} 125 self.statusCache = {}
126 126
127 self.__commitData = {} 127 self.__commitData = {}
128 self.__commitDialog = None 128 self.__commitDialog = None
129 129
130 self.__wcng = True # assume new generation working copy metadata format
131
130 def getPlugin(self): 132 def getPlugin(self):
131 """ 133 """
132 Public method to get a reference to the plugin object. 134 Public method to get a reference to the plugin object.
133 135
134 @return reference to the plugin object (VcsSubversionPlugin) 136 @return reference to the plugin object (VcsSubversionPlugin)
568 dname, fname = os.path.split(name) 570 dname, fname = os.path.split(name)
569 else: 571 else:
570 dname, fname = self.splitPath(name) 572 dname, fname = self.splitPath(name)
571 tree = [] 573 tree = []
572 wdir = dname 574 wdir = dname
573 while not os.path.exists(os.path.join(dname, self.adminDir)): 575 if self.__wcng:
574 # add directories recursively, if they aren't in the repository already 576 repodir = dname
575 tree.insert(-1, dname) 577 while not os.path.isdir(os.path.join(repodir, self.adminDir)):
576 dname = os.path.split(dname)[0] 578 repodir = os.path.dirname(repodir)
577 wdir = dname 579 if os.path.splitdrive(repodir)[1] == os.sep:
580 return # oops, project is not version controlled
581 while os.path.normcase(dname) != os.path.normcase(repodir) and \
582 (os.path.normcase(dname) not in self.statusCache or \
583 self.statusCache[os.path.normcase(dname)] == self.canBeAdded):
584 # add directories recursively, if they aren't in the repository already
585 tree.insert(-1, dname)
586 dname = os.path.dirname(dname)
587 wdir = dname
588 else:
589 while not os.path.exists(os.path.join(dname, self.adminDir)):
590 # add directories recursively, if they aren't in the repository already
591 tree.insert(-1, dname)
592 dname = os.path.dirname(dname)
593 wdir = dname
578 self.addArguments(args, tree) 594 self.addArguments(args, tree)
579 595
580 if isinstance(name, list): 596 if isinstance(name, list):
581 tree2 = [] 597 tree2 = []
582 for n in name: 598 for n in name:
583 d = os.path.split(n)[0] 599 d = os.path.dirname(n)
584 while not os.path.exists(os.path.join(d, self.adminDir)): 600 if self.__wcng:
585 if d in tree2 + tree: 601 repodir = d
586 break 602 while not os.path.isdir(os.path.join(repodir, self.adminDir)):
587 tree2.append(d) 603 repodir = os.path.dirname(repodir)
588 d = os.path.split(d)[0] 604 if os.path.splitdrive(repodir)[1] == os.sep:
605 return # oops, project is not version controlled
606 while os.path.normcase(d) != os.path.normcase(repodir) and \
607 (d not in tree2 + tree) and \
608 (os.path.normcase(d) not in self.statusCache or \
609 self.statusCache[os.path.normcase(d)] == self.canBeAdded):
610 tree2.append(d)
611 d = os.path.dirname(d)
612 else:
613 while not os.path.exists(os.path.join(d, self.adminDir)):
614 if d in tree2 + tree:
615 break
616 tree2.append(d)
617 d = os.path.dirname(d)
589 tree2.reverse() 618 tree2.reverse()
590 self.addArguments(args, tree2) 619 self.addArguments(args, tree2)
591 self.addArguments(args, name) 620 self.addArguments(args, name)
592 else: 621 else:
593 args.append(name) 622 args.append(name)
624 653
625 tree = [] 654 tree = []
626 if isinstance(path, list): 655 if isinstance(path, list):
627 dname, fnames = self.splitPathList(path) 656 dname, fnames = self.splitPathList(path)
628 for n in path: 657 for n in path:
629 d = os.path.split(n)[0] 658 d = os.path.dirname(n)
630 while not os.path.exists(os.path.join(d, self.adminDir)): 659 if self.__wcng:
660 repodir = d
661 while not os.path.isdir(os.path.join(repodir, self.adminDir)):
662 repodir = os.path.dirname(repodir)
663 if os.path.splitdrive(repodir)[1] == os.sep:
664 return # oops, project is not version controlled
665 while os.path.normcase(d) != os.path.normcase(repodir) and \
666 (d not in tree) and \
667 (os.path.normcase(d) not in self.statusCache or \
668 self.statusCache[os.path.normcase(d)] == self.canBeAdded):
669 tree.append(d)
670 d = os.path.dirname(d)
671 else:
672 while not os.path.exists(os.path.join(d, self.adminDir)):
673 # add directories recursively,
674 # if they aren't in the repository already
675 if d in tree:
676 break
677 tree.append(d)
678 d = os.path.dirname(d)
679 tree.reverse()
680 else:
681 dname, fname = os.path.split(path)
682 if self.__wcng:
683 repodir = dname
684 while not os.path.isdir(os.path.join(repodir, self.adminDir)):
685 repodir = os.path.dirname(repodir)
686 if os.path.splitdrive(repodir)[1] == os.sep:
687 return # oops, project is not version controlled
688 while os.path.normcase(dname) != os.path.normcase(repodir) and \
689 (os.path.normcase(dname) not in self.statusCache or \
690 self.statusCache[os.path.normcase(dname)] == self.canBeAdded):
691 # add directories recursively, if they aren't in the repository already
692 tree.insert(-1, dname)
693 dname = os.path.dirname(dname)
694 else:
695 while not os.path.exists(os.path.join(dname, self.adminDir)):
631 # add directories recursively, 696 # add directories recursively,
632 # if they aren't in the repository already 697 # if they aren't in the repository already
633 if d in tree: 698 tree.insert(-1, dname)
634 break 699 dname = os.path.dirname(dname)
635 tree.append(d)
636 d = os.path.split(d)[0]
637 tree.reverse()
638 else:
639 dname, fname = os.path.split(path)
640 while not os.path.exists(os.path.join(dname, self.adminDir)):
641 # add directories recursively,
642 # if they aren't in the repository already
643 tree.insert(-1, dname)
644 dname = os.path.split(dname)[0]
645 if tree: 700 if tree:
646 self.vcsAdd(tree, True) 701 self.vcsAdd(tree, True)
647 702
648 if isinstance(path, list): 703 if isinstance(path, list):
649 self.addArguments(args, path) 704 self.addArguments(args, path)
1048 Public method used to get the registered state of a file in the vcs. 1103 Public method used to get the registered state of a file in the vcs.
1049 1104
1050 @param name filename to check (string) 1105 @param name filename to check (string)
1051 @return a combination of canBeCommited and canBeAdded 1106 @return a combination of canBeCommited and canBeAdded
1052 """ 1107 """
1108 if self.__wcng:
1109 return self.__vcsRegisteredState_wcng(name)
1110 else:
1111 return self.__vcsRegisteredState_wc(name)
1112
1113 def __vcsRegisteredState_wcng(self, name):
1114 """
1115 Private method used to get the registered state of a file in the vcs.
1116
1117 This is the variant for subversion installations using the new working copy
1118 meta-data format.
1119
1120 @param name filename to check (string)
1121 @return a combination of canBeCommited and canBeAdded
1122 """
1123 if name.endswith(os.sep):
1124 name = name[:-1]
1125 name = os.path.normcase(name)
1126 dname, fname = self.splitPath(name)
1127
1128 if fname == '.' and os.path.isdir(os.path.join(dname, self.adminDir)):
1129 return self.canBeCommitted
1130
1131 if name in self.statusCache:
1132 return self.statusCache[name]
1133
1134 name = os.path.normcase(name)
1135 states = { name : 0 }
1136 states = self.vcsAllRegisteredStates(states, dname, False)
1137 if states[name] == self.canBeCommitted:
1138 return self.canBeCommitted
1139 else:
1140 return self.canBeAdded
1141
1142 def __vcsRegisteredState_wc(self, name):
1143 """
1144 Private method used to get the registered state of a file in the vcs.
1145
1146 This is the variant for subversion installations using the old working copy
1147 meta-data format.
1148
1149 @param name filename to check (string)
1150 @return a combination of canBeCommited and canBeAdded
1151 """
1053 dname, fname = self.splitPath(name) 1152 dname, fname = self.splitPath(name)
1054 1153
1055 if fname == '.': 1154 if fname == '.':
1056 if os.path.isdir(os.path.join(dname, self.adminDir)): 1155 if os.path.isdir(os.path.join(dname, self.adminDir)):
1057 return self.canBeCommitted 1156 return self.canBeCommitted
1076 1175
1077 @param names dictionary with all filenames to be checked as keys 1176 @param names dictionary with all filenames to be checked as keys
1078 @param dname directory to check in (string) 1177 @param dname directory to check in (string)
1079 @param shortcut flag indicating a shortcut should be taken (boolean) 1178 @param shortcut flag indicating a shortcut should be taken (boolean)
1080 @return the received dictionary completed with a combination of 1179 @return the received dictionary completed with a combination of
1180 canBeCommited and canBeAdded or None in order to signal an error
1181 """
1182 if self.__wcng:
1183 return self.__vcsAllRegisteredStates_wcng(names, dname, shortcut)
1184 else:
1185 return self.__vcsAllRegisteredStates_wc(names, dname, shortcut)
1186
1187 def __vcsAllRegisteredStates_wcng(self, names, dname, shortcut = True):
1188 """
1189 Private method used to get the registered states of a number of files in the vcs.
1190
1191 This is the variant for subversion installations using the new working copy
1192 meta-data format.
1193
1194 <b>Note:</b> If a shortcut is to be taken, the code will only check, if the named
1195 directory has been scanned already. If so, it is assumed, that the states for
1196 all files has been populated by the previous run.
1197
1198 @param names dictionary with all filenames to be checked as keys
1199 @param dname directory to check in (string)
1200 @param shortcut flag indicating a shortcut should be taken (boolean)
1201 @return the received dictionary completed with a combination of
1202 canBeCommited and canBeAdded or None in order to signal an error
1203 """
1204 if dname.endswith(os.sep):
1205 dname = dname[:-1]
1206 dname = os.path.normcase(dname)
1207
1208 found = False
1209 for name in self.statusCache.keys():
1210 if name in names:
1211 found = True
1212 names[name] = self.statusCache[name]
1213
1214 if not found:
1215 # find the root of the repo
1216 repodir = dname
1217 while not os.path.isdir(os.path.join(repodir, self.adminDir)):
1218 repodir = os.path.dirname(repodir)
1219 if os.path.splitdrive(repodir)[1] == os.sep:
1220 return names
1221
1222 ioEncoding = str(Preferences.getSystem("IOEncoding"))
1223 process = QProcess()
1224 args = []
1225 args.append('status')
1226 args.append('--verbose')
1227 args.append('--non-interactive')
1228 args.append(dname)
1229 process.start('svn', args)
1230 procStarted = process.waitForStarted()
1231 if procStarted:
1232 finished = process.waitForFinished(30000)
1233 if finished and process.exitCode() == 0:
1234 output = \
1235 str(process.readAllStandardOutput(), ioEncoding, 'replace')
1236 for line in output.splitlines():
1237 if self.rx_status1.exactMatch(line):
1238 flags = str(self.rx_status1.cap(1))
1239 path = self.rx_status1.cap(5).strip()
1240 elif self.rx_status2.exactMatch(line):
1241 flags = str(self.rx_status2.cap(1))
1242 path = self.rx_status2.cap(2).strip()
1243 else:
1244 continue
1245 name = os.path.normcase(path)
1246 if flags[0] not in "?I":
1247 if name in names:
1248 names[name] = self.canBeCommitted
1249 self.statusCache[name] = self.canBeCommitted
1250 else:
1251 self.statusCache[name] = self.canBeAdded
1252
1253 return names
1254
1255 def __vcsAllRegisteredStates_wc(self, names, dname, shortcut = True):
1256 """
1257 Private method used to get the registered states of a number of files in the vcs.
1258
1259 This is the variant for subversion installations using the old working copy
1260 meta-data format.
1261
1262 <b>Note:</b> If a shortcut is to be taken, the code will only check, if the named
1263 directory has been scanned already. If so, it is assumed, that the states for
1264 all files has been populated by the previous run.
1265
1266 @param names dictionary with all filenames to be checked as keys
1267 @param dname directory to check in (string)
1268 @param shortcut flag indicating a shortcut should be taken (boolean)
1269 @return the received dictionary completed with a combination of
1081 canBeCommited and canBeAdded or None in order to signal an error 1270 canBeCommited and canBeAdded or None in order to signal an error
1082 """ 1271 """
1083 if not os.path.isdir(os.path.join(dname, self.adminDir)): 1272 if not os.path.isdir(os.path.join(dname, self.adminDir)):
1084 # not under version control -> do nothing 1273 # not under version control -> do nothing
1085 return names 1274 return names
1816 @param project reference to the project object 2005 @param project reference to the project object
1817 @return the project helper object 2006 @return the project helper object
1818 """ 2007 """
1819 helper = self.__plugin.getProjectHelper() 2008 helper = self.__plugin.getProjectHelper()
1820 helper.setObjects(self, project) 2009 helper.setObjects(self, project)
2010 self.__wcng = \
2011 os.path.exists(os.path.join(project.getProjectPath(), ".svn", "format")) or \
2012 os.path.exists(os.path.join(project.getProjectPath(), "_svn", "format"))
1821 return helper 2013 return helper
1822 2014
1823 ############################################################################ 2015 ############################################################################
1824 ## Status Monitor Thread methods 2016 ## Status Monitor Thread methods
1825 ############################################################################ 2017 ############################################################################

eric ide

mercurial