Liigu sisu juurde

Lahtritasemel ühendamine

Veerutasemel ühendamine tuvastab, kui mõlemad pooled muutsid sama veergu. Lahtritasemel ühendamine läheb sügavamale ja ühendab selle veeru sisu. Kaks inimest saavad muuta puhtalt sama TEXT-välja eri ridu või JSON-objekti eri võtmeid.

PHP
use Merql\CellMerge\CellMergeConfig;
use Merql\Merge\ThreeWayMerge;

$config = CellMergeConfig::auto();
$merge = new ThreeWayMerge($config);
$result = $merge->merge($base, $ours, $theirs);

Lahtritasemel ühendamise lubamine

Lahtritasemel ühendamine on valikuline. See töötab ainult CellMergeConfig abil loodud ThreeWayMerge puhul. Ilma selleta tekitab iga veerg, mida mõlemad pooled on eri väärtuseks muutnud, konflikti update_update.

Merql-fassaad ei võta seadistust vastu: Merql::merge(), Merql::patch() ja Merql::plan() loovad new ThreeWayMerge() ilma selleta ning CLI käsk merge kaudu kasutab Merql::merge()-i. Need ühendavad alati veerutasemel (#7).

Fassaadi või CLI abil salvestatud hetktõmmiste ühendamiseks lahtritasemel laadige need ja kutsuge ise välja ThreeWayMerge. Tulemuseks on tavaline MergeResult, seega saab fassaad seda endiselt rakendada ja MergePlanBuilder muudab selle ühendamisplaaniks:

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

Lahtrite ühendajad töötavad ainult nende veergude puhul, mida mõlemad pooled muutsid. Kui veergu muutis ainult üks pool, kasutatakse selle väärtust muutmata kujul.

CellMergeConfig

CellMergeConfig seostab veerud või veerutüübid lahtriühendajate teostustega. Tehas auto() pakub sobivaid vaikeväärtusi:

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

Ühendaja valimise tähtsusjärjekord:

  1. Täielikult kvalifitseeritud veerunimi (table.column).
  2. Kvalifitseerimata veerunimi (column).
  3. Veerutüübi mustrile vastavus (tõstutundetu str_contains).
  4. Vaikeväärtus: OpaqueCellMerger (annab alati konflikti, kui väärtused erinevad).

TextCellMerger

Ühendab mitmerealise teksti Myersi erinevuste leidmise algoritmiga, mida git kasutab failisisu jaoks. Iga rida käsitletakse eraldi ühikuna ning eri ridade muudatused ühendatakse puhtalt.

PHP
use Merql\CellMerge\TextCellMerger;

$merger = new TextCellMerger();

Näide: puhas tekstiühendamine

Kood
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

Muudeti eri ridu. Ühendamise tulemuseks on "LINE ONE\nline two\nLINE THREE" ilma konfliktita.

Näide: tekstikonflikt

Kood
Base:    "line one\nline two"
Ours:    "changed by us\nline two"     // changed line 1
Theirs:  "changed by them\nline two"   // also changed line 1

Mõlemad pooled muutsid sama rea väärtuse erinevaks. Ühendaja tagastab konfliktitulemuse. Ühendatud sisu sisaldab git-i omadega sarnaseid konfliktimarkereid.

Kuidas see töötab

TextCellMerger kasutab pitmasteri ThreeWayMerge::merge()-i, mis arvutab baasi ja kummagi poole vahel Myersi erinevused ning ühendab seejärel kaks muudatuste skripti. Kui muudatused kattuvad samas reapiirkonnas, teatatakse konfliktist.

JsonCellMerger

Ühendab JSON-objekte, võrreldes ülataseme võtmeid ükshaaval. Iga võti ühendatakse tavaliste kolmeosalise ühendamise reeglite järgi.

PHP
use Merql\CellMerge\JsonCellMerger;

$merger = new JsonCellMerger();

Näide: puhas JSON-ühendamine

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}

Muutusid erinevad võtmed. Ühendatud tulemus on järgmine:

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

Näide: JSON-konflikt

JSON
// Base
{"color": "red"}

// Ours
{"color": "blue"}

// Theirs
{"color": "green"}

Mõlemad pooled muutsid võtme color väärtuse erinevaks. Tekib konflikt. Vaikimisi eelistab ühendaja meiepoolset väärtust ja teatab ühest konfliktist.

Võtmetaseme reeglid

Baas Meiepoolne Teine pool Tulemus
Võti muutmata Võti muutmata Võetakse baasi väärtus
Võti muutmata Võtit muudeti Võetakse teise poole väärtus
Võtit muudeti Võti muutmata Võetakse meiepoolne väärtus
Võtit muudeti (sama) Võtit muudeti (sama) Võetakse ühine väärtus
Võtit muudeti (erinevaks) Võtit muudeti (erinevaks) Konflikt (vaikimisi: meiepoolne väärtus)
Võti olemas Võti olemas Võti eemaldatakse
Võti olemas Võti eemaldati Võti olemas Võti eemaldatakse
Võti puudub Võti lisati Võti puudub Võti lisatakse
Võti puudub Võti puudub Võti lisati Võti lisatakse

Pesastatud objekte võrreldakse läbipaistmatute JSON-stringidena, mitte rekursiivselt. Kui pesastatud objekt erineb, võrreldakse kogu võtme väärtust, mitte selle alamvõtmeid.

Nõuded

Kõik kolm väärtust peavad olema kehtivad JSON-objektid või massiivid. Kui mõni väärtus pole kehtiv JSON või on JSON-skalaar (string, arv või tõeväärtus), kasutab ühendaja konflikti korral varukäitumist.

OpaqueCellMerger

Vaikimisi liitja, mida kasutatakse siis, kui lahtritaseme strateegiat pole seadistatud. See käsitleb veeru väärtust läbipaistmatu andmeplokina ja teatab alati konfliktist, kui mõlemad pooled erinevad.

PHP
use Merql\CellMerge\OpaqueCellMerger;

$merger = new OpaqueCellMerger();
$result = $merger->merge($base, $ours, $theirs);
// $result->clean is always false when $ours !== $theirs

CellMergeResult

Kõik lahtriliitjad tagastavad 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

Tehasemeetodid:

PHP
CellMergeResult::resolved($value);           // clean merge
CellMergeResult::conflict($oursValue, $n);   // n conflicts, defaults to ours

Kohandatud lahtriliitjad

Oma liitmisstrateegia lisamiseks rakendage liidest CellMerger:

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