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 ############################################################################ |