Pereiti prie turinio

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.

PHP
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:

PHP
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:

PHP
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:

  1. Pilnas stulpelio pavadinimas (table.column).
  2. Stulpelio pavadinimas be kvalifikatoriaus (column).
  3. Stulpelio tipo šablono atitiktis (str_contains, nepaisant raidžių dydžio).
  4. 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.

PHP
use Merql\CellMerge\TextCellMerger;

$merger = new TextCellMerger();

Pavyzdys: sklandus teksto sujungimas

Kodas
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

Kodas
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.

PHP
use Merql\CellMerge\JsonCellMerger;

$merger = new JsonCellMerger();

Pavyzdys: sklandus JSON sujungimas

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}

Buvo pakeisti skirtingi raktai. Sujungimo rezultatas:

JSON
{"name": "Bob", "role": "admin", "active": true}

Pavyzdys: JSON konfliktas

JSON
// 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.

PHP
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:

PHP
$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:

PHP
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ą:

PHP
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());