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.
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:
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:
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:
- Täysin määritetty sarakkeen nimi (
table.column). - Määrittämätön sarakkeen nimi (
column). - Saraketyypin mallivastaavuus (kirjainkoosta riippumaton
str_contains). - 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.
use Merql\CellMerge\TextCellMerger;
$merger = new TextCellMerger();
Esimerkki: ristiriidaton tekstin yhdistäminen
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
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ä.
use Merql\CellMerge\JsonCellMerger;
$merger = new JsonCellMerger();
Esimerkki: ristiriidaton JSON-yhdistäminen
// 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:
{"name": "Bob", "role": "admin", "active": true}
Esimerkki: JSON-ristiriita
// 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.
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:
$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:
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:
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());