Sujungimas langelio lygmeniu
Sujungimas stulpelių lygmeniu aptinka, kai abi pusės pakeitė tą patį stulpelį. Sujungimas langelio lygmeniu veikia išsamiau – sujungia to stulpelio turinį. Du žmonės gali sklandžiai sujungti pakeitimus, jei vienas redagavo skirtingas TEXT lauko eilutes, o kitas – skirtingus JSON objekto raktus.
use Merql\CellMerge\CellMergeConfig;
use Merql\Merge\ThreeWayMerge;
$config = CellMergeConfig::auto();
$merge = new ThreeWayMerge($config);
$result = $merge->merge($base, $ours, $theirs);
Sujungimo langelio lygmeniu įjungimas
Sujungimas langelio lygmeniu yra pasirenkamas. Jis veikia tik ThreeWayMerge, sukurtame su CellMergeConfig. Jei jo nėra, kiekvienas stulpelis, kurį abi pusės pakeitė į skirtingas reikšmes, laikomas update_update konfliktu.
Merql fasadas nepriima konfigūracijos: Merql::merge(), Merql::patch() ir Merql::plan() sukuria new ThreeWayMerge() be jos, o CLI komanda merge vykdoma per Merql::merge(). Jie visada sujungia stulpelių lygmeniu (#7).
Norėdami sujungti fasado arba CLI išsaugotus momentinius vaizdus langelio lygmens sujungimu, įkelkite juos ir patys iškvieskite ThreeWayMerge. Rezultatas yra įprastas MergeResult, todėl fasadas vis tiek gali jį pritaikyti, o MergePlanBuilder paverčia jį sujungimo planu:
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);
Langeliai sujungiami tik tuose stulpeliuose, kuriuos pakeitė abi pusės. Jei stulpelį pakeitė tik viena pusė, jo reikšmė perimama nepakeista.
CellMergeConfig
CellMergeConfig susieja stulpelius arba stulpelių tipus su langelių sujungimo realizacijomis. auto() gamykloje nustatytos reikšmės yra tinkamos:
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());
Sujungimo būdo parinkimo prioritetas:
- Pilnas stulpelio pavadinimas (
table.column). - Stulpelio pavadinimas be kvalifikatoriaus (
column). - Stulpelio tipo šablono atitiktis (
str_contains, nepaisant raidžių dydžio). - Numatytoji reikšmė:
OpaqueCellMerger(visada praneša apie konfliktą, kai reikšmės skiriasi).
TextCellMerger
Sujungia kelių eilučių tekstą naudodamas Myers skirtumų algoritmą, tą patį, kurį git naudoja failų turiniui. Kiekviena eilutė laikoma vienetu, todėl skirtingų eilučių pakeitimai sujungiami sklandžiai.
use Merql\CellMerge\TextCellMerger;
$merger = new TextCellMerger();
Pavyzdys: sklandus teksto sujungimas
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
Buvo redaguotos skirtingos eilutės. Sujungimo rezultatas – "LINE ONE\nline two\nLINE THREE" be konflikto.
Pavyzdys: teksto konfliktas
Base: "line one\nline two"
Ours: "changed by us\nline two" // changed line 1
Theirs: "changed by them\nline two" // also changed line 1
Abi pusės pakeitė tą pačią eilutę į skirtingas reikšmes. Sujungimo būdas grąžina konflikto rezultatą. Sujungtame turinyje pateikiami į git panašūs konfliktų žymekliai.
Kaip tai veikia
TextCellMerger naudoja pitmaster ThreeWayMerge::merge(), kuris apskaičiuoja Myers skirtumą tarp bazinės versijos ir kiekvienos pusės, tada sujungia abu redagavimo scenarijus. Jei pakeitimai persidengia toje pačioje eilučių srityje, pranešama apie konfliktą.
JsonCellMerger
Sujungia JSON objektus, atskirai palygindamas aukščiausio lygio raktus. Kiekvienas raktas sujungiamas pagal standartines trijų krypčių taisykles.
use Merql\CellMerge\JsonCellMerger;
$merger = new JsonCellMerger();
Pavyzdys: sklandus JSON sujungimas
// 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}
Buvo pakeisti skirtingi raktai. Sujungimo rezultatas:
{"name": "Bob", "role": "admin", "active": true}
Pavyzdys: JSON konfliktas
// Base
{"color": "red"}
// Ours
{"color": "blue"}
// Theirs
{"color": "green"}
Abi pusės pakeitė tą patį color raktą į skirtingas reikšmes. Tai konfliktas. Pagal numatytąją nuostatą sujungimo būdas pasirenka mūsų reikšmę ir praneša apie vieną konfliktą.
Raktų lygmens taisyklės
| Bazė | Mūsų pusė | Jų pusė | Rezultatas |
|---|---|---|---|
| Raktas nepakeistas | Raktas nepakeistas | Priimti bazinę reikšmę | |
| Raktas nepakeistas | Raktas pakeistas | Priimti jų reikšmę | |
| Raktas pakeistas | Raktas nepakeistas | Priimti mūsų reikšmę | |
| Raktas pakeistas (vienodai) | Raktas pakeistas (vienodai) | Priimti (sutampa) | |
| Raktas pakeistas (skirtingai) | Raktas pakeistas (skirtingai) | Konfliktas (numatyta: mūsų reikšmė) | |
| Raktas yra | Raktas yra | Raktas pašalintas | Priimti pašalinimą |
| Raktas yra | Raktas pašalintas | Raktas yra | Priimti pašalinimą |
| Raktas trūksta | Raktas pridėtas | Raktas trūksta | Priimti pridėjimą |
| Raktas trūksta | Raktas trūksta | Raktas pridėtas | Priimti pridėjimą |
Įdėtiniai objektai lyginami kaip vientisos JSON eilutės, o ne rekursyviai. Jei įdėtinis objektas skiriasi, lyginama visa to rakto reikšmė, o ne jo po-rakčiai.
Reikalavimai
Visos trys reikšmės turi būti galiojantys JSON objektai arba masyvai. Jei bent viena reikšmė nėra galiojantis JSON arba yra JSON skaliaras (eilutė, skaičius, loginė reikšmė), sujungimo būdas grįžta prie konflikto.
OpaqueCellMerger
Numatytasis sujungimo būdas, kai nesukonfigūruota sujungimo langelio lygmeniu strategija. Stulpelio reikšmė laikoma vientisu objektu ir visada pranešama apie konfliktą, jei abiejų pusių reikšmės skiriasi.
use Merql\CellMerge\OpaqueCellMerger;
$merger = new OpaqueCellMerger();
$result = $merger->merge($base, $ours, $theirs);
// $result->clean is always false when $ours !== $theirs
CellMergeResult
Visi langelių sujungimo būdai grąžina 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
Gamyklos metodai:
CellMergeResult::resolved($value); // clean merge
CellMergeResult::conflict($oursValue, $n); // n conflicts, defaults to ours
Pasirinktiniai langelių sujungimo būdai
Įgyvendinkite CellMerger sąsają, kad pridėtumėte savo sujungimo strategiją:
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());