diff -r e9e7eca7efee -r bf71ee032bb4 src/eric7/Plugins/VcsPlugins/vcsGit/GitDiffGenerator.py --- a/src/eric7/Plugins/VcsPlugins/vcsGit/GitDiffGenerator.py Wed Jul 13 11:16:20 2022 +0200 +++ b/src/eric7/Plugins/VcsPlugins/vcsGit/GitDiffGenerator.py Wed Jul 13 14:55:47 2022 +0200 @@ -20,53 +20,58 @@ class GitDiffGenerator(QObject): """ Class implementing the generation of output of the git diff command. - + @signal finished() emitted when all processes have finished """ + finished = pyqtSignal() - + def __init__(self, vcs, parent=None): """ Constructor - + @param vcs reference to the vcs object @param parent parent widget (QWidget) """ super().__init__(parent) - + self.vcs = vcs - + self.__process = EricOverrideCursorProcess() self.__process.finished.connect(self.__procFinished) self.__process.readyReadStandardOutput.connect( - lambda: self.__readStdout(self.__process)) + lambda: self.__readStdout(self.__process) + ) self.__process.readyReadStandardError.connect( - lambda: self.__readStderr(self.__process)) - + lambda: self.__readStderr(self.__process) + ) + self.__process2 = EricOverrideCursorProcess() self.__process2.finished.connect(self.__procFinished) self.__process2.readyReadStandardOutput.connect( - lambda: self.__readStdout(self.__process2)) + lambda: self.__readStdout(self.__process2) + ) self.__process2.readyReadStandardError.connect( - lambda: self.__readStderr(self.__process2)) - + lambda: self.__readStderr(self.__process2) + ) + def stopProcesses(self): """ Public slot to stop the diff processes. """ for process in [self.__process, self.__process2]: if ( - process is not None and - process.state() != QProcess.ProcessState.NotRunning + process is not None + and process.state() != QProcess.ProcessState.NotRunning ): process.terminate() QTimer.singleShot(2000, process.kill) process.waitForFinished(3000) - + def start(self, fn, versions=None, diffMode="work2repo", stashName=""): """ Public slot to start the git diff command. - + @param fn filename to be diffed (string) @param versions list of versions to be diffed (list of up to 2 strings or None) @@ -82,24 +87,28 @@ @exception ValueError raised to indicate a bad value for the 'diffMode' parameter. """ - if diffMode not in ["work2repo", "work2stage", "stage2repo", - "work2stage2repo", "stash"]: + if diffMode not in [ + "work2repo", + "work2stage", + "stage2repo", + "work2stage2repo", + "stash", + ]: raise ValueError("Bad value for 'diffMode' parameter.") - + self.__output1 = [] self.__output2 = [] self.__errors = [] self.__fileSeparators = [] args2 = [] - + self.__ioEncoding = Preferences.getSystem("IOEncoding") - - if diffMode in ["work2repo", "work2stage", "stage2repo", - "work2stage2repo"]: + + if diffMode in ["work2repo", "work2stage", "stage2repo", "work2stage2repo"]: args = self.vcs.initCommand("diff") args.append("--patch") args.append("--find-copies-harder") - + if versions is not None: for version in versions: if version: @@ -113,7 +122,7 @@ args.append("--cached") elif diffMode == "work2repo": args.append("HEAD") - + args.append("--") if isinstance(fn, list): dname, fnames = self.vcs.splitPathList(fn) @@ -132,60 +141,59 @@ args.append("--patch") if stashName: args.append(stashName) - + # find the root of the repo repodir = dname while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): repodir = os.path.dirname(repodir) if os.path.splitdrive(repodir)[1] == os.sep: return False - + self.__process.kill() self.__process.setWorkingDirectory(repodir) - self.__process.start('git', args) + self.__process.start("git", args) procStarted = self.__process.waitForStarted(5000) if not procStarted: return False - + if diffMode == "work2stage2repo": self.__process2.kill() self.__process2.setWorkingDirectory(repodir) - self.__process2.start('git', args2) + self.__process2.start("git", args2) procStarted = self.__process2.waitForStarted(5000) if not procStarted: return False - + return True - + def __procFinished(self, exitCode, exitStatus): """ Private slot connected to the finished signal. - + @param exitCode exit code of the process (integer) @param exitStatus exit status of the process (QProcess.ExitStatus) """ if ( - self.__process.state() == QProcess.ProcessState.NotRunning and - self.__process2.state() == QProcess.ProcessState.NotRunning + self.__process.state() == QProcess.ProcessState.NotRunning + and self.__process2.state() == QProcess.ProcessState.NotRunning ): self.finished.emit() - + def getResult(self): """ Public method to return the result data. - + @return tuple of lists of string containing lines of the diff, the diff between stage and repo for 'work2stage2repo' mode (empty otherwise), the list of errors and a list of tuples of filenames and the line into the diff output. """ - return (self.__output1, self.__output2, self.__errors, - self.__fileSeparators) - + return (self.__output1, self.__output2, self.__errors, self.__fileSeparators) + def __processFileLine(self, line, isTopDiff): """ Private slot to process a line giving the old/new file. - + @param line line to be processed (string) @param isTopDiff flag indicating to show the output in the top output widget (boolean) @@ -193,57 +201,57 @@ prefix, filenames = line.split(" a/", 1) oldFile, newFile = filenames.split(" b/", 1) if isTopDiff: - self.__fileSeparators.append((oldFile.strip(), newFile.strip(), - len(self.__output1), -2)) + self.__fileSeparators.append( + (oldFile.strip(), newFile.strip(), len(self.__output1), -2) + ) else: - self.__fileSeparators.append((oldFile.strip(), newFile.strip(), - -2, len(self.__output2))) - + self.__fileSeparators.append( + (oldFile.strip(), newFile.strip(), -2, len(self.__output2)) + ) + def __processLine(self, line, isTopDiff): """ Private method to process one line of output. - + @param line output line to process (string) @param isTopDiff flag indicating to show the output in the top output widget (boolean) """ if line.startswith("diff --git"): self.__processFileLine(line, isTopDiff) - + if isTopDiff: self.__output1.append(line) else: self.__output2.append(line) - + def __readStdout(self, process): """ Private slot to handle the readyReadStandardOutput signal. - + It reads the output of the process, formats it and inserts it into the contents pane. - + @param process reference to the process providing output @type QProcess """ process.setReadChannel(QProcess.ProcessChannel.StandardOutput) - + isTopDiff = process == self.__process - + while process.canReadLine(): - line = str(process.readLine(), self.__ioEncoding, - 'replace') + line = str(process.readLine(), self.__ioEncoding, "replace") self.__processLine(line, isTopDiff) - + def __readStderr(self, process): """ Private slot to handle the readyReadStandardError signal. - + It reads the error output of the process and inserts it into the error pane. - + @param process reference to the process providing error output @type QProcess """ - s = str(process.readAllStandardError(), self.__ioEncoding, - 'replace') + s = str(process.readAllStandardError(), self.__ioEncoding, "replace") self.__errors.append(s)