Syncing & commits
ForkLeaf is deliberately explicit about the difference between “saved on this device” and “pushed to GitHub”. An autosaving app that is vague about that distinction is how people come to believe they lost work.
The life of an edit
- You type. The editor updates.
- A few hundred milliseconds later the note is written to IndexedDB. It is now safe against a crash, a closed tab, or a flat battery.
- A pending change is queued: the path, the new content, and the SHA the edit was based on.
- The sync engine drains the queue — on a timer, on reconnect, or immediately when you press
⌘S. - Changes are pushed to GitHub as a commit, and the queue empties.
Reading the status bar
| What it says | What it means |
|---|---|
| All changes saved | Local and GitHub agree. Nothing is pending. |
| Saved locally · 2 to push | Two notes are safely on this device but have not reached GitHub yet. Click to push now. |
| Saving to GitHub… | A push is in flight. |
| Offline · 3 changes queued | No network. Everything is on this device and will go up automatically when you reconnect. |
| A sentence saying what went wrong — click to retry | The push failed. The message says what happened and what to do about it; nothing was lost, and your work is on this device either way. |
| 2 conflicts — click to resolve | The same note changed here and on GitHub. See Conflicts. |
| Saved on this device | You are in the local workspace, which never pushes. |
What the commits look like
One commit per sync, containing every change in that batch. Multi-file operations — a rename is a delete plus a create — go through GitHub’s tree API as a single atomic commit, so the repository can never be left half-updated.
a3f9c21 forkleaf: update architecture/sync-engine.md
7b21e08 forkleaf: update 3 notes
1c94ffa forkleaf: rename reading.md to reading-list.mdCommit squashing
Typing produces a lot of small saves, and a commit per keystroke-batch would bury your history. So when the branch head is a commit ForkLeaf made recently, the next push amends it rather than stacking a new one.
The guard rails on that are strict, because rewriting history is dangerous:
- Only if the head commit carries ForkLeaf’s own marker in its message.
- Only within a short time window.
- Only if the author matches.
- Never if anyone else has pushed in the meantime.
Offline
Everything works: opening notes, writing, switching views, inserting diagrams, exporting. The queue accumulates and the status bar says how much is waiting. On reconnect it drains automatically.
If you try to close the tab with unpushed changes, the browser asks you to confirm.
Across devices
Sign in with the same GitHub account elsewhere and ForkLeaf pulls the repository down. Both devices commit to the same branch, and each pulls the other’s commits on the next sync. If they both changed the same note, you get a conflict rather than a silent overwrite.
Deleting
Deleting a note commits the deletion. The content remains in your git history, so it is recoverable:
# find the commit that deleted it
git log --diff-filter=D --name-only -- meetings/2026-08-14.md
# restore it from the commit before that
git checkout <commit>^ -- meetings/2026-08-14.mdRate limits
Authenticated GitHub requests are capped at 5,000 per hour per user. ForkLeaf stays well under that by batching and by squashing, but if you do hit it, pushes fail with a rate-limit error and resume automatically once the window resets. Nothing is lost in the meantime.