-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcallback_builder.py
More file actions
81 lines (71 loc) · 3.13 KB
/
callback_builder.py
File metadata and controls
81 lines (71 loc) · 3.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import os
from datetime import datetime, timezone, timedelta
class CallbackScriptBuilder:
@staticmethod
def build_bulk_commit_callback(filepath: str, commit_changes: dict) -> bool:
"""
生成 callback 脚本,针对多次提交,每个提交设置独立的 author/email/date/message
"""
try:
import json
changes_json = json.dumps(commit_changes, indent=2, ensure_ascii=False)
content = f'''
from datetime import datetime, timezone, timedelta
commit_changes = {changes_json}
commit_id = commit.original_id.decode()[:7]
if commit_id in commit_changes:
change = commit_changes[commit_id]
commit.author_name = change["name"].encode("utf-8")
commit.author_email = change["email"].encode("utf-8")
commit.committer_name = change["name"].encode("utf-8")
commit.committer_email = change["email"].encode("utf-8")
dt = datetime.strptime(change["date"], "%Y-%m-%dT%H:%M:%S")
dt = dt.replace(tzinfo=timezone(timedelta(hours=8)))
timestamp = int(dt.timestamp())
commit.author_date = f"{{timestamp}} +0800".encode("utf-8")
commit.committer_date = f"{{timestamp}} +0800".encode("utf-8")
commit.message = change["message"].encode("utf-8")
'''
os.makedirs(os.path.dirname(filepath), exist_ok=True)
with open(filepath, "w", encoding="utf-8", newline="\n") as f:
f.write(content.lstrip())
return True
except Exception as e:
print(f"[CallbackScriptBuilder] 错误: {e}")
return False
@staticmethod
def build_single_commit_callback(
filepath: str,
target_hash: str,
author_name: str,
author_email: str,
commit_message: str,
commit_time: datetime
):
"""
生成 callback 脚本(用于 git-filter-repo),只修改一个指定提交
"""
try:
safe_msg = commit_message.replace('"""', r'\"\"\"')
new_dt = datetime(commit_time.year, commit_time.month, commit_time.day, commit_time.hour, commit_time.minute, commit_time.second,
tzinfo=timezone(timedelta(hours=8)))
timestamp = int(new_dt.timestamp())
def encode_line(key: str, value: str) -> str:
return f'commit.{key} = "{value}".encode("utf-8")'
content = f'''
if commit.original_id.decode()[:7] == "{target_hash}":
{encode_line("author_name", author_name)}
{encode_line("author_email", author_email)}
{encode_line("committer_name", author_name)}
{encode_line("committer_email", author_email)}
commit.message = "{safe_msg}".encode("utf-8")
commit.author_date = f"{timestamp} +0800".encode("utf-8") # 格式化为字节
commit.committer_date = f"{timestamp} +0800".encode("utf-8") # 格式化为字节
'''
os.makedirs(os.path.dirname(filepath), exist_ok=True)
with open(filepath, "w", encoding="utf-8", newline="\n") as f:
f.write(content)
return True
except Exception as e:
print(f"CallbackScriptBuilder 错误: {e}")
return False