bowline
Guides

Resolve a sync conflict

Find conflict-aside files with bowline conflicts, pick a side with bowline resolve, or reconcile by hand with your editor or a coding agent.

When two machines or agents change the same file in incompatible ways, Bowline records the divergence instead of guessing. Your real project directory stays usable, both versions are preserved as ordinary files, and nothing interrupts you. This guide walks through the whole flow: how a conflict-aside file appears, how it surfaces, and how you pick a side.

What a conflict looks like

A conflict happens when two devices diverge on the same file: each changed it since the last state they agreed on, and the sync engine can't keep both versions at one path. Instead of merging blindly or splicing conflict markers into your source, the engine keeps a coherent version at the real path and writes the other side to a deterministically named aside file next to it:

A conflict-aside next to its file
~/Code/acme/web/src/auth/callback.ts
~/Code/acme/web/src/auth/callback.ts.bowline-conflict.3f2a1c9d

The name shape is <path>.bowline-conflict.<prefix>, where the prefix comes from the incoming content so repeated conflicts never collide. Because the marker lands after the original name, the aside no longer ends in .ts, so your build and language server ignore it. Both files are ordinary workspace files. The aside syncs to your other devices like anything else, so every trusted device sees the same conflict and any of them — including an agent host — can reconcile it.

Find what is waiting

bowline conflicts

Each entry names the file that kept your version, the aside holding the incoming one, and the command that resolves it. bowline status and bowline tui report the same conflicts as attention, and they stay there until the aside is gone.

Because conflicts are passive, you reconcile them on your schedule. The aside file sits there indefinitely, and unrelated edits keep syncing in the meantime.

Read the difference

bowline resolve 'acme/web/src/auth/callback.ts.bowline-conflict.3f2a1c9d' --diff

--diff changes nothing. It prints the lines that differ between your file and the incoming version so you can decide which side to keep.

Pick a side

# Keep your file; discard the incoming version.
bowline resolve '<aside-path>' --keep-local

# Replace your file with the incoming version.
bowline resolve '<aside-path>' --take-remote

Exactly one of --keep-local, --take-remote, and --diff is required. Bowline will not default to a side of your own work.

Both mutating verbs end with the aside gone, and that absence is what clears the conflict — on this device, in status, and on every other device once the deletion syncs.

Or fold both sides in by hand

Nothing about a conflict is special-cased, so the manual path works identically and is the right one when you want lines from both sides:

  1. Open the file and its aside side by side in your editor or diff tool.
  2. Edit the real file into the version you want.
  3. Delete the aside. Removing it is what clears the conflict.

The same flow works with a coding agent. Point your agent at the project and ask it to reconcile the aside — for example, "fold the changes from callback.ts.bowline-conflict.3f2a1c9d into callback.ts, keep both sides' intent, then delete the aside." The agent uses its normal read and edit tools.

Reconciling a conflict syncs files; it never stages, commits, pushes, or branches. Source control stays your tool.

Secret-bearing conflicts

A conflict-aside can land next to a secret-bearing file like .env. Both versions exist only as local files on trusted devices; Bowline's hosted service cannot read them. If you hand the reconciliation to an agent, keep secret values out of the prompt — name the paths and let the agent read the files from disk.

Next steps

On this page