Skip to content

[Bug] Plugin leaks memory and crashes Obsidian when initializing large vault repos#24

Open
crypdick wants to merge 1 commit into
silvanocerza:mainfrom
crypdick:fix/crashing-large-repo
Open

[Bug] Plugin leaks memory and crashes Obsidian when initializing large vault repos#24
crypdick wants to merge 1 commit into
silvanocerza:mainfrom
crypdick:fix/crashing-large-repo

Conversation

@crypdick
Copy link
Copy Markdown

When initializing a vault with many files, the plugin extracts every ZIP entry at once. This crashes Obsidian repeatedly on my Pixel 9 Pro. This PR switches the extraction to a simple for loop so that the files are handled one at a time.

Comment thread src/sync-manager.ts
}
// Process entries sequentially to avoid loading many files in memory at once
// which can crash Obsidian when initializing a large Obsidian repository.
for (const entry of entries) {
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Github is being dumb and making the diff look bigger than it actually is. The only real change is on this line, as well as changing a few return to continue

@kj-9
Copy link
Copy Markdown

kj-9 commented Jul 9, 2025

+1 for this PR, works great on my Android☺️

@TheAsphaltDevil
Copy link
Copy Markdown

When initializing a vault with many files, the plugin extracts every ZIP entry at once. This crashes Obsidian repeatedly on my Pixel 9 Pro. This PR switches the extraction to a simple for loop so that the files are handled one at a time.

Hi, I tried making a fork of this so I could try it in obsidian, and I still get a crash when trying to sync my vault. Did I do something wrong, or is my vault just too large even for this? It has around a few hundred notes.

agungwas added a commit to agungwas/github-gitless-sync that referenced this pull request May 14, 2026
- fix(sync): process ZIP entries sequentially to prevent memory exhaustion
  on large vaults during initial sync from remote (refs silvanocerza#24)

- fix(sync): add null guard before setting sha on delete_remote tree item
  to prevent TypeError on mobile when file entry is missing (refs silvanocerza#52, silvanocerza#28)

- fix(sync): use SHA as primary truth in determineSyncActions instead of
  timestamps, preventing files modified by plugins or external tools from
  being silently skipped on sync

- fix(sync): correct inverted syncConfigDir condition in ZIP extraction
  that caused .obsidian folder to be skipped when config sync was enabled

- fix(sync): auto-reconcile config dir files into metadata on loadMetadata
  when syncConfigDir is true, so users no longer need to toggle the setting
  after enabling it

- fix(sync): recover from stale blob SHAs by falling back to current tree
  SHA on 404 responses, preventing sync failures after force-pushes (refs silvanocerza#58)

- fix(sync): exclude volatile sync artifacts (github-sync.log) from
  metadata and conflict detection to prevent recurring false conflicts

- fix(sync): reconcile remote metadata SHAs with live tree on each sync
  to remove stale references before conflict detection runs

- fix(sync): add null guards on metadataStore.data.files before setting
  sha to prevent TypeError on new files not yet in local metadata
dbdeveloper added a commit to dbdeveloper/github-easy-sync that referenced this pull request May 23, 2026
…lvanocerza#22

Decision silvanocerza#22 (Reset → rename siblings to *.unresolved-*):
- ConflictStore.renameVaultSiblingsToUnresolved() walks the vault and
  renames `*.conflict-from-<dev>-<isoTs>.<ext>` siblings to
  `*.unresolved-<isoTs>.<ext>`, dropping the device-label segment so
  a re-enable on a different device can't collide with prior artifacts.
- Pure helper unresolvedNameFor() anchors on buildSiblingPath's exact
  iso-timestamp shape; non-matching filenames return null.
- main.ts:resetPluginState() calls the rename BEFORE clearAll(); the
  repo-switch path still skips it (siblings stay as live conflicts
  against the new remote).
- 11 new unit tests in conflict-store.test.ts: 6 instance-method
  (regular ext, hidden file, extensionless, multi-sibling, ignore
  non-matching, mobile rename-throws safety) + 5 pure helper cases.

Decision silvanocerza#19 (branch prefix derived from plugin id):
- CONFLICT_BRANCH_PREFIX = `${manifest.id}-conflicts-` →
  `github-easy-sync-conflicts-` instead of bare `easy-sync-conflicts-`.
  Reconciles the doc's Decision silvanocerza#19 wording with code.
- Existing installs with active branches under the old prefix become
  orphans (per Decision silvanocerza#23) — sole-user constraint (Decision silvanocerza#24)
  means no migration path needed; finalize before upgrade if active.
- Comments + tests across conflict-branch / snapshot-store /
  branch-lifecycle integration updated to the new prefix.

Incidental polish bundled in:
- settings/tab.ts: "Settings > Files and links" → "Settings (Options)
  > Files and links" — disambiguates for mobile where the menu label
  differs.
- sync2/gitignore-invariants.ts: ROOT_RECOMMENDED_DEFAULTS gains
  more OS-noise + trash-can entries (.AppleDouble, .LSOverride, Icon,
  ._*, ehthumbs.db, $RECYCLE.BIN/, .trash/, .trashed-*).

Tests: 525/525 unit pass (was 514, +11). Build clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants