git-sync-web 自动提交 2026-09-09 13:46:40

This commit is contained in:
tamakyi
2026-09-09 13:46:41 +08:00
parent b921569b72
commit bba6a3362e
7 changed files with 234 additions and 24 deletions
+17 -5
View File
@@ -205,7 +205,8 @@ func (e *Engine) logf(s *repoState, level, format string, args ...any) {
if logPath != "" {
_ = os.MkdirAll(filepath.Dir(logPath), 0o755)
if f, err := os.OpenFile(logPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644); err == nil {
fmt.Fprintln(f, "["+ts+"] "+msg)
// 落盘格式:[时间] [级别] 消息,便于网页端按级别过滤
fmt.Fprintln(f, "["+ts+"] ["+level+"] "+msg)
_ = f.Close()
}
}
@@ -1241,7 +1242,8 @@ func (e *Engine) safeRepoPath(s *repoState, rel string) (string, error) {
// FileNode 文件树节点(网页端)
type FileNode struct {
Path string `json:"path"`
Path string `json:"path"`
Status string `json:"status"` // M 已修改 / A 新增 / D 删除 / ? 未跟踪 / 空 未改动
}
// FileTree 列出仓库内可编辑文件(已跟踪 + 未跟踪且未被忽略),天然避开 .git 内部
@@ -1268,9 +1270,11 @@ func (e *Engine) FileTree(name string) []FileNode {
paths = append(paths, p)
}
sort.Strings(paths)
// 附带每个文件的改动状态(M/A/D/?),便于网页端一眼看出哪些文件被动过
status := changedFiles(s.cfg.RepoPath)
nodes := make([]FileNode, 0, len(paths))
for _, p := range paths {
nodes = append(nodes, FileNode{Path: p})
nodes = append(nodes, FileNode{Path: p, Status: status[p]})
}
return nodes
}
@@ -1373,8 +1377,8 @@ type DiffResult struct {
VsRemote bool `json:"vs_remote"`
}
// WorkingDiff 返回工作区/暂存/全部/与远程的差异
func (e *Engine) WorkingDiff(name, scope string) (*DiffResult, error) {
// WorkingDiff 返回工作区/暂存/全部/与远程的差异;rel 非空时只对比该文件
func (e *Engine) WorkingDiff(name, scope, rel string) (*DiffResult, error) {
s := e.get(name)
if s == nil {
return nil, fmt.Errorf("配置不存在: %s", name)
@@ -1404,6 +1408,14 @@ func (e *Engine) WorkingDiff(name, scope string) (*DiffResult, error) {
} else {
statArgs = append(statArgs, "--stat")
}
// 单文件过滤:追加 -- <path>,先做路径安全校验(防穿越 / .git)
if rel != "" {
if _, err := e.safeRepoPath(s, rel); err != nil {
return nil, err
}
args = append(args, "--", rel)
statArgs = append(statArgs, "--", rel)
}
if statOut, serr := gitRun(s.cfg.RepoPath, 30*time.Second, statArgs...); serr == nil {
statOut = stripWarnings(statOut)
res.Stat = statOut