Združevanje na ravni celic
Združevanje na ravni stolpcev zazna, kadar obe strani spremenita isti stolpec. Združevanje na ravni celic gre globlje in združuje vsebino znotraj tega stolpca. Dve osebi lahko brez težav združita spremembe različnih vrstic polja TEXT ali različnih ključev objekta JSON.
use Merql\CellMerge\CellMergeConfig;
use Merql\Merge\ThreeWayMerge;
$config = CellMergeConfig::auto();
$merge = new ThreeWayMerge($config);
$result = $merge->merge($base, $ours, $theirs);
Omogočanje združevanja na ravni celic
Združevanje na ravni celic je izbirno. Deluje samo, če je ThreeWayMerge ustvarjen z nastavitvijo CellMergeConfig. Brez nje vsak stolpec, ki sta ga obe strani spremenili na različni vrednosti, povzroči spor update_update.
Vmesnik Merql ne sprejme konfiguracije: Merql::merge(), Merql::patch() in Merql::plan() ustvarijo new ThreeWayMerge() brez nje, ukaz merge v CLI pa se izvaja prek Merql::merge(). Vedno združujejo na ravni stolpcev (#7).
Če želite posnetke, shranjene prek vmesnika ali CLI, združiti na ravni celic, jih naložite in sami pokličite ThreeWayMerge. Rezultat je običajen MergeResult, zato ga lahko vmesnik še vedno uveljavi, MergePlanBuilder pa ga pretvori v načrt združevanja:
use Merql\CellMerge\CellMergeConfig;
use Merql\Merge\ThreeWayMerge;
use Merql\Merql;
use Merql\Plan\MergePlanBuilder;
use Merql\Snapshot\SnapshotStore;
$base = SnapshotStore::load('base');
$ours = SnapshotStore::load('ours');
$theirs = SnapshotStore::load('theirs');
$result = (new ThreeWayMerge(CellMergeConfig::auto()))->merge($base, $ours, $theirs);
$plan = (new MergePlanBuilder())->build('plan-1', $base, $ours, $theirs, $result);
Združevalniki celic se zaženejo samo za stolpce, ki sta jih spremenili obe strani. Če je stolpec spremenila samo ena stran, se njegova vrednost prevzame nespremenjena.
CellMergeConfig
CellMergeConfig povezuje stolpce ali vrste stolpcev z izvedbami združevalnikov celic. Tovarna auto() ponuja smiselne privzete vrednosti:
use Merql\CellMerge\CellMergeConfig;
use Merql\CellMerge\JsonCellMerger;
use Merql\CellMerge\TextCellMerger;
// Auto: column types containing "text" (TEXT, MEDIUMTEXT, LONGTEXT, ...) use
// TextCellMerger, column types containing "json" use JsonCellMerger.
$config = CellMergeConfig::auto();
// Custom: assign mergers to specific columns.
$config = (new CellMergeConfig())
->forColumn('posts.content', new TextCellMerger())
->forColumn('settings', new JsonCellMerger())
->forType('json', new JsonCellMerger());
Prednostni vrstni red razreševanja združevalnikov:
- Polno kvalificirano ime stolpca (
table.column). - Nekvalificirano ime stolpca (
column). - Ujemanje vzorca vrste stolpca (brez razlikovanja velikih in malih črk
str_contains). - Privzeto:
OpaqueCellMerger(ob različnih vrednostih vedno sporoči spor).
TextCellMerger
Združuje večvrstično besedilo z algoritmom Myers diff, ki ga git uporablja tudi za vsebino datotek. Vsaka vrstica je obravnavana kot enota, spremembe različnih vrstic pa se združijo brez sporov.
use Merql\CellMerge\TextCellMerger;
$merger = new TextCellMerger();
Primer: čisto združevanje besedila
Base: "line one\nline two\nline three"
Ours: "LINE ONE\nline two\nline three" // changed line 1
Theirs: "line one\nline two\nLINE THREE" // changed line 3
Spremenjene so bile različne vrstice. Združitev ustvari "LINE ONE\nline two\nLINE THREE" brez sporov.
Primer: spor pri besedilu
Base: "line one\nline two"
Ours: "changed by us\nline two" // changed line 1
Theirs: "changed by them\nline two" // also changed line 1
Obe strani sta isto vrstico spremenili na različni vrednosti. Združevalnik vrne rezultat s sporom. Združena vsebina vključuje oznake sporov, podobne kot pri git.
Kako deluje
TextCellMerger uporabi ThreeWayMerge::merge() iz pitmaster, ki izračuna Myersove razlike med osnovo in vsako stranjo, nato pa združi oba skripta sprememb. Če se spremembe prekrivajo na istem območju vrstic, sporoči spor.
JsonCellMerger
Združuje objekte JSON tako, da primerja vsak vrhnji ključ posebej. Vsak ključ združi po standardnih trosmernih pravilih.
use Merql\CellMerge\JsonCellMerger;
$merger = new JsonCellMerger();
Primer: čisto združevanje JSON
// Base
{"name": "Alice", "role": "editor", "active": true}
// Ours: changed "role"
{"name": "Alice", "role": "admin", "active": true}
// Theirs: changed "name"
{"name": "Bob", "role": "editor", "active": true}
Spremenjeni so bili različni ključi. Združeni rezultat je:
{"name": "Bob", "role": "admin", "active": true}
Primer: spor pri JSON
// Base
{"color": "red"}
// Ours
{"color": "blue"}
// Theirs
{"color": "green"}
Obe strani sta ključ color spremenili na različni vrednosti. To je spor. Združevalnik privzeto izbere našo vrednost in sporoči en spor.
Pravila za ključe
| Osnova | Naši | Njihovi | Rezultat |
|---|---|---|---|
| Ključ nespremenjen | Ključ nespremenjen | Sprejmi osnovo | |
| Ključ nespremenjen | Ključ spremenjen | Sprejmi njihovega | |
| Ključ spremenjen | Ključ nespremenjen | Sprejmi našega | |
| Ključ spremenjen (enako) | Ključ spremenjen (enako) | Sprejmi (ujemanje) | |
| Ključ spremenjen (različno) | Ključ spremenjen (različno) | Spor (privzeto: naši) | |
| Ključ obstaja | Ključ obstaja | Ključ odstranjen | Sprejmi odstranitev |
| Ključ obstaja | Ključ odstranjen | Ključ obstaja | Sprejmi odstranitev |
| Ključ manjka | Ključ dodan | Ključ manjka | Sprejmi dodajanje |
| Ključ manjka | Ključ manjka | Ključ dodan | Sprejmi dodajanje |
Vgnezdeni objekti so primerjani kot neprosojni nizi JSON in ne rekurzivno. Če se vgnezdeni objekt razlikuje, se primerja celotna vrednost tega ključa, ne njegovi podključi.
Zahteve
Vse tri vrednosti morajo biti veljavni objekti ali polja JSON. Če katera koli vrednost ni veljaven JSON ali je skalar JSON (niz, število, logična vrednost), združevalnik sporoči spor.
OpaqueCellMerger
Privzeti združevalnik, kadar strategija za raven celic ni nastavljena. Vrednost stolpca obravnava kot neprosojen blok in vedno sporoči spor, kadar se strani razlikujeta.
use Merql\CellMerge\OpaqueCellMerger;
$merger = new OpaqueCellMerger();
$result = $merger->merge($base, $ours, $theirs);
// $result->clean is always false when $ours !== $theirs
CellMergeResult
Vsi združevalniki celic vrnejo CellMergeResult:
$result = $merger->merge($base, $ours, $theirs);
$result->clean; // bool: true if merge resolved cleanly
$result->value; // mixed: the merged value (or ours on conflict)
$result->conflicts; // int: number of conflicts within the cell
Tovarniške metode:
CellMergeResult::resolved($value); // clean merge
CellMergeResult::conflict($oursValue, $n); // n conflicts, defaults to ours
Prilagojeni združevalniki celic
Izvedite vmesnik CellMerger, da dodate lastno strategijo združevanja:
use Merql\CellMerge\CellMerger;
use Merql\CellMerge\CellMergeResult;
class YamlCellMerger implements CellMerger
{
public function merge(mixed $base, mixed $ours, mixed $theirs): CellMergeResult
{
// Parse YAML, merge keys, return result.
$merged = $this->mergeYaml($base, $ours, $theirs);
if ($merged['clean']) {
return CellMergeResult::resolved($merged['value']);
}
return CellMergeResult::conflict($ours);
}
}
$config = (new CellMergeConfig())
->forColumn('config_data', new YamlCellMerger());