Files
obsidian-vault/family/documents/vault-sync/2026-09-26-commit-skip-pipefail.md
T

102 lines
5.4 KiB
Markdown
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: sync-vault-lib.sh — pipefail + grep -q молча пропускал коммиты (492 файла застряли)
type: log
namespace: family
tags: [vault, sync, git, sync-script, pipefail, bug, fixed]
date: 2026-09-26
---
# `git status --porcelain | grep -q .` под `set -o pipefail` = коммиты молча не создаются
**Когда:** 2026-09-26 09:53 UTC, найдено и починено в cron-тике Taiga.
**Статус:** **фикс применён** (`/opt/data/sync-vault-lib.sh`), синк проверен.
## Симптом
Каждый тик печатал `Pushed ✓` ×3 и `Already up to date.`, exit 0, три SHA равны —
но рабочий каталог `/obsidian-syncthing` **не очищался**, и в нём накопилось
**492 изменения**, включая реальную правку пользователя:
- 491 файл — смена режима `100644 → 100755` (класс «mode-flip», см.
`2026-09-26-mode-flip-644-755.md`), включая папки `personal/` 199, `family/` 166, `work/` 108;
- `personal/plans/music-tags-review/1-needs-decision.md` — 4 чекбокса `- [ ]` → `- [x]`
(пользователь отмечал разобранные треки, вероятно с телефона).
То есть правки телефона **не доезжали до bare**, пока в клоне было мало изменений —
коммит делался; как только изменений становилось много, коммит перестал создаваться вообще.
## Причина
В `/opt/data/sync-vault-lib.sh`:
```bash
set -euo pipefail
...
if git status --porcelain | grep -q .; then # ← вот это
git add -A 2>/dev/null || true
...
git commit ... || true
else
true # ← «нечего коммитить», молча
fi
```
`grep -q` выходит сразу после первого совпадения. При большом выводе `git status`
(492 записи ≈ **23 КБ**) он продолжает писать в уже закрытый pipe, получает `SIGPIPE`,
и **`pipefail` объявляет весь pipeline упавшим (exit 141)**. `if` уходит в `else` —
ветка коммита не выполняется вообще. Ошибка полностью безмолвная: stderr у
`add`/`commit` погашен, `Pushed ✓` печатается как ни в чём не бывало.
Порог — размер вывода: у коммита из 2 файлов (09:44:37) условие было истинным,
у 492 файлов — ложным.
**Доказательство (воспроизведение):**
```bash
cd /obsidian-syncthing
bash -c 'set -euo pipefail; if git status --porcelain | grep -q .; then echo IF=TRUE; else echo IF=FALSE; fi'
# → IF=FALSE (492 записи)
bash -c 'set -eu; if git status --porcelain | grep -q .; then echo IF=TRUE; else echo IF=FALSE; fi'
# → IF=TRUE (то же состояние, без pipefail)
```
## Фикс
```bash
STATUS="$(git status --porcelain 2>/dev/null || true)" # подстановка не даёт SIGPIPE
if [ -n "$STATUS" ]; then
git add -A 2>/dev/null || true
MSG="$(printf '%s\n' "$STATUS" | awk 'NF{n++; if(n<=25) printf "%s ", $2} END{if(n>25) printf "(... +%d more)", n-25}' || true)"
git commit -m "[$STAMP] $LABEL: $MSG" 2>/dev/null || true
fi
```
Две правки в одном месте:
1. **условие** через `$( )` вместо `| grep -q` — нет пайпа, нет SIGPIPE;
2. **сообщение коммита** собирается одним `awk` (читает вход целиком) — раньше при массовом
flip в сообщение и в `/tmp/vault-sync.log` попадали все ~500 путей; теперь первые 25 + `(... +N more)`.
⚠️ Не заменять на `awk ... | head -25 | tr ...`: `head` рвёт пайп, `awk` получает SIGPIPE,
подстановка падает под `set -e` — тик завершается `exit 141` (проверено, первая версия фикса
так и падала).
## Проверка после фикса
```
синк: exit 0, Pushed ✓ ×3
bare = /vault = /obsidian-syncthing = 041885fa
git status --porcelain пуст в обоих клонах, маркеров конфликта 0
Push failed 0, Fetch failed 4 (все исторические, тик 09:40 до origin-guard)
safe.directory 3 записи (без дублей), insteadOf 2 (без дублей)
коммит 12a7566e: 492 файла, сообщение "... (+467 more)"
чекбоксы [x] в bare HEAD и в /vault = 8 → правка телефона доехала
```
## Связанное
- `2026-09-26-syncthing-clone-origin-url-flip.md` — flip `origin` в клоне (guard уже вшит)
- `2026-09-26-syncthing-clone-root-objects-acl-confusion.md` — root-объекты и ACL (разбор
другой сессии, решения за Alex): там же симптом «документ не доехал до телефона»
- `2026-09-26-mode-flip-644-755.md` — откуда берутся `100644 → 100755`
- `family/how-to/vault-git-sync.md`, skill `vault-sync-infrastructure`