Siirry sisältöön

Solutason yhdistäminen

Saraketason yhdistäminen havaitsee, kun molemmat puolet ovat muuttaneet samaa saraketta. Solutason yhdistäminen menee syvemmälle ja yhdistää kyseisen sarakkeen sisällön. Kahden henkilön eri riveihin tekemät muutokset TEXT-kentässä tai eri avaimiin tekemät muutokset JSON-objektissa voidaan yhdistää ongelmitta.

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

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

Solutason yhdistämisen käyttöönotto

Solutason yhdistäminen on valinnainen. Se toimii vain CellMergeConfig-määrityksellä luodussa kohteessa ThreeWayMerge. Ilman sitä jokainen sarake, jonka molemmat puolet muuttivat eri arvoiksi, aiheuttaa update_update-ristiriidan.

Merql-julkisivu ei ota asetuksia: Merql::merge(), Merql::patch() ja Merql::plan() luovat new ThreeWayMerge()-instanssin ilman niitä, ja CLI-ohjelman merge-komento kulkee Merql::merge()-kohteen kautta. Ne yhdistävät aina vain saraketasolla (#7).

Jos haluat yhdistää julkisivulla tai CLI-ohjelmalla tallennettuja tilannevedoksia solutason yhdistämisellä, lataa ne ja kutsu itse ThreeWayMerge-toimintoa. Tulos on tavallinen MergeResult, joten julkisivu voi yhä käyttää sitä, ja MergePlanBuilder muuntaa sen yhdistämissuunnitelmaksi:

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

Soluyhdistimet suoritetaan vain sarakkeille, joita molemmat puolet ovat muuttaneet. Jos vain toinen puoli muutti saraketta, sen arvo otetaan sellaisenaan.

CellMergeConfig

CellMergeConfig yhdistää sarakkeet tai saraketyypit soluyhdistimen toteutuksiin. auto()-tehdas tarjoaa järkevät oletusarvot:

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

Yhdistimen valintajärjestys:

  1. Täysin määritetty sarakkeen nimi (table.column).
  2. Määrittämätön sarakkeen nimi (column).
  3. Saraketyypin mallivastaavuus (kirjainkoosta riippumaton str_contains).
  4. Oletusarvo: OpaqueCellMerger (ilmoittaa aina ristiriidan, kun arvot eroavat).

TextCellMerger

Yhdistää monirivistä tekstiä Myers-erotusalgoritmilla, samalla algoritmilla, jota git käyttää tiedostosisällölle. Kukin rivi käsitellään yhtenä yksikkönä, ja eri riveihin tehdyt muutokset yhdistyvät ongelmitta.

PHP
use Merql\CellMerge\TextCellMerger;

$merger = new TextCellMerger();

Esimerkki: ristiriidaton tekstin yhdistäminen

Koodi
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

Eri rivejä muokattiin. Yhdistäminen tuottaa tuloksen "LINE ONE\nline two\nLINE THREE" ilman ristiriitaa.

Esimerkki: tekstiristiriita

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

Molemmat puolet muuttivat saman rivin eri arvoiksi. Yhdistin palauttaa ristiriitatuloksen. Yhdistetty sisältö sisältää gitin kaltaiset ristiriitamerkinnät.

Näin se toimii

TextCellMerger käyttää pitmasterin ThreeWayMerge::merge()-toteutusta, joka laskee Myers-erotuksen basen ja kummankin puolen välillä ja yhdistää sitten muokkauskomentosarjat. Jos muokkaukset menevät päällekkäin samalla rivialueella, tuloksena ilmoitetaan ristiriita.

JsonCellMerger

Yhdistää JSON-objektit vertaamalla ylimmän tason avaimia erikseen. Kukin avain yhdistetään tavanomaisilla kolmen osapuolen säännöillä.

PHP
use Merql\CellMerge\JsonCellMerger;

$merger = new JsonCellMerger();

Esimerkki: ristiriidaton JSON-yhdistäminen

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}

Eri avaimia muutettiin. Yhdistetty tulos on:

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

Esimerkki: JSON-ristiriita

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

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

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

Molemmat puolet muuttivat avaimen color eri arvoiksi. Kyseessä on ristiriita. Yhdistin valitsee oletusarvoisesti ours-puolen ja ilmoittaa yhden ristiriidan.

Avaintason säännöt

Lähtötila Ours Theirs Tulos
Avain ennallaan Avain ennallaan Hyväksy lähtötila
Avain ennallaan Avain muuttunut Hyväksy theirs
Avain muuttunut Avain ennallaan Hyväksy ours
Avain muuttunut (sama) Avain muuttunut (sama) Hyväksy (samaa mieltä)
Avain muuttunut (eri) Avain muuttunut (eri) Ristiriita (oletus: ours)
Avain on olemassa Avain on olemassa Avain poistettu Hyväksy poisto
Avain on olemassa Avain poistettu Avain on olemassa Hyväksy poisto
Avain puuttuu Avain lisätty Avain puuttuu Hyväksy lisäys
Avain puuttuu Avain puuttuu Avain lisätty Hyväksy lisäys

Sisäkkäisiä objekteja verrataan käsittelemällä niitä läpinäkymättöminä JSON-merkkijonoina, ei rekursiivisesti. Jos sisäkkäinen objekti eroaa, verrataan kyseisen avaimen koko arvoa, ei sen aliavaimia.

Vaatimukset

Kaikkien kolmen arvon on oltava kelvollisia JSON-objekteja tai taulukoita. Jos jokin arvo ei ole kelvollista JSON-dataa tai on JSON-tyyppinen alkeisarvo (merkkijono, luku tai totuusarvo), yhdistin palautuu ristiriitaan.

OpaqueCellMerger

Oletusyhdistin, kun solutason strategiaa ei ole määritetty. Se käsittelee sarakkeen arvoa läpinäkymättömänä tietona ja ilmoittaa aina ristiriidasta, kun molemmat puolet ovat muuttaneet arvoa eri tavalla.

PHP
use Merql\CellMerge\OpaqueCellMerger;

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

CellMergeResult

Kaikki soluyhdistimet palauttavat arvon 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

Tehdasmetodit:

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

Mukautetut soluyhdistimet

Toteuta rajapinta CellMerger lisätäksesi oman yhdistämisstrategiasi:

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