Improve HTML description
This commit is contained in:
parent
8501033acd
commit
ac8f2e77ad
2 changed files with 60 additions and 39 deletions
|
|
@ -8,18 +8,18 @@
|
||||||
/>
|
/>
|
||||||
<meta
|
<meta
|
||||||
name="description"
|
name="description"
|
||||||
content="Easily merge three versions of a text document with this 3-way text merge tool."
|
content="3-way text merging that automatically resolves conflicts. No more Git conflict markers — just clean, merged results."
|
||||||
/>
|
/>
|
||||||
<meta property="og:title" content="3-Way Text Merge" />
|
<meta property="og:title" content="3-Way Text Merge" />
|
||||||
<meta
|
<meta
|
||||||
property="og:description"
|
property="og:description"
|
||||||
content="Easily merge three versions of a text document with this 3-way text merge tool."
|
content="3-way text merging that automatically resolves conflicts. No more Git conflict markers — just clean, merged results."
|
||||||
/>
|
/>
|
||||||
<meta property="og:type" content="website" />
|
<meta property="og:type" content="website" />
|
||||||
<meta property="og:url" content="https://github.com/schmelczer/reconcile" />
|
<meta property="og:url" content="https://schmelczer.dev/reconcile" />
|
||||||
<meta property="og:image" content="/favicon.ico" />
|
<meta property="og:image" content="/favicon.ico" />
|
||||||
<link rel="icon" type="image/x-icon" href="favicon.ico" />
|
<link rel="icon" type="image/x-icon" href="favicon.ico" />
|
||||||
<title>3-Way Text Merge</title>
|
<title>Reconcile: conflict-free text merging</title>
|
||||||
<link inline inline-asset="index.css" inline-asset-delete />
|
<link inline inline-asset="index.css" inline-asset-delete />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
@ -28,49 +28,58 @@
|
||||||
<div class="scroll-container">
|
<div class="scroll-container">
|
||||||
<div class="page-wrapper">
|
<div class="page-wrapper">
|
||||||
<header>
|
<header>
|
||||||
<h1>Reconcile: automated 3-way text merge</h1>
|
<h1>Reconcile: conflict-free 3-way text merging</h1>
|
||||||
<p>
|
<p>
|
||||||
The
|
Think
|
||||||
<a
|
|
||||||
href="https://github.com/schmelczer/reconcile"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>reconcile</a
|
|
||||||
>
|
|
||||||
library solves a fundamental challenge in collaborative editing: what happens
|
|
||||||
when multiple users edit the same text simultaneously but we can only capture
|
|
||||||
the end result, not the intermediary edits? Essentially, it's
|
|
||||||
<a
|
<a
|
||||||
href="https://www.gnu.org/software/diffutils/manual/html_node/Invoking-diff3.html"
|
href="https://www.gnu.org/software/diffutils/manual/html_node/Invoking-diff3.html"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
>diff3</a
|
>diff3</a
|
||||||
>
|
>
|
||||||
(or <code>git merge</code>) but with automatic conflict resolution.
|
or <code>git merge</code>, but with intelligent conflict resolution that
|
||||||
</p>
|
requires no user intervention. The
|
||||||
<p>
|
<a
|
||||||
The
|
href="https://github.com/schmelczer/reconcile"
|
||||||
<code>reconcile(parent: str, left: str, right: str) -> str</code>
|
target="_blank"
|
||||||
takes conflicting concurrent edits and intelligently merges them into a
|
rel="noopener noreferrer"
|
||||||
unified result. Beyond basic conflict resolution, it offers sophisticated
|
>Reconcile</a
|
||||||
merging heuristics, flexible tokenization options, and cursor position
|
>
|
||||||
tracking.
|
library tackles a fundamental challenge in collaborative editing: what happens
|
||||||
</p>
|
when multiple users edit the same text simultaneously, but the conflict
|
||||||
<p>
|
resolver only has access to the final results, not the intermediate steps?
|
||||||
The algorithm begins with your chosen tokenizer, then applies Myers' diff
|
|
||||||
algorithm to compare the original text with both conflicting versions. These
|
|
||||||
diffs undergo transformation to preserve meaningful change sequences, before a
|
|
||||||
final merge strategy—inspired by Operational Transformation reconciles all
|
|
||||||
conflicting modifications without losing any edits.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
For more details, see the
|
|
||||||
<a href="https://github.com/schmelczer/reconcile" target="_blank">README</a>.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Use the tokenization options below to experiment with different strategies.
|
Where traditional merge tools leave you with conflict markers to resolve
|
||||||
The library supports user-defined tokenizers as well.
|
manually, Reconcile automatically weaves changes together. The
|
||||||
|
<code>reconcile(parent, left, right)</code> function takes conflicting edits
|
||||||
|
and produces clean, unified results using an algorithm inspired by Operational
|
||||||
|
Transformation. No more <code><<<<<<<</code> markers
|
||||||
|
cluttering your text.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The process starts with your chosen tokenisation strategy, then applies Myers'
|
||||||
|
diff algorithm to compare the original with both modified versions. These
|
||||||
|
diffs are optimised and transformed to preserve meaningful changes, before a
|
||||||
|
final merge strategy combines all modifications without losing any edits.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Ready to dive deeper? Check out the
|
||||||
|
<a
|
||||||
|
href="https://github.com/schmelczer/reconcile"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>documentation</a
|
||||||
|
>
|
||||||
|
or try editing the text boxes below to see Reconcile in action.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Use the tokenisation options below to experiment with different approaches —
|
||||||
|
the library also supports custom tokenisers.
|
||||||
</p>
|
</p>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|
@ -87,7 +96,9 @@
|
||||||
<span class="radio-custom" aria-hidden="true"></span>
|
<span class="radio-custom" aria-hidden="true"></span>
|
||||||
<div class="radio-content">
|
<div class="radio-content">
|
||||||
<span class="radio-label">Character</span>
|
<span class="radio-label">Character</span>
|
||||||
<span class="radio-description">Split by individual characters</span>
|
<span class="radio-description"
|
||||||
|
>Fine-grained character-level merging</span
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
<label class="radio-option">
|
<label class="radio-option">
|
||||||
|
|
@ -101,7 +112,7 @@
|
||||||
<span class="radio-custom" aria-hidden="true"></span>
|
<span class="radio-custom" aria-hidden="true"></span>
|
||||||
<div class="radio-content">
|
<div class="radio-content">
|
||||||
<span class="radio-label">Word</span>
|
<span class="radio-label">Word</span>
|
||||||
<span class="radio-description">Split by words (default)</span>
|
<span class="radio-description">Retain full words (default)</span>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
<label class="radio-option">
|
<label class="radio-option">
|
||||||
|
|
@ -110,7 +121,7 @@
|
||||||
<div class="radio-content">
|
<div class="radio-content">
|
||||||
<span class="radio-label">Line</span>
|
<span class="radio-label">Line</span>
|
||||||
<span class="radio-description"
|
<span class="radio-description"
|
||||||
>Split by lines similarly to <code>git merge</code></span
|
>Line-by-line like <code>git merge</code></span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
|
|
@ -120,7 +131,7 @@
|
||||||
<div class="text-area-card diamond-parent">
|
<div class="text-area-card diamond-parent">
|
||||||
<label
|
<label
|
||||||
for="original"
|
for="original"
|
||||||
title="The text document's content before any concurrent edits occurred."
|
title="The original text before any concurrent edits were made."
|
||||||
>Original</label
|
>Original</label
|
||||||
>
|
>
|
||||||
<textarea id="original" name="original"></textarea>
|
<textarea id="original" name="original"></textarea>
|
||||||
|
|
@ -129,9 +140,9 @@
|
||||||
<div class="text-area-card diamond-left">
|
<div class="text-area-card diamond-left">
|
||||||
<label
|
<label
|
||||||
for="left"
|
for="left"
|
||||||
title="Colour-coded tokens mark the origin of each token in the result. This text box is marked with the colour green."
|
title="First user's edits — changes from this box appear in green in the result."
|
||||||
>
|
>
|
||||||
First concurrent edit
|
First user's edits
|
||||||
<div class="box Left"></div>
|
<div class="box Left"></div>
|
||||||
</label>
|
</label>
|
||||||
<textarea id="left" name="left"></textarea>
|
<textarea id="left" name="left"></textarea>
|
||||||
|
|
@ -140,9 +151,9 @@
|
||||||
<div class="text-area-card diamond-right">
|
<div class="text-area-card diamond-right">
|
||||||
<label
|
<label
|
||||||
for="right"
|
for="right"
|
||||||
title="Colour-coded tokens mark the origin of each token in the result. This text box is marked with the colour blue."
|
title="Second user's edits — changes from this box appear in blue in the result."
|
||||||
>
|
>
|
||||||
Second concurrent edit
|
Second user's edits
|
||||||
<div class="box Right"></div>
|
<div class="box Right"></div>
|
||||||
</label>
|
</label>
|
||||||
<textarea id="right" name="right"></textarea>
|
<textarea id="right" name="right"></textarea>
|
||||||
|
|
@ -151,9 +162,9 @@
|
||||||
<div class="text-area-card diamond-result">
|
<div class="text-area-card diamond-result">
|
||||||
<label
|
<label
|
||||||
for="merged"
|
for="merged"
|
||||||
title="Read-only. Change the above text boxes to change the content of this box."
|
title="The automatically merged result — edit the boxes above to see changes in real-time."
|
||||||
>
|
>
|
||||||
Deconflicted result
|
Merged result
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width="24"
|
width="24"
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,16 @@ p * {
|
||||||
user-select: text;
|
user-select: text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
background: #61769a;
|
||||||
|
color: #e2e8f0;
|
||||||
|
padding: 2px 6px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Roboto Mono', 'Consolas', monospace;
|
||||||
|
font-size: 0.875em;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
header > p {
|
header > p {
|
||||||
color: #5a6272;
|
color: #5a6272;
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue