Apvienošana šūnu līmenī
Kolonnu līmeņa sapludināšana nosaka, vai abas puses mainījušas vienu un to pašu kolonnu. Šūnu līmeņa sapludināšana darbojas detalizētāk, sapludinot šīs kolonnas saturu. Divu cilvēku veiktas izmaiņas dažādās TEXT lauka rindās vai dažādās JSON objekta atslēgās var sapludināt bez konfliktiem.
use Merql\CellMerge\CellMergeConfig;
use Merql\Merge\ThreeWayMerge;
$config = CellMergeConfig::auto();
$merge = new ThreeWayMerge($config);
$result = $merge->merge($base, $ours, $theirs);
Šūnu līmeņa sapludināšanas iespējošana
Šūnu līmeņa sapludināšana pēc noklusējuma nav ieslēgta. Tā darbojas tikai ThreeWayMerge, kas izveidots ar CellMergeConfig. Bez tā ikviena kolonna, kurai abas puses mainījušas vērtību uz atšķirīgu vērtību, rada update_update konfliktu.
Merql fasāde nepieņem konfigurāciju: Merql::merge(), Merql::patch() un Merql::plan() izveido new ThreeWayMerge() bez tās, bet CLI komanda merge tiek izpildīta, izmantojot Merql::merge(). Tās vienmēr sapludina kolonnu līmenī (#7).
Lai sapludinātu fasādes vai CLI saglabātos momentuzņēmumus ar šūnu līmeņa sapludināšanu, ielādējiet tos un paši izsauciet ThreeWayMerge. Rezultāts ir parasts MergeResult, ko fasāde joprojām var lietot, un MergePlanBuilder to pārveido par sapludināšanas plānu:
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);
Šūnu sapludinātāji darbojas tikai kolonnām, kuras mainījušas abas puses. Ja kolonnu mainījusi tikai viena puse, tās vērtība tiek ņemta tāda, kāda tā ir.
CellMergeConfig
CellMergeConfig sasaista kolonnas vai kolonnu tipus ar šūnu sapludinātāju implementācijām. auto() rūpnīca nodrošina saprātīgas noklusējuma vērtības:
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());
Sapludinātāja izvēles prioritāte:
- Pilnais kolonnas nosaukums (
table.column). - Kolonnas nosaukums bez prefiksa (
column). - Atbilstība kolonnas tipa rakstam (reģistrnejutīgs
str_contains). - Noklusējums:
OpaqueCellMerger(vienmēr ziņo par konfliktu, ja vērtības atšķiras).
TextCellMerger
Sapludina vairākrindu tekstu, izmantojot Myers diff — to pašu algoritmu, ko git izmanto failu saturam. Katra rinda tiek uzskatīta par vienību, un izmaiņas dažādās rindās saplūst bez konfliktiem.
use Merql\CellMerge\TextCellMerger;
$merger = new TextCellMerger();
Piemērs: tīra teksta sapludināšana
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
Rediģētas dažādas rindas. Sapludināšanas rezultātā tiek iegūts "LINE ONE\nline two\nLINE THREE" bez konflikta.
Piemērs: teksta konflikts
Base: "line one\nline two"
Ours: "changed by us\nline two" // changed line 1
Theirs: "changed by them\nline two" // also changed line 1
Abas puses mainīja vienu un to pašu rindu uz atšķirīgām vērtībām. Sapludinātājs atgriež konflikta rezultātu. Sapludinātajā saturā ir konfliktu marķieri, kas līdzinās git marķieriem.
Kā tas darbojas
TextCellMerger izmanto pitmaster ThreeWayMerge::merge(), kas aprēķina Myers diff starp bāzi un katru pusi un pēc tam apvieno abas izmaiņu secības. Ja izmaiņas pārklājas vienā un tajā pašā rindas apgabalā, tas ziņo par konfliktu.
JsonCellMerger
Sapludina JSON objektus, neatkarīgi salīdzinot augstākā līmeņa atslēgas. Katra atslēga tiek sapludināta, izmantojot standarta trīsvirzienu noteikumus.
use Merql\CellMerge\JsonCellMerger;
$merger = new JsonCellMerger();
Piemērs: tīra JSON sapludināšana
// 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}
Mainītas dažādas atslēgas. Sapludināšanas rezultāts:
{"name": "Bob", "role": "admin", "active": true}
Piemērs: JSON konflikts
// Base
{"color": "red"}
// Ours
{"color": "blue"}
// Theirs
{"color": "green"}
Abas puses mainīja color atslēgu uz atšķirīgām vērtībām. Tas ir konflikts. Pēc noklusējuma sapludinātājs izvēlas mūsu vērtību un ziņo par vienu konfliktu.
Atslēgu līmeņa noteikumi
| Bāze | Mūsu | Viņu | Rezultāts |
|---|---|---|---|
| Atslēga nemainīta | Atslēga nemainīta | Pieņemt bāzi | |
| Atslēga nemainīta | Atslēga mainīta | Pieņemt viņu vērtību | |
| Atslēga mainīta | Atslēga nemainīta | Pieņemt mūsu vērtību | |
| Atslēga mainīta (vienādi) | Atslēga mainīta (vienādi) | Pieņemt (sakrīt) | |
| Atslēga mainīta (atšķirīgi) | Atslēga mainīta (atšķirīgi) | Konflikts (pēc noklusējuma: mūsu vērtība) | |
| Atslēga pastāv | Atslēga pastāv | Atslēga noņemta | Pieņemt noņemšanu |
| Atslēga pastāv | Atslēga noņemta | Atslēga pastāv | Pieņemt noņemšanu |
| Atslēgas nav | Atslēga pievienota | Atslēgas nav | Pieņemt pievienošanu |
| Atslēgas nav | Atslēgas nav | Atslēga pievienota | Pieņemt pievienošanu |
Ligzdotie objekti tiek salīdzināti kā necaurredzamas JSON virknes, nevis rekursīvi. Ja ligzdots objekts atšķiras, tiek salīdzināta visa šīs atslēgas vērtība, nevis tās apakšatslēgas.
Prasības
Visām trim vērtībām jābūt derīgiem JSON objektiem vai masīviem. Ja kāda vērtība nav derīgs JSON vai ir skalāra vērtība JSON (virkne, skaitlis, Būla vērtība), sapludinātājs atgriežas pie konflikta.
OpaqueCellMerger
Noklusējuma sapludinātājs, ja nav konfigurēta šūnu līmeņa stratēģija. Tas uzskata kolonnas vērtību par necaurredzamu bloku un vienmēr ziņo par konfliktu, ja abu pušu vērtības atšķiras.
use Merql\CellMerge\OpaqueCellMerger;
$merger = new OpaqueCellMerger();
$result = $merger->merge($base, $ours, $theirs);
// $result->clean is always false when $ours !== $theirs
CellMergeResult
Visi šūnu sapludinātāji atgriež 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
Rūpnīcas metodes:
CellMergeResult::resolved($value); // clean merge
CellMergeResult::conflict($oursValue, $n); // n conflicts, defaults to ours
Pielāgoti šūnu sapludinātāji
Lai pievienotu savu sapludināšanas stratēģiju, implementējiet CellMerger saskarni:
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());