src/eric7/Plugins/VcsPlugins/vcsGit/GitStatusMonitorThread.py

branch
eric7
changeset 9209
b99e7fd55fd3
parent 8881
54e42bc2437a
child 9221
bf71ee032bb4
equal deleted inserted replaced
9208:3fc8dfeb6ebe 9209:b99e7fd55fd3
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2014 - 2022 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the VCS status monitor thread class for Git.
8 """
9
10 from PyQt6.QtCore import QProcess
11
12 from VCS.StatusMonitorThread import VcsStatusMonitorThread
13
14 import Preferences
15
16
17 class GitStatusMonitorThread(VcsStatusMonitorThread):
18 """
19 Class implementing the VCS status monitor thread class for Git.
20 """
21 ConflictStates = ["AA", "AU", "DD", "DU", "UA", "UD", "UU"]
22
23 def __init__(self, interval, project, vcs, parent=None):
24 """
25 Constructor
26
27 @param interval new interval in seconds (integer)
28 @param project reference to the project object (Project)
29 @param vcs reference to the version control object
30 @param parent reference to the parent object (QObject)
31 """
32 VcsStatusMonitorThread.__init__(self, interval, project, vcs, parent)
33
34 self.__ioEncoding = Preferences.getSystem("IOEncoding")
35
36 self.__client = None
37 self.__useCommandLine = False
38
39 def _performMonitor(self):
40 """
41 Protected method implementing the monitoring action.
42
43 This method populates the statusList member variable
44 with a list of strings giving the status in the first column and the
45 path relative to the project directory starting with the third column.
46 The allowed status flags are:
47 <ul>
48 <li>"A" path was added but not yet committed</li>
49 <li>"M" path has local changes</li>
50 <li>"O" path was removed</li>
51 <li>"R" path was deleted and then re-added</li>
52 <li>"U" path needs an update</li>
53 <li>"Z" path contains a conflict</li>
54 <li>"?" path is not tracked</li>
55 <li>"!" path is missing</li>
56 <li>" " path is back at normal</li>
57 </ul>
58
59 @return tuple of flag indicating successful operation (boolean) and
60 a status message in case of non successful operation (string)
61 """
62 self.shouldUpdate = False
63
64 # step 1: get overall status
65 args = self.vcs.initCommand("status")
66 args.append('--porcelain')
67
68 output = ""
69 error = ""
70 process = QProcess()
71 process.setWorkingDirectory(self.projectDir)
72 process.start('git', args)
73 procStarted = process.waitForStarted(5000)
74 if procStarted:
75 finished = process.waitForFinished(300000)
76 if finished and process.exitCode() == 0:
77 output = str(process.readAllStandardOutput(),
78 self.__ioEncoding, 'replace')
79 else:
80 process.kill()
81 process.waitForFinished()
82 error = str(process.readAllStandardError(),
83 self.__ioEncoding, 'replace')
84 else:
85 process.kill()
86 process.waitForFinished()
87 error = self.tr("Could not start the Git process.")
88
89 if error:
90 return False, error
91
92 states = {}
93 for line in output.splitlines():
94 flags = line[:2]
95 name = line[3:].split(" -> ")[-1]
96 if flags in self.ConflictStates:
97 states[name] = "Z"
98 if flags[0] in "AMDR":
99 if flags[0] == "D":
100 status = "O"
101 elif flags[0] == "R":
102 status = "A"
103 else:
104 status = flags[0]
105 states[name] = status
106 elif flags[1] in "MD":
107 if flags[1] == "D":
108 status = "O"
109 else:
110 status = flags[1]
111 states[name] = status
112 elif flags == "??":
113 states[name] = "?"
114
115 # step 2: collect the status to be reported back
116 for name in states:
117 try:
118 if self.reportedStates[name] != states[name]:
119 self.statusList.append(
120 "{0} {1}".format(states[name], name))
121 except KeyError:
122 self.statusList.append("{0} {1}".format(states[name], name))
123 for name in self.reportedStates:
124 if name not in states:
125 self.statusList.append(" {0}".format(name))
126 self.reportedStates = states
127
128 return (
129 True,
130 self.tr("Git status checked successfully")
131 )
132
133 def _getInfo(self):
134 """
135 Protected method implementing the real info action.
136
137 This method should be overridden and create a short info message to be
138 shown in the main window status bar right next to the status indicator.
139
140 @return short info message
141 @rtype str
142 """
143 args = self.vcs.initCommand("show")
144 args.append("--abbrev-commit")
145 args.append("--format=%h %D")
146 args.append("--no-patch")
147
148 output = ""
149 process = QProcess()
150 process.setWorkingDirectory(self.projectDir)
151 process.start('git', args)
152 procStarted = process.waitForStarted(5000)
153 if procStarted:
154 finished = process.waitForFinished(30000)
155 if finished and process.exitCode() == 0:
156 output = str(process.readAllStandardOutput(),
157 Preferences.getSystem("IOEncoding"),
158 'replace')
159
160 if output:
161 commitId, refs = output.splitlines()[0].strip().split(None, 1)
162 ref = refs.split(",", 1)[0]
163 if "->" in ref:
164 branch = ref.split("->", 1)[1].strip()
165 else:
166 branch = self.tr("<detached>")
167
168 return self.tr("{0} / {1}", "branch, commit").format(
169 branch, commitId)
170 else:
171 return ""
172
173 def _shutdown(self):
174 """
175 Protected method performing shutdown actions.
176 """
177 if self.__client:
178 self.__client.stopServer()

eric ide

mercurial