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.
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:
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:
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:
- Täielikult kvalifitseeritud veerunimi (
table.column). - Kvalifitseerimata veerunimi (
column). - Veerutüübi mustrile vastavus (tõstutundetu
str_contains). - 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.
use Merql\CellMerge\TextCellMerger;
$merger = new TextCellMerger();
Näide: puhas tekstiühendamine
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
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.
use Merql\CellMerge\JsonCellMerger;
$merger = new JsonCellMerger();
Näide: puhas JSON-ühendamine
// 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:
{"name": "Bob", "role": "admin", "active": true}
Näide: JSON-konflikt
// 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.
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:
$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:
CellMergeResult::resolved($value); // clean merge
CellMergeResult::conflict($oursValue, $n); // n conflicts, defaults to ours
Kohandatud lahtriliitjad
Oma liitmisstrateegia lisamiseks rakendage liidest CellMerger:
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());