6.6 KiB
Executable File
tags, date
| tags | date | ||||
|---|---|---|---|---|---|
|
2026-09-26 |
2026-09-26 — Флип origin у клона /obsidian-syncthing (Syncthing переписал .git/config)
Симптом
Первый за всю историю лога (21646 строк) провал fetch в тике 09:40:31:
[2026-09-26 09:40:31] [syncthing] Fetch failed (origin offline?) — skipping merge/push
[2026-09-26 09:40:31] [taiga-vault] Pushed ✓
[2026-09-26 09:40:31] [syncthing-out] Fetch failed (origin offline?) — skipping merge/push
Тик завершался exit 0 (graceful skip в sync-vault-lib.sh), поэтому cron-задача
рапортовала «успех», хотя фазы 1 и 3 не выполнялись вообще:
- фаза 1 (
syncthing): правки с телефона коммитились локально, но не доезжали до bare; - фаза 3 (
syncthing-out): правки агента/Eagle не доезжали до клона → и дальше по Syncthing не уходили на телефон.
Состояние на момент обнаружения: bare и /vault = 5c939ed8, /obsidian-syncthing
= 66d4d626 (отстал на один коммит Eagle), git status --porcelain пуст в обоих,
маркеров конфликта 0. Данные не потеряны — git идемпотентен, отставание догоняется
одним прогоном.
Причина
remote.origin.url клона /obsidian-syncthing оказался
/mnt/RED_2TB/storage/git/obsidian-vault.git
— хост-путь, которого в контейнере hermes-taiga нет (/mnt пуст, mount-ов на
/mnt/RED_2TB нет; bare смонтирован как /vault.git). Проба вручную:
$ git -C /obsidian-syncthing fetch origin main
fatal: '/mnt/RED_2TB/storage/git/obsidian-vault.git' does not appear to be a git repository
До 09:35:33 фаза 1 успешно фетчила и мерджила (reflog клона: merge origin/main: Fast-forward в 09:06, 09:12, 09:25, 09:35), а в 09:36:19 файл .git/config был
перезаписан — mtime == ctime == 2026-09-26 09:36:19, владелец uid 950 (наши git-процессы
в контейнере пишут файлы клона как root: index, ORIG_HEAD, refs/remotes/origin/main
— root, а сам config — 950:950, -rw-rw----). Значит записал внешний процесс,
а не наш контейнер.
Это тот же механизм, что и .sync-conflict-файлы внутри .git (от 2026-05-29:
config.sync-conflict-…, index.sync-conflict-…, FETCH_HEAD.sync-conflict-…):
каталог .git клона /obsidian-syncthing сам синкается Syncthing'ом с других
устройств. Старая конфликт-копия конфига (2026-05-15) содержит совсем другой remote —
телефонный:
[remote "origin"] url = https://git.mallexxx.duckdns.org/git_admin/obsidian-vault.git
[user] name = alex phone S25
То есть у клона периодически «прилетает» origin с чужого устройства, и внутри
контейнера этот адрес не резолвится. Сегодня прилетел хост-путь.
Что сделано (Taiga, 2026-09-26 09:42–09:43 UTC)
-
Клону вернули контейнерно-корректный remote:
origin = file:///vault.git(тот же bare, что и у/vault). -
В
/opt/data/sync-vault.shдобавлен идемпотентный guard (рядом с блокамиsafe.directoryи git identity) — он выполняется в начале каждого тика:- если
remote.origin.urlклона ≠file:///vault.git→git remote set-url origin file:///vault.git; - в глобальный конфиг (
/root/.gitconfig) добавляется правило перезаписиurl."file:///vault.git".insteadOfдля обоих известных чужих адресов (хост-путь/mnt/RED_2TB/storage/git/obsidian-vault.gitи Gitea-URLhttps://git.mallexxx.duckdns.org/git_admin/obsidian-vault.git) — на случай, если Syncthing перепишет конфиг посреди тика, уже после guard'а.
Побочных эффектов нет: других репозиториев, использующих эти два адреса, в контейнере нет (проверено
grepпо git-конфигам). - если
Проверка (после правки)
bash -n /opt/data/sync-vault.sh→ syntax OK;- три прогона, все
exit 0,Pushed ✓×3, новыхFetch failedнет (в логе остались только 4 исторические строки тика 09:40); - три SHA равны:
bare=/vault=/obsidian-syncthing=3edbddf5; git status --porcelainпуст в обоих клонах, маркеров конфликта 0,Push failed0;- idempotency guard'а: два прогона подряд → правила
insteadOfне дублируются (2 шт.); - функциональный тест перезаписи: временный клон с
origin = /mnt/RED_2TB/storage/git/obsidian-vault.git→git fetch origin mainпроходит (REWRITE_OK), т.е. даже чужой адрес теперь разрешается в локальный bare.
Осталось за владельцем (Taiga молча не делает)
- Корень класса —
.gitклона/obsidian-syncthingсинкается Syncthing'ом между устройствами (отсюда и.sync-conflict-*внутри.git, и флип remote'а). Правильное лечение — исключить.git/из синка этого folder'а на стороне Syncthing (.stignoreв корне folder'а или в конфиге демона). Это правка чужой инфраструктуры, решение Алексея. Пока guard вsync-vault.shдержит fetch рабочим независимо от содержимого.git/config. - Конфиги
/root/.gitconfigи/opt/data/sync-vault.shживут в контейнере: скрипт персистентен (/opt/data= ZFS), глобальный конфиг — нет, но он пересоздаётся при каждом тике самим скриптом.