diff --git a/index.html b/index.html
index 4891b2f..f85f42e 100644
--- a/index.html
+++ b/index.html
@@ -243,24 +243,38 @@
const lastCommitData = await this.apiRequest(`/git/commits/${lastCommitSha}`);
const baseTreeSha = lastCommitData.tree.sha;
- const treePayload = [];
+ // Deduplicate changes by path to prevent GitRPC::BadObjectState
+ const finalChanges = new Map();
this.pendingChanges.forEach(change => {
const mode = change.itemType === 'tree' ? '040000' : '100644';
if (change.type === 'delete') {
- treePayload.push({ path: change.path, mode, type: change.itemType, sha: null });
+ finalChanges.set(change.path, { path: change.path, mode, type: change.itemType, sha: null });
} else if (change.type === 'rename' || change.type === 'move') {
- treePayload.push({ path: change.oldPath, mode, type: change.itemType, sha: null });
- treePayload.push({ path: change.path, mode, type: change.itemType, sha: change.sha });
+ finalChanges.set(change.oldPath, { path: change.oldPath, mode, type: change.itemType, sha: null });
+ finalChanges.set(change.path, { path: change.path, mode, type: change.itemType, sha: change.sha });
} else if (change.type === 'add') {
- if (change.sha) {
- treePayload.push({ path: change.path, mode, type: change.itemType, sha: change.sha });
- } else {
- treePayload.push({ path: change.path, mode, type: change.itemType, content: '\n' });
- }
+ const entry = { path: change.path, mode, type: change.itemType };
+ if (change.sha) entry.sha = change.sha;
+ else entry.content = '\n';
+ finalChanges.set(change.path, entry);
}
});
+ // Optimization: If a parent folder is being deleted, don't explicitly delete children
+ const pathsToDelete = Array.from(finalChanges.values())
+ .filter(c => c.sha === null)
+ .map(c => c.path)
+ .sort((a, b) => a.length - b.length);
+
+ const treePayload = Array.from(finalChanges.values()).filter(change => {
+ if (change.sha === null) {
+ const hasParentDeleted = pathsToDelete.some(p => change.path.startsWith(p + '/') && change.path !== p);
+ return !hasParentDeleted;
+ }
+ return true;
+ });
+
const newTree = await this.apiRequest('/git/trees', 'POST', {
base_tree: baseTreeSha,
tree: treePayload