diff --git a/config.go b/config.go
index 46f009d..f83ff7e 100644
--- a/config.go
+++ b/config.go
@@ -28,6 +28,7 @@ type RepoConfig struct {
ConflictStrategy string `json:"conflict_strategy"`
PushStrategy string `json:"push_strategy"`
AutoCommit bool `json:"auto_commit"`
+ AutoSync bool `json:"auto_sync"`
Cron string `json:"cron"`
}
@@ -109,6 +110,8 @@ func loadRepoConfig(dir, name string) (*RepoConfig, error) {
c.ConflictStrategy = orDefault(m["CONFLICT_STRATEGY"], "merge")
c.PushStrategy = orDefault(m["PUSH_STRATEGY"], "manual")
c.AutoCommit = strings.EqualFold(m["AUTO_COMMIT"], "1") || strings.EqualFold(m["AUTO_COMMIT"], "true")
+ // 自动同步默认开启;仅在显式配置 0 / false 时关闭(关闭后不再自动触发,但手动同步仍可用)
+ c.AutoSync = !(strings.EqualFold(m["AUTO_SYNC"], "0") || strings.EqualFold(m["AUTO_SYNC"], "false"))
c.Cron = strings.TrimSpace(m["CRON"])
if remotes := strings.TrimSpace(m["REMOTES"]); remotes != "" {
for _, pair := range strings.Split(remotes, ",") {
@@ -154,8 +157,13 @@ func saveRepoConfig(dir string, c *RepoConfig) error {
if c.AutoCommit {
ac = "1"
}
- fmt.Fprintf(&b, "AUTO_COMMIT=%s\n", q(ac))
- fmt.Fprintf(&b, "CRON=%s\n", q(c.Cron))
+ fmt.Fprintf(&b, "AUTO_COMMIT=%s\n", q(ac))
+ as := "0"
+ if c.AutoSync {
+ as = "1"
+ }
+ fmt.Fprintf(&b, "AUTO_SYNC=%s\n", q(as))
+ fmt.Fprintf(&b, "CRON=%s\n", q(c.Cron))
return os.WriteFile(filepath.Join(dir, c.Name+".conf"), []byte(b.String()), 0o644)
}
diff --git a/engine.go b/engine.go
index 84c54dc..a331ee5 100644
--- a/engine.go
+++ b/engine.go
@@ -75,6 +75,7 @@ type RepoSnapshot struct {
PushStrategy string `json:"push_strategy"`
LogFile string `json:"log_file"`
AutoCommit bool `json:"auto_commit"`
+ AutoSync bool `json:"auto_sync"`
Cron string `json:"cron"`
Remotes []Remote `json:"remotes"`
Running bool `json:"running"`
@@ -273,6 +274,7 @@ func (s *repoState) snapshot(live bool) RepoSnapshot {
PushStrategy: cfg.PushStrategy,
LogFile: cfg.LogFile,
AutoCommit: cfg.AutoCommit,
+ AutoSync: cfg.AutoSync,
Cron: cfg.Cron,
Remotes: cfg.Remotes,
Running: s.running,
@@ -350,7 +352,15 @@ func (e *Engine) loop(s *repoState, stopCh chan struct{}) {
s.mu.Lock()
interval := s.cfg.Interval
cronStr := s.cfg.Cron
+ autoSync := s.cfg.AutoSync
s.mu.Unlock()
+ // 自动同步关闭:不再自动触发,仅保留监控与手动同步能力
+ if !autoSync {
+ e.logf(s, "info", "已关闭自动同步,仅响应手动同步")
+ e.pushStatus(s)
+ <-stopCh
+ return
+ }
if interval < 5 {
interval = 5
}
diff --git a/static/app.js b/static/app.js
index c4d80a8..3f7226c 100644
--- a/static/app.js
+++ b/static/app.js
@@ -161,6 +161,7 @@ function card(r) {
${r.cron ? `cron` : ''}
${r.conflicts && r.conflicts.length ? `冲突 ${r.conflicts.length}` : ''}
${r.push_conflict ? `推送冲突` : ''}
+ ${r.running && r.auto_sync === false ? `手动模式` : ''}
${r.running && r.last_sync && isStale(r.last_sync.time) ? '久未同步' : ''}
上次同步:${esc(last)}
@@ -1024,6 +1025,7 @@ function fillForm(r) {
$('#f-retry').value = r ? r.retry_count : 3;
$('#f-retry-interval').value = r ? r.retry_interval : 5;
$('#f-autocommit').checked = r ? !!r.auto_commit : false;
+ $('#f-autosync').checked = r ? (r.auto_sync !== false) : true;
$('#f-cron').value = r ? (r.cron || '') : '';
$('#f-log').value = r ? (r.log_file || '') : '';
previewCron();
@@ -1050,6 +1052,7 @@ function readForm() {
conflict_strategy: $('#f-conflict').value,
push_strategy: $('#f-push').value,
auto_commit: $('#f-autocommit').checked,
+ auto_sync: $('#f-autosync').checked,
cron: $('#f-cron').value.trim(),
log_file: $('#f-log').value.trim(),
};
diff --git a/static/index.html b/static/index.html
index 00e772b..dd4d599 100644
--- a/static/index.html
+++ b/static/index.html
@@ -127,15 +127,15 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
@@ -197,6 +197,10 @@
自动提交模式:检测到未提交改动时自动 commit,并随同步推送到远程
+