Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 21 additions & 21 deletions README.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/brand/roadmap.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
47 changes: 24 additions & 23 deletions docs/ipc-security.md

Large diffs are not rendered by default.

24 changes: 14 additions & 10 deletions docs/roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,10 @@ flowchart LR
end
subgraph merge["three-way merge"]
m["index :1: :2: :3: — no markers on screen"]
f["conflicts list — every file, any order"]
v["MergeView — ours │ result │ theirs, middle editable"]
w["mergeSession.js — the one write"]
m --> v --> w
w["conflictSession.js — every write verified"]
m --> f --> v --> w
end
```

Expand All @@ -205,14 +206,17 @@ flowchart LR
- **Revisions** — `diffbro compare HEAD~1:src/app.js src/app.js`. `git show`
behind a fence: fixed argv, no shell, the repo root computed in main, hooks
and the fsmonitor disabled, every inherited `GIT_*` dropped
- **Merge** — `git mergetool` now finishes, in a three-pane view: the two
branches either side, named by branch, and the file you are producing in the
middle as a real editor. Sides come from the index, so no `<<<<<<<` reaches
the screen; gutter chevrons move a side across, F7 walks the conflicts, and
typing IS the answer where neither side was right. This CROSSES "Diff Bro
never writes files", deliberately: the app had already registered for the job.
Main writes only the `$MERGED` path it was launched with, the renderer sends
text and never a path, and the launcher waits so `trustExitCode` is honest
- **Merge** — `git mergetool` now finishes, and opens on the LIST: every
conflicted file, what is left and what is done. Take a whole side from a row,
or open one in the three-pane view — the two branches either side, named by
branch, and the file you are producing in the middle as a real editor. Sides
come from the index, so no `<<<<<<<` reaches the screen; a button on each
pane's inner edge moves that side across, F7 walks the conflicts, and typing
IS the answer where neither side was right. Files are answered in any order.
This CROSSES "Diff Bro never writes files", deliberately: the app had already
registered for the job. The renderer names a row by INDEX and never a path,
every write is re-verified against git's unmerged list on the way in, and the
launcher waits so `trustExitCode` is honest

**Open.** TOML lockfiles (`Cargo.lock`, `poetry.lock`) need a parser this repo
does not have. A revision PICKER — the app takes a revision, it is not a git
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshots/themes/conflict-list-beacon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshots/themes/conflict-list-bloom.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshots/themes/conflict-list-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshots/themes/conflict-list-dim.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshots/themes/conflict-list-ember.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshots/themes/conflict-list-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshots/themes/conflict-list-linen.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshots/themes/conflict-list-matrix.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshots/themes/conflict-list-neon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshots/themes/conflict-list-nord.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshots/themes/conflict-list-nyan.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshots/themes/conflict-list-sepia.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshots/themes/conflict-list-solar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshots/themes/conflict-list-tide.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshots/themes/conflict-list-vector.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshots/themes/conflict-list-volcano.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 26 additions & 0 deletions docs/security.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,32 @@ takes bytes and a display name. With no mergetool launch there is no path held,
so the handler writes nothing at all whatever arrives, and a session is spent
once used.

### The conflicts list widens that to the whole walk

`git mergetool` walks the conflicted files one launch at a time, and the list
lets a reader answer them in their own order — so main writes files this
launch's argv did not name. That is a real widening of the most sensitive
surface in the app, and it is fenced the same way rather than differently:

- The renderer addresses a row by its **index** into the list main built
(`merge:take`, `merge:open`). It never sees a path — a row carries a display
name and a directory label — and there is no handler that takes one.
- Every path is recomputed in main from the repository root plus that row's
entry, and `isRepoRelative` refuses anything absolute, option-shaped, or
climbing out with `..`.
- Verification happens at **use** time, never at list time. A row can stop being
unmerged between the dialog opening and the click, so each write re-runs
`git diff --name-only --diff-filter=U` and refuses a row that is no longer in
it. A stale list fails closed.
- A file answered out of order still gets a launch of its own later. It no
longer has markers, so it is short-circuited **before** the marker guard and
released with a `written` sentinel; refused there instead, it would write no
sentinel and hang the terminal for the launcher's full two hours.
- The list itself is built from a size-capped, binary-sniffed read of each
working copy. A file that cannot be opened as text is listed as `blocked` and
can only be answered whole-file from the index — never decoded and written
back.

The middle pane is a full editor, and that costs nothing here: `merge:write`
already took arbitrary text, so a renderer that wanted to write something
neither side said could always do it. Editing widens what the READER can
Expand Down
Loading
Loading