You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-up to the push-all batching work: batch-deleting remote-only
files via the sync status panel's checkbox multi-select was still N
separate commits (SyncStatusView.performRemoteDeletion looped
gitService.deleteFile once per file).
- Add optional GitServiceInterface.deleteBatch, mirroring pushBatch.
GitHub/Gitea implement it via the git blob->tree->commit->ref Data
API, reusing resolveGitHubStyleBaseTree/resolveBaseTree and
commitGitHubStyleTree (widened its tree-item sha type to
string | null -- a null sha removes that path from the resulting
tree, GitHub's way of expressing a delete at the tree level).
GitLab implements it via the same Commits API endpoint pushBatch
already uses, with action: 'delete' entries.
- SyncStatusView.performRemoteDeletion now calls deleteBatch once per
chunk (MAX_BATCH_PUSH_SIZE, reused from the push work) when the
provider supports it; a failed chunk marks every path in it as
failed rather than dropping results silently. The original per-file
loop is preserved verbatim as performRemoteDeletionSequential, the
fallback for providers without deleteBatch.
Local deletion is unaffected -- it's a local vault operation, not a
git commit.
Evidence: npx eslint . -> 0 errors; npm run build -> clean;
npx vitest run -> 339/339 passed.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
"description": "Follow-up to feat-011: batch-deleting remote-only files via the sync status panel's checkbox multi-select was still N separate commits (SyncStatusView.performRemoteDeletion looped gitService.deleteFile per file). Added optional GitServiceInterface.deleteBatch, mirroring pushBatch: GitHub/Gitea via the git blob->tree->commit->ref Data API (a tree entry with sha:null removes that path); GitLab via the same Commits API actions array used for pushBatch, with action:'delete'. SyncStatusView.performRemoteDeletion now calls deleteBatch once (chunked at MAX_BATCH_PUSH_SIZE) when the provider supports it, falling back to the original sequential per-file performRemoteDeletionSequential otherwise",
"_evidenceStyle": "Keep evidence to one line: commit hash + short pointer (e.g. 'Commit abc1234 - added X, tests pass'). Debugging narrative and design discussion belong in the commit message, not this file."
Copy file name to clipboardExpand all lines: progress.md
+14-4Lines changed: 14 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,9 +12,9 @@ Completed work is archived in [archive/](./archive/), one file per calendar mont
12
12
13
13
## Current State
14
14
15
-
**Last Updated:** 2026-07-14 10:10
15
+
**Last Updated:** 2026-07-14 10:30
16
16
**Session ID:** current
17
-
**Active Feature:** feat-011 (perf: batch-commit push-all + SHA-based diffing) — done, lint/build/test all green. Previous active item (issue #78 delete-remote-only-file fix) still awaiting user re-test after rebuild.
17
+
**Active Feature:** feat-012 (perf: batch-commit remote-only file deletion) — done, lint/build/test all green. feat-011 (push-all batching) also done this session. Previous active item (issue #78 delete-remote-only-file fix) still awaiting user re-test after rebuild.
18
18
19
19
## Status
20
20
@@ -44,15 +44,25 @@ Completed work is archived in [archive/](./archive/), one file per calendar mont
44
44
- Pull path (`pullAllFiles`) intentionally untouched — out of scope, still needs full remote content regardless of sha comparison.
45
45
- Not yet committed as of this note — pending commit onto `claude/fix-directory-symlink-pull-260713`.
46
46
47
+
-[x] feat-012: perf(delete): batch-commit remote-only file deletion. User asked whether batch-deleting remote-only files (checkbox multi-select in the sync status panel) was also one commit; it wasn't (`performRemoteDeletion` looped `gitService.deleteFile` per file). Applied the same batching pattern as feat-011:
48
+
1. New optional `GitServiceInterface.deleteBatch?(paths, branch, commitMessage)`, mirroring `pushBatch?`. No result payload (deletes don't produce a new sha to report back).
49
+
2.`GitHubService`/`GiteaService.deleteBatch` reuse `resolveGitHubStyleBaseTree`/`resolveBaseTree` + `commitGitHubStyleTree` (widened `commitGitHubStyleTree`'s tree-item `sha` type to `string | null` — a `null` sha removes that path from the resulting tree, which is how GitHub's Git Data API expresses a delete at the tree level).
50
+
3.`GitLabService.deleteBatch` reuses the same Commits API endpoint as `pushBatch`, with `action: 'delete'` entries (no `content`/`encoding`).
51
+
4.`src/ui/SyncStatusView.ts`'s `performRemoteDeletion` now calls `deleteBatch` once per chunk (`MAX_BATCH_PUSH_SIZE`, reused from feat-011) when the provider supports it, updating progress per-file during a fast local pass before the grouped network call — same UX pattern as push. The original per-file loop was extracted verbatim into `performRemoteDeletionSequential`, used as the fallback when a provider has no `deleteBatch` (e.g. future Bitbucket). A failed chunk marks every path in it as failed (kept in `fileStatuses`/`selectedFiles`, not silently dropped); earlier successful chunks stay deleted.
52
+
- Local deletion (`performLocalDeletion`) untouched — pure local vault operation, nothing to batch.
53
+
- Added `deleteBatch` tests to `github-service.test.ts`/`gitea-service.test.ts`/`gitlab-service.test.ts` (happy path, empty-array short-circuit) and new `SyncStatusView.test.ts` cases (grouped call, whole-chunk-failure, fallback when `deleteBatch` is absent). Existing vaultFolder-prefix-stripping and real-error-message tests still pass unchanged against the fallback path.
- Not yet committed as of this note — pending commit onto `claude/fix-directory-symlink-pull-260713`.
56
+
47
57
### What's In Progress
48
58
49
59
- Nothing else actively in progress.
50
60
51
61
### What's Next
52
62
53
63
1. Get user confirmation that delete now works (or a new detailed error message) after they rebuild/reload with the latest push (issue #78).
54
-
2. Manually verify feat-011 in Obsidian if possible: push-all on a mixed vault should produce one new commit containing only changed/new files.
55
-
3. Issue #37 (Bitbucket provider support, feat-010) — large, was deferred until #38 (i18n) landed. Now unblocked. Its `GitServiceInterface` implementation should simply omit `pushBatch` and use the existing per-file fallback.
64
+
2. Manually verify feat-011/feat-012 in Obsidian if possible: push-all and batch-delete on a mixed vault should each produce exactly one new commit.
65
+
3. Issue #37 (Bitbucket provider support, feat-010) — large, was deferred until #38 (i18n) landed. Now unblocked. Its `GitServiceInterface` implementation should simply omit `pushBatch`/`deleteBatch` and use the existing per-file fallbacks.
56
66
4. Re-sync against `gh issue list --repo firstsun-dev/git-files-sync --state open`. Remaining genuinely-unstarted issues as of this session: #47 (regex ignore lists), #45 (SonarQube findings), #37 (Bitbucket), #28 (non-engineering: community visibility).
57
67
5. PR #51 is large (8+ issues' worth of changes now). If the user wants to review/merge it before more work piles on, flag this rather than continuing to add commits indefinitely.
0 commit comments