jarvis-ai-assistant 0.1.193__py3-none-any.whl → 0.1.194__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of jarvis-ai-assistant might be problematic. Click here for more details.
- jarvis/__init__.py +1 -1
- jarvis/jarvis_agent/__init__.py +34 -41
- jarvis/jarvis_agent/builtin_input_handler.py +26 -4
- jarvis/jarvis_agent/jarvis.py +38 -22
- jarvis/jarvis_agent/main.py +20 -12
- jarvis/jarvis_agent/output_handler.py +7 -7
- jarvis/jarvis_agent/shell_input_handler.py +14 -11
- jarvis/jarvis_code_agent/code_agent.py +91 -85
- jarvis/jarvis_code_agent/lint.py +92 -105
- jarvis/jarvis_code_analysis/checklists/__init__.py +1 -1
- jarvis/jarvis_code_analysis/checklists/c_cpp.py +1 -1
- jarvis/jarvis_code_analysis/checklists/csharp.py +1 -1
- jarvis/jarvis_code_analysis/checklists/data_format.py +1 -1
- jarvis/jarvis_code_analysis/checklists/devops.py +1 -1
- jarvis/jarvis_code_analysis/checklists/docs.py +1 -1
- jarvis/jarvis_code_analysis/checklists/go.py +1 -1
- jarvis/jarvis_code_analysis/checklists/infrastructure.py +1 -1
- jarvis/jarvis_code_analysis/checklists/java.py +1 -1
- jarvis/jarvis_code_analysis/checklists/javascript.py +1 -1
- jarvis/jarvis_code_analysis/checklists/kotlin.py +1 -1
- jarvis/jarvis_code_analysis/checklists/loader.py +51 -35
- jarvis/jarvis_code_analysis/checklists/php.py +1 -1
- jarvis/jarvis_code_analysis/checklists/python.py +1 -1
- jarvis/jarvis_code_analysis/checklists/ruby.py +1 -1
- jarvis/jarvis_code_analysis/checklists/rust.py +1 -1
- jarvis/jarvis_code_analysis/checklists/shell.py +1 -1
- jarvis/jarvis_code_analysis/checklists/sql.py +1 -1
- jarvis/jarvis_code_analysis/checklists/swift.py +1 -1
- jarvis/jarvis_code_analysis/checklists/web.py +1 -1
- jarvis/jarvis_code_analysis/code_review.py +293 -192
- jarvis/jarvis_dev/main.py +73 -56
- jarvis/jarvis_git_details/main.py +29 -33
- jarvis/jarvis_git_squash/main.py +13 -11
- jarvis/jarvis_git_utils/git_commiter.py +12 -3
- jarvis/jarvis_mcp/__init__.py +8 -10
- jarvis/jarvis_mcp/sse_mcp_client.py +182 -205
- jarvis/jarvis_mcp/stdio_mcp_client.py +93 -120
- jarvis/jarvis_mcp/streamable_mcp_client.py +117 -142
- jarvis/jarvis_methodology/main.py +75 -41
- jarvis/jarvis_multi_agent/__init__.py +24 -16
- jarvis/jarvis_multi_agent/main.py +10 -4
- jarvis/jarvis_platform/__init__.py +1 -1
- jarvis/jarvis_platform/base.py +49 -21
- jarvis/jarvis_platform/human.py +5 -3
- jarvis/jarvis_platform/kimi.py +96 -72
- jarvis/jarvis_platform/openai.py +23 -28
- jarvis/jarvis_platform/registry.py +50 -33
- jarvis/jarvis_platform/tongyi.py +16 -10
- jarvis/jarvis_platform/yuanbao.py +197 -144
- jarvis/jarvis_platform_manager/main.py +4 -2
- jarvis/jarvis_smart_shell/main.py +35 -29
- jarvis/jarvis_tools/ask_user.py +8 -16
- jarvis/jarvis_tools/base.py +3 -2
- jarvis/jarvis_tools/chdir.py +7 -19
- jarvis/jarvis_tools/cli/main.py +14 -10
- jarvis/jarvis_tools/code_plan.py +10 -31
- jarvis/jarvis_tools/create_code_agent.py +10 -13
- jarvis/jarvis_tools/create_sub_agent.py +10 -22
- jarvis/jarvis_tools/edit_file.py +98 -76
- jarvis/jarvis_tools/execute_script.py +46 -46
- jarvis/jarvis_tools/file_analyzer.py +22 -34
- jarvis/jarvis_tools/file_operation.py +69 -62
- jarvis/jarvis_tools/generate_new_tool.py +0 -2
- jarvis/jarvis_tools/methodology.py +19 -23
- jarvis/jarvis_tools/read_code.py +35 -35
- jarvis/jarvis_tools/read_webpage.py +7 -16
- jarvis/jarvis_tools/registry.py +63 -30
- jarvis/jarvis_tools/rewrite_file.py +26 -29
- jarvis/jarvis_tools/search_web.py +5 -8
- jarvis/jarvis_tools/virtual_tty.py +133 -122
- jarvis/jarvis_utils/__init__.py +0 -1
- jarvis/jarvis_utils/builtin_replace_map.py +9 -9
- jarvis/jarvis_utils/config.py +59 -32
- jarvis/jarvis_utils/embedding.py +17 -14
- jarvis/jarvis_utils/file_processors.py +16 -9
- jarvis/jarvis_utils/git_utils.py +140 -99
- jarvis/jarvis_utils/globals.py +1 -1
- jarvis/jarvis_utils/input.py +84 -52
- jarvis/jarvis_utils/methodology.py +28 -21
- jarvis/jarvis_utils/output.py +159 -78
- jarvis/jarvis_utils/tag.py +2 -1
- jarvis/jarvis_utils/utils.py +85 -51
- {jarvis_ai_assistant-0.1.193.dist-info → jarvis_ai_assistant-0.1.194.dist-info}/METADATA +314 -230
- jarvis_ai_assistant-0.1.194.dist-info/RECORD +97 -0
- jarvis/jarvis_agent/file_input_handler.py +0 -112
- jarvis/jarvis_event/__init__.py +0 -0
- jarvis_ai_assistant-0.1.193.dist-info/RECORD +0 -99
- {jarvis_ai_assistant-0.1.193.dist-info → jarvis_ai_assistant-0.1.194.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.193.dist-info → jarvis_ai_assistant-0.1.194.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.1.193.dist-info → jarvis_ai_assistant-0.1.194.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.193.dist-info → jarvis_ai_assistant-0.1.194.dist-info}/top_level.txt +0 -0
jarvis/jarvis_utils/git_utils.py
CHANGED
|
@@ -14,8 +14,7 @@ import re
|
|
|
14
14
|
import subprocess
|
|
15
15
|
from typing import Any, Dict, List, Tuple
|
|
16
16
|
|
|
17
|
-
from jarvis.jarvis_utils.config import
|
|
18
|
-
is_confirm_before_apply_patch)
|
|
17
|
+
from jarvis.jarvis_utils.config import get_auto_update, is_confirm_before_apply_patch
|
|
19
18
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
20
19
|
from jarvis.jarvis_utils.utils import user_confirm
|
|
21
20
|
|
|
@@ -42,29 +41,47 @@ def find_git_root(start_dir: str = ".") -> str:
|
|
|
42
41
|
git_root = os.path.abspath(".")
|
|
43
42
|
os.chdir(git_root)
|
|
44
43
|
return git_root
|
|
44
|
+
|
|
45
|
+
|
|
45
46
|
def has_uncommitted_changes() -> bool:
|
|
46
47
|
"""检查Git仓库中是否有未提交的更改
|
|
47
|
-
|
|
48
|
+
|
|
48
49
|
返回:
|
|
49
50
|
bool: 如果有未提交的更改返回True,否则返回False
|
|
50
51
|
"""
|
|
51
52
|
# 静默添加所有更改
|
|
52
|
-
subprocess.run(
|
|
53
|
+
subprocess.run(
|
|
54
|
+
["git", "add", "."], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
|
|
55
|
+
)
|
|
53
56
|
|
|
54
57
|
# 检查工作目录更改
|
|
55
|
-
working_changes =
|
|
56
|
-
|
|
57
|
-
|
|
58
|
+
working_changes = (
|
|
59
|
+
subprocess.run(
|
|
60
|
+
["git", "diff", "--exit-code"],
|
|
61
|
+
stdout=subprocess.DEVNULL,
|
|
62
|
+
stderr=subprocess.DEVNULL,
|
|
63
|
+
).returncode
|
|
64
|
+
!= 0
|
|
65
|
+
)
|
|
58
66
|
|
|
59
67
|
# 检查暂存区更改
|
|
60
|
-
staged_changes =
|
|
61
|
-
|
|
62
|
-
|
|
68
|
+
staged_changes = (
|
|
69
|
+
subprocess.run(
|
|
70
|
+
["git", "diff", "--cached", "--exit-code"],
|
|
71
|
+
stdout=subprocess.DEVNULL,
|
|
72
|
+
stderr=subprocess.DEVNULL,
|
|
73
|
+
).returncode
|
|
74
|
+
!= 0
|
|
75
|
+
)
|
|
63
76
|
|
|
64
77
|
# 静默重置更改
|
|
65
|
-
subprocess.run(
|
|
78
|
+
subprocess.run(
|
|
79
|
+
["git", "reset"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
|
|
80
|
+
)
|
|
66
81
|
|
|
67
82
|
return working_changes or staged_changes
|
|
83
|
+
|
|
84
|
+
|
|
68
85
|
def get_commits_between(start_hash: str, end_hash: str) -> List[Tuple[str, str]]:
|
|
69
86
|
"""获取两个提交哈希值之间的提交列表
|
|
70
87
|
|
|
@@ -78,103 +95,100 @@ def get_commits_between(start_hash: str, end_hash: str) -> List[Tuple[str, str]]
|
|
|
78
95
|
try:
|
|
79
96
|
# 使用git log和pretty格式获取哈希值和信息
|
|
80
97
|
result = subprocess.run(
|
|
81
|
-
[
|
|
98
|
+
["git", "log", f"{start_hash}..{end_hash}", "--pretty=format:%H|%s"],
|
|
82
99
|
stdout=subprocess.PIPE,
|
|
83
100
|
stderr=subprocess.PIPE,
|
|
84
|
-
text=False # 禁用自动文本解码
|
|
101
|
+
text=False, # 禁用自动文本解码
|
|
85
102
|
)
|
|
86
103
|
if result.returncode != 0:
|
|
87
|
-
error_msg = result.stderr.decode(
|
|
104
|
+
error_msg = result.stderr.decode("utf-8", errors="replace")
|
|
88
105
|
PrettyOutput.print(f"获取commit历史失败: {error_msg}", OutputType.ERROR)
|
|
89
106
|
return []
|
|
90
107
|
|
|
91
|
-
output = result.stdout.decode(
|
|
108
|
+
output = result.stdout.decode("utf-8", errors="replace")
|
|
92
109
|
commits = []
|
|
93
110
|
for line in output.splitlines():
|
|
94
|
-
if
|
|
95
|
-
commit_hash, message = line.split(
|
|
111
|
+
if "|" in line:
|
|
112
|
+
commit_hash, message = line.split("|", 1)
|
|
96
113
|
commits.append((commit_hash, message))
|
|
97
114
|
return commits
|
|
98
115
|
|
|
99
116
|
except Exception as e:
|
|
100
117
|
PrettyOutput.print(f"获取commit历史异常: {str(e)}", OutputType.ERROR)
|
|
101
118
|
return []
|
|
102
|
-
|
|
119
|
+
|
|
103
120
|
|
|
104
121
|
# 修改后的获取差异函数
|
|
105
122
|
|
|
106
123
|
|
|
107
124
|
def get_diff() -> str:
|
|
108
125
|
"""使用git获取工作区差异,包括修改和新增的文件内容
|
|
109
|
-
|
|
126
|
+
|
|
110
127
|
返回:
|
|
111
128
|
str: 差异内容或错误信息
|
|
112
129
|
"""
|
|
113
130
|
try:
|
|
114
131
|
# 暂存新增文件
|
|
115
|
-
subprocess.run([
|
|
116
|
-
|
|
132
|
+
subprocess.run(["git", "add", "-N", "."], check=True)
|
|
133
|
+
|
|
117
134
|
# 获取所有差异(包括新增文件)
|
|
118
135
|
result = subprocess.run(
|
|
119
|
-
[
|
|
120
|
-
capture_output=True,
|
|
121
|
-
text=False,
|
|
122
|
-
check=True
|
|
136
|
+
["git", "diff", "HEAD"], capture_output=True, text=False, check=True
|
|
123
137
|
)
|
|
124
|
-
|
|
138
|
+
|
|
125
139
|
# 重置暂存区
|
|
126
|
-
subprocess.run([
|
|
127
|
-
|
|
140
|
+
subprocess.run(["git", "reset"], check=True)
|
|
141
|
+
|
|
128
142
|
try:
|
|
129
|
-
return result.stdout.decode(
|
|
143
|
+
return result.stdout.decode("utf-8")
|
|
130
144
|
except UnicodeDecodeError:
|
|
131
|
-
return result.stdout.decode(
|
|
132
|
-
|
|
145
|
+
return result.stdout.decode("utf-8", errors="replace")
|
|
146
|
+
|
|
133
147
|
except subprocess.CalledProcessError as e:
|
|
134
148
|
return f"获取差异失败: {str(e)}"
|
|
135
149
|
except Exception as e:
|
|
136
150
|
return f"发生意外错误: {str(e)}"
|
|
137
151
|
|
|
138
152
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
153
|
def revert_file(filepath: str) -> None:
|
|
143
154
|
"""增强版git恢复,处理新文件"""
|
|
144
155
|
import subprocess
|
|
156
|
+
|
|
145
157
|
try:
|
|
146
158
|
# 检查文件是否在版本控制中
|
|
147
159
|
result = subprocess.run(
|
|
148
|
-
[
|
|
160
|
+
["git", "ls-files", "--error-unmatch", filepath],
|
|
149
161
|
stderr=subprocess.PIPE,
|
|
150
|
-
text=False # 禁用自动文本解码
|
|
162
|
+
text=False, # 禁用自动文本解码
|
|
151
163
|
)
|
|
152
164
|
if result.returncode == 0:
|
|
153
|
-
subprocess.run([
|
|
154
|
-
'--', filepath], check=True)
|
|
165
|
+
subprocess.run(["git", "checkout", "HEAD", "--", filepath], check=True)
|
|
155
166
|
else:
|
|
156
167
|
if os.path.exists(filepath):
|
|
157
168
|
os.remove(filepath)
|
|
158
|
-
subprocess.run([
|
|
169
|
+
subprocess.run(["git", "clean", "-f", "--", filepath], check=True)
|
|
159
170
|
except subprocess.CalledProcessError as e:
|
|
160
|
-
error_msg = e.stderr.decode(
|
|
171
|
+
error_msg = e.stderr.decode("utf-8", errors="replace") if e.stderr else str(e)
|
|
161
172
|
PrettyOutput.print(f"恢复文件失败: {error_msg}", OutputType.ERROR)
|
|
173
|
+
|
|
174
|
+
|
|
162
175
|
# 修改后的恢复函数
|
|
163
176
|
|
|
164
177
|
|
|
165
178
|
def revert_change() -> None:
|
|
166
179
|
"""恢复所有未提交的修改到HEAD状态"""
|
|
167
180
|
import subprocess
|
|
181
|
+
|
|
168
182
|
try:
|
|
169
183
|
# 检查是否为空仓库
|
|
170
184
|
head_check = subprocess.run(
|
|
171
|
-
[
|
|
185
|
+
["git", "rev-parse", "--verify", "HEAD"],
|
|
172
186
|
stderr=subprocess.PIPE,
|
|
173
|
-
stdout=subprocess.PIPE
|
|
187
|
+
stdout=subprocess.PIPE,
|
|
174
188
|
)
|
|
175
189
|
if head_check.returncode == 0:
|
|
176
|
-
subprocess.run([
|
|
177
|
-
subprocess.run([
|
|
190
|
+
subprocess.run(["git", "reset", "--hard", "HEAD"], check=True)
|
|
191
|
+
subprocess.run(["git", "clean", "-fd"], check=True)
|
|
178
192
|
except subprocess.CalledProcessError as e:
|
|
179
193
|
PrettyOutput.print(f"恢复更改失败: {str(e)}", OutputType.ERROR)
|
|
180
194
|
|
|
@@ -185,30 +199,30 @@ def handle_commit_workflow() -> bool:
|
|
|
185
199
|
Returns:
|
|
186
200
|
bool: 提交是否成功
|
|
187
201
|
"""
|
|
188
|
-
if is_confirm_before_apply_patch() and not user_confirm(
|
|
202
|
+
if is_confirm_before_apply_patch() and not user_confirm(
|
|
203
|
+
"是否要提交代码?", default=True
|
|
204
|
+
):
|
|
189
205
|
revert_change()
|
|
190
206
|
return False
|
|
191
|
-
|
|
207
|
+
|
|
192
208
|
import subprocess
|
|
209
|
+
|
|
193
210
|
try:
|
|
194
211
|
# 获取当前分支的提交总数
|
|
195
212
|
commit_result = subprocess.run(
|
|
196
|
-
[
|
|
197
|
-
capture_output=True,
|
|
198
|
-
text=True
|
|
213
|
+
["git", "rev-list", "--count", "HEAD"], capture_output=True, text=True
|
|
199
214
|
)
|
|
200
215
|
if commit_result.returncode != 0:
|
|
201
216
|
return False
|
|
202
|
-
|
|
217
|
+
|
|
203
218
|
commit_count = int(commit_result.stdout.strip())
|
|
204
|
-
|
|
219
|
+
|
|
205
220
|
# 暂存所有修改
|
|
206
|
-
subprocess.run([
|
|
207
|
-
|
|
221
|
+
subprocess.run(["git", "add", "."], check=True)
|
|
222
|
+
|
|
208
223
|
# 提交变更
|
|
209
224
|
subprocess.run(
|
|
210
|
-
[
|
|
211
|
-
check=True
|
|
225
|
+
["git", "commit", "-m", f"CheckPoint #{commit_count + 1}"], check=True
|
|
212
226
|
)
|
|
213
227
|
return True
|
|
214
228
|
except subprocess.CalledProcessError as e:
|
|
@@ -224,24 +238,30 @@ def get_latest_commit_hash() -> str:
|
|
|
224
238
|
try:
|
|
225
239
|
# 首先检查是否存在HEAD引用
|
|
226
240
|
head_check = subprocess.run(
|
|
227
|
-
[
|
|
241
|
+
["git", "rev-parse", "--verify", "HEAD"],
|
|
228
242
|
stdout=subprocess.PIPE,
|
|
229
243
|
stderr=subprocess.PIPE,
|
|
230
|
-
text=False
|
|
244
|
+
text=False,
|
|
231
245
|
)
|
|
232
246
|
if head_check.returncode != 0:
|
|
233
247
|
return "" # 空仓库或无效HEAD
|
|
234
248
|
|
|
235
249
|
# 获取HEAD的完整哈希值
|
|
236
250
|
result = subprocess.run(
|
|
237
|
-
[
|
|
251
|
+
["git", "rev-parse", "HEAD"],
|
|
238
252
|
stdout=subprocess.PIPE,
|
|
239
253
|
stderr=subprocess.PIPE,
|
|
240
|
-
text=False
|
|
254
|
+
text=False,
|
|
255
|
+
)
|
|
256
|
+
return (
|
|
257
|
+
result.stdout.decode("utf-8", errors="replace").strip()
|
|
258
|
+
if result.returncode == 0
|
|
259
|
+
else ""
|
|
241
260
|
)
|
|
242
|
-
return result.stdout.decode('utf-8', errors='replace').strip() if result.returncode == 0 else ""
|
|
243
261
|
except Exception:
|
|
244
262
|
return ""
|
|
263
|
+
|
|
264
|
+
|
|
245
265
|
def get_modified_line_ranges() -> Dict[str, Tuple[int, int]]:
|
|
246
266
|
"""从Git差异中获取所有更改文件的修改行范围
|
|
247
267
|
|
|
@@ -274,18 +294,16 @@ def get_modified_line_ranges() -> Dict[str, Tuple[int, int]]:
|
|
|
274
294
|
return result
|
|
275
295
|
|
|
276
296
|
|
|
277
|
-
|
|
278
297
|
def is_file_in_git_repo(filepath: str) -> bool:
|
|
279
298
|
"""检查文件是否在当前Git仓库中"""
|
|
280
299
|
import subprocess
|
|
300
|
+
|
|
281
301
|
try:
|
|
282
302
|
# 获取Git仓库根目录
|
|
283
303
|
repo_root = subprocess.run(
|
|
284
|
-
[
|
|
285
|
-
capture_output=True,
|
|
286
|
-
text=True
|
|
304
|
+
["git", "rev-parse", "--show-toplevel"], capture_output=True, text=True
|
|
287
305
|
).stdout.strip()
|
|
288
|
-
|
|
306
|
+
|
|
289
307
|
# 检查文件路径是否在仓库根目录下
|
|
290
308
|
return os.path.abspath(filepath).startswith(os.path.abspath(repo_root))
|
|
291
309
|
except:
|
|
@@ -316,25 +334,49 @@ def check_and_update_git_repo(repo_path: str) -> bool:
|
|
|
316
334
|
# 获取远程tag更新
|
|
317
335
|
subprocess.run(["git", "fetch", "--tags"], cwd=git_root, check=True)
|
|
318
336
|
# 获取最新本地tag
|
|
319
|
-
local_tag_result = subprocess.run(
|
|
320
|
-
|
|
337
|
+
local_tag_result = subprocess.run(
|
|
338
|
+
["git", "describe", "--tags", "--abbrev=0"],
|
|
339
|
+
cwd=git_root,
|
|
340
|
+
capture_output=True,
|
|
341
|
+
text=True,
|
|
342
|
+
)
|
|
321
343
|
# 获取最新远程tag
|
|
322
344
|
remote_tag_result = subprocess.run(
|
|
323
345
|
["git", "ls-remote", "--tags", "--refs", "origin"],
|
|
324
|
-
cwd=git_root,
|
|
346
|
+
cwd=git_root,
|
|
347
|
+
capture_output=True,
|
|
348
|
+
text=True,
|
|
325
349
|
)
|
|
326
350
|
if remote_tag_result.returncode == 0:
|
|
327
351
|
# 提取最新的tag名称
|
|
328
352
|
tags = [ref.split("/")[-1] for ref in remote_tag_result.stdout.splitlines()]
|
|
329
|
-
tags = sorted(
|
|
353
|
+
tags = sorted(
|
|
354
|
+
tags,
|
|
355
|
+
key=lambda x: [
|
|
356
|
+
int(i) if i.isdigit() else i for i in re.split(r"([0-9]+)", x)
|
|
357
|
+
],
|
|
358
|
+
)
|
|
330
359
|
remote_tag = tags[-1] if tags else ""
|
|
331
360
|
remote_tag_result.stdout = remote_tag
|
|
332
361
|
|
|
333
|
-
if (
|
|
334
|
-
local_tag_result.
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
362
|
+
if (
|
|
363
|
+
local_tag_result.returncode == 0
|
|
364
|
+
and remote_tag_result.returncode == 0
|
|
365
|
+
and local_tag_result.stdout.strip() != remote_tag_result.stdout.strip()
|
|
366
|
+
):
|
|
367
|
+
PrettyOutput.print(
|
|
368
|
+
f"检测到新版本tag {remote_tag_result.stdout.strip()},正在更新Jarvis...",
|
|
369
|
+
OutputType.INFO,
|
|
370
|
+
)
|
|
371
|
+
subprocess.run(
|
|
372
|
+
["git", "checkout", remote_tag_result.stdout.strip()],
|
|
373
|
+
cwd=git_root,
|
|
374
|
+
check=True,
|
|
375
|
+
)
|
|
376
|
+
PrettyOutput.print(
|
|
377
|
+
f"Jarvis已更新到tag {remote_tag_result.stdout.strip()}",
|
|
378
|
+
OutputType.SUCCESS,
|
|
379
|
+
)
|
|
338
380
|
return True
|
|
339
381
|
return False
|
|
340
382
|
except Exception as e:
|
|
@@ -346,30 +388,30 @@ def check_and_update_git_repo(repo_path: str) -> bool:
|
|
|
346
388
|
|
|
347
389
|
def get_diff_file_list() -> List[str]:
|
|
348
390
|
"""获取HEAD到当前变更的文件列表,包括修改和新增的文件
|
|
349
|
-
|
|
391
|
+
|
|
350
392
|
返回:
|
|
351
393
|
List[str]: 修改和新增的文件路径列表
|
|
352
394
|
"""
|
|
353
395
|
try:
|
|
354
396
|
# 暂存新增文件
|
|
355
|
-
subprocess.run([
|
|
356
|
-
|
|
397
|
+
subprocess.run(["git", "add", "-N", "."], check=True)
|
|
398
|
+
|
|
357
399
|
# 获取所有差异文件(包括新增文件)
|
|
358
400
|
result = subprocess.run(
|
|
359
|
-
[
|
|
360
|
-
capture_output=True,
|
|
361
|
-
text=True
|
|
401
|
+
["git", "diff", "--name-only", "HEAD"], capture_output=True, text=True
|
|
362
402
|
)
|
|
363
|
-
|
|
403
|
+
|
|
364
404
|
# 重置暂存区
|
|
365
|
-
subprocess.run([
|
|
366
|
-
|
|
405
|
+
subprocess.run(["git", "reset"], check=True)
|
|
406
|
+
|
|
367
407
|
if result.returncode != 0:
|
|
368
|
-
PrettyOutput.print(
|
|
408
|
+
PrettyOutput.print(
|
|
409
|
+
f"获取差异文件列表失败: {result.stderr}", OutputType.ERROR
|
|
410
|
+
)
|
|
369
411
|
return []
|
|
370
|
-
|
|
412
|
+
|
|
371
413
|
return [f for f in result.stdout.splitlines() if f]
|
|
372
|
-
|
|
414
|
+
|
|
373
415
|
except subprocess.CalledProcessError as e:
|
|
374
416
|
PrettyOutput.print(f"获取差异文件列表失败: {str(e)}", OutputType.ERROR)
|
|
375
417
|
return []
|
|
@@ -378,10 +420,9 @@ def get_diff_file_list() -> List[str]:
|
|
|
378
420
|
return []
|
|
379
421
|
|
|
380
422
|
|
|
381
|
-
|
|
382
423
|
def get_recent_commits_with_files() -> List[Dict[str, Any]]:
|
|
383
424
|
"""获取最近5次提交的commit信息和文件清单
|
|
384
|
-
|
|
425
|
+
|
|
385
426
|
返回:
|
|
386
427
|
List[Dict[str, Any]]: 包含commit信息和文件清单的字典列表,格式为:
|
|
387
428
|
[
|
|
@@ -399,9 +440,9 @@ def get_recent_commits_with_files() -> List[Dict[str, Any]]:
|
|
|
399
440
|
try:
|
|
400
441
|
# 获取最近5次提交的基本信息
|
|
401
442
|
result = subprocess.run(
|
|
402
|
-
[
|
|
443
|
+
["git", "log", "-5", "--pretty=format:%H%n%s%n%an%n%ad"],
|
|
403
444
|
capture_output=True,
|
|
404
|
-
text=True
|
|
445
|
+
text=True,
|
|
405
446
|
)
|
|
406
447
|
if result.returncode != 0:
|
|
407
448
|
return []
|
|
@@ -413,26 +454,26 @@ def get_recent_commits_with_files() -> List[Dict[str, Any]]:
|
|
|
413
454
|
if i + 3 >= len(lines):
|
|
414
455
|
break
|
|
415
456
|
commit = {
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
457
|
+
"hash": lines[i],
|
|
458
|
+
"message": lines[i + 1],
|
|
459
|
+
"author": lines[i + 2],
|
|
460
|
+
"date": lines[i + 3],
|
|
461
|
+
"files": [],
|
|
421
462
|
}
|
|
422
463
|
commits.append(commit)
|
|
423
464
|
|
|
424
465
|
# 获取每个提交的文件修改清单
|
|
425
466
|
for commit in commits:
|
|
426
467
|
files_result = subprocess.run(
|
|
427
|
-
[
|
|
468
|
+
["git", "show", "--name-only", "--pretty=format:", commit["hash"]],
|
|
428
469
|
capture_output=True,
|
|
429
|
-
text=True
|
|
470
|
+
text=True,
|
|
430
471
|
)
|
|
431
472
|
if files_result.returncode == 0:
|
|
432
473
|
files = list(set(filter(None, files_result.stdout.splitlines())))
|
|
433
|
-
commit[
|
|
474
|
+
commit["files"] = files[:20] # 限制最多20个文件
|
|
434
475
|
|
|
435
476
|
return commits
|
|
436
477
|
|
|
437
478
|
except subprocess.CalledProcessError:
|
|
438
|
-
return []
|
|
479
|
+
return []
|