Hücre Düzeyinde Birleştirme
Sütun düzeyinde birleştirme, her iki tarafın da aynı sütunu değiştirdiğini algılar. Hücre düzeyinde birleştirme daha derine iner ve o sütunun içeriğini birleştirir. TEXT alanının farklı satırlarını veya bir JSON nesnesinin farklı anahtarlarını düzenleyen iki kişi, sorunsuzca birleştirme yapabilir.
use Merql\CellMerge\CellMergeConfig;
use Merql\Merge\ThreeWayMerge;
$config = CellMergeConfig::auto();
$merge = new ThreeWayMerge($config);
$result = $merge->merge($base, $ours, $theirs);
Hücre düzeyinde birleştirmeyi etkinleştirme
Hücre düzeyinde birleştirme isteğe bağlıdır. Yalnızca CellMergeConfig ile oluşturulan bir ThreeWayMerge içinde çalışır. Böyle bir yapılandırma olmadan, her iki tarafın da farklı değerlere değiştirdiği her sütun bir update_update çakışmasıdır.
Merql facade'ı yapılandırma almaz: Merql::merge(), Merql::patch() ve Merql::plan(), new ThreeWayMerge() öğesini yapılandırma olmadan oluşturur; CLI öğesinin merge komutu ise Merql::merge() üzerinden çalışır. Bunlar her zaman sütun düzeyinde birleştirme yapar (#7).
Facade veya CLI tarafından kaydedilen anlık görüntüleri hücre düzeyinde birleştirmek için yükleyin ve ThreeWayMerge öğesini kendiniz çağırın. Sonuç sıradan bir MergeResult olduğundan facade bunu uygulayabilir; MergePlanBuilder ise onu bir birleştirme planı haline getirir:
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);
Hücre birleştiricileri yalnızca her iki tarafın da değiştirdiği sütunlarda çalışır. Sütunu yalnızca bir taraf değiştirdiyse değeri olduğu gibi alınır.
CellMergeConfig
CellMergeConfig sütunları veya sütun türlerini hücre birleştirici uygulamalarına eşler. auto() fabrikası makul varsayılanlar sunar:
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());
Birleştirici çözümleme önceliği:
- Tam nitelikli sütun adı (
table.column). - Niteliksiz sütun adı (
column). - Sütun türü kalıbı eşleşmesi (büyük/küçük harfe duyarsız
str_contains). - Varsayılan:
OpaqueCellMerger(değerler farklı olduğunda her zaman çakışma bildirir).
TextCellMerger
Dosya içeriği için git ile aynı algoritma olan Myers farkını kullanarak çok satırlı metni birleştirir. Her satır bir birim olarak ele alınır ve farklı satırlardaki değişiklikler sorunsuzca birleştirilir.
use Merql\CellMerge\TextCellMerger;
$merger = new TextCellMerger();
Örnek: sorunsuz metin birleştirme
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
Farklı satırlar düzenlendi. Birleştirme, çakışma olmadan "LINE ONE\nline two\nLINE THREE" üretir.
Örnek: metin çakışması
Base: "line one\nline two"
Ours: "changed by us\nline two" // changed line 1
Theirs: "changed by them\nline two" // also changed line 1
Her iki taraf da aynı satırı farklı değerlere değiştirdi. Birleştirici bir çakışma sonucu döndürür. Birleştirilen içerik, git benzeri çakışma işaretçileri içerir.
Nasıl çalışır
TextCellMerger, pitmaster'ın ThreeWayMerge::merge() öğesini kullanır. Bu, base ile her bir taraf arasındaki Myers farkını hesaplar ve ardından iki düzenleme betiğini birleştirir. Düzenlemeler aynı satır bölgesinde çakıştığında bir çakışma bildirir.
JsonCellMerger
JSON nesnelerini, üst düzey anahtarları ayrı ayrı karşılaştırarak birleştirir. Her anahtar standart üç yönlü kurallarla birleştirilir.
use Merql\CellMerge\JsonCellMerger;
$merger = new JsonCellMerger();
Örnek: sorunsuz JSON birleştirme
// 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}
Farklı anahtarlar değiştirildi. Birleştirilmiş sonuç:
{"name": "Bob", "role": "admin", "active": true}
Örnek: JSON çakışması
// Base
{"color": "red"}
// Ours
{"color": "blue"}
// Theirs
{"color": "green"}
Her iki taraf da color anahtarını farklı değerlere değiştirdi. Bu bir çakışmadır. Birleştirici varsayılan olarak ours değerini kullanır ve bir çakışma bildirir.
Anahtar düzeyindeki kurallar
| Temel | Ours | Theirs | Sonuç |
|---|---|---|---|
| Anahtar değişmedi | Anahtar değişmedi | Temel kabul edilir | |
| Anahtar değişmedi | Anahtar değişti | Theirs kabul edilir | |
| Anahtar değişti | Anahtar değişmedi | Ours kabul edilir | |
| Anahtar değişti (aynı) | Anahtar değişti (aynı) | Kabul edilir (aynı fikirde) | |
| Anahtar değişti (farklı) | Anahtar değişti (farklı) | Çakışma (varsayılan: ours) | |
| Anahtar mevcut | Anahtar mevcut | Anahtar kaldırıldı | Kaldırma kabul edilir |
| Anahtar mevcut | Anahtar kaldırıldı | Anahtar mevcut | Kaldırma kabul edilir |
| Anahtar eksik | Anahtar eklendi | Anahtar eksik | Ekleme kabul edilir |
| Anahtar eksik | Anahtar eksik | Anahtar eklendi | Ekleme kabul edilir |
İç içe nesneler, özyinelemeli olarak değil, opak JSON dizeleri olarak karşılaştırılır. İç içe bir nesne farklıysa, alt anahtarları değil, anahtarın tüm değeri karşılaştırılır.
Gereksinimler
Üç değerin tümü geçerli JSON nesneleri veya dizileri olmalıdır. Herhangi bir değer geçerli JSON değilse ya da JSON skaler bir değerse (dize, sayı, boolean), birleştirici çakışma çözümüne geri döner.
OpaqueCellMerger
Hücre düzeyinde bir strateji yapılandırılmadığında kullanılan varsayılan birleştirici. Sütun değerini opak bir blok olarak ele alır ve her iki taraf farklı olduğunda daima çakışma bildirir.
use Merql\CellMerge\OpaqueCellMerger;
$merger = new OpaqueCellMerger();
$result = $merger->merge($base, $ours, $theirs);
// $result->clean is always false when $ours !== $theirs
CellMergeResult
Tüm hücre birleştiricileri bir CellMergeResult döndürür:
$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
Fabrika yöntemleri:
CellMergeResult::resolved($value); // clean merge
CellMergeResult::conflict($oursValue, $n); // n conflicts, defaults to ours
Özel hücre birleştiricileri
Kendi birleştirme stratejinizi eklemek için CellMerger arayüzünü uygulayın:
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());