reconcile: harden replayLocalOntoRemote against merge commits + empty commits
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 68/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 静か
- 技術スタック
- git, typescript
調査の方向性
apps/api/src/store/reconcile.ts の replayLocalOntoRemote から始め、次に apps/api/tests/data-repo-reconcile.test.ts にある既存の調整ケースを読みます。提案された結果を使って、ローカルのマージコミットと空のコミットのカバレッジを追加し、そのテストファイルを実行します。マージコミットがハッシュとともに競合ログに残り、空のコミットが書き換え後の履歴に存在しなければ完了です。
索引モデルが issue の本文から書いたものです。
説明
Background
PR #86's replayLocalOntoRemote (in apps/api/src/store/reconcile.ts) replaces git rebase with a per-commit merge-tree --write-tree + commit-tree loop. The plan's Risks section flags two edge cases that the implementation accepts silently rather than guarding against:
1. Merge commits get silently flattened
'commit-tree', mergedTreeHash, '-p', newTip, '-m', message
Single -p parent. If a multi-parent commit ever appears in localCommits, the replay collapses it into a single-parent commit. git rebase by default refuses to replay merges (errors out); --rebase-merges preserves them.
Risk: the data repo today is all programmatic single-parent gitsheets transacts, so this never fires. But if a human or a future automation ever lands a merge commit on the data repo, reconcile would silently drop one of the parents and rewrite history in a misleading way.
2. Empty commits are preserved instead of dropped
git commit-tree <existing-tree> happily writes a commit even when the resulting tree equals the parent's tree (no diff). Modern git rebase drops empty commits by default (--no-empty). The replay loop currently writes them through.
Risk: an empty commit (programmatically possible if a gitsheets transact does nothing but still commits) gets preserved across reconcile, making history noisier than git rebase would produce.
Proposed hardening
In replayLocalOntoRemote:
- Reject merge commits early. Before the loop, check each commit's parent count via
git rev-list --parentsorgit cat-file -p <commit> | head -1. If any commit has>1parent, throwRebaseReplayConflictError(routes to the escape-hatch) with a clear message. Operator can then investigate the unexpected merge commit onconflicts/<UTC>. - Skip empty commits. Before calling
commit-tree, comparemergedTreeHashto the new tip's tree (git show <newTip> --format=%T -s). If equal, skip the commit and continue withnewTipunchanged.
Both checks are cheap. The merge-commit guard is the more important one (data loss avoidance); the empty-commit skip is purely a history-cleanliness improvement.
Tests to add
In apps/api/tests/data-repo-reconcile.test.ts:
- New case: diverged-with-merge-commit-on-local → expect
outcome: 'conflict-escaped'with the merge commit's hash mentioned in the conflict log. - New case: diverged-with-empty-commit-on-local → expect
outcome: 'rebased', empty commit dropped from the rewritten history.
Why post-cutover
Neither edge case is reachable from current code paths (no merge commits, no empty-commit-producing transacts). Filing as hardening rather than a bug fix.
Filed as follow-up from PR #86.
- 主要言語
- TypeScript
- スター
- 1
- フォーク
- 1
- 平均マージ
- 1日 20時間
- マージ済み PR(30日)
- 25
コントリビューションガイド
このリポジトリのコントリビューションガイドは索引されていません
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
CodeForPhilly/codeforphilly-ng のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
-
MarkdownEditor toolbar: use Radix Toolbar from radix-ui instead of the hand-rolled roving tabindex オープンenhancement
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
CodeForPhilly/codeforphilly-ng の issue をすべて見る
似ている issue
-
bug(cli): hapi doctor inline-media prints a fabricated B:\ helper-script path in packaged installs オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
-
Crush オープン
難易度 1/5 1時間未満 初心者へのやさしさ 85/100
catppuccin/catppuccin#3125 ·
-
Add a SECURITY.md オープン
難易度 1/5 1時間未満 初心者へのやさしさ 90/100
ElementsProject/cln-application#167 · コメント 1 件 · リアクション 1 件 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
Quantco/pnpm-licenses#17 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100