
# 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.

```php
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](https://github.com/inline0/merql/issues/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ı](https://merql.inline0.dev/tr/docs/merge/plans) haline getirir:

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

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:

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

Birleştirici çözümleme önceliği:

1. Tam nitelikli sütun adı (`table.column`).
2. Niteliksiz sütun adı (`column`).
3. Sütun türü kalıbı eşleşmesi (büyük/küçük harfe duyarsız `str_contains`).
4. 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.

```php
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.

```php
use Merql\CellMerge\JsonCellMerger;

$merger = new JsonCellMerger();
```

### Örnek: sorunsuz JSON birleştirme

```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}
```

Farklı anahtarlar değiştirildi. Birleştirilmiş sonuç:

```json
{"name": "Bob", "role": "admin", "active": true}
```

### Örnek: JSON çakışması

```json
// 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.

```php
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:

```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
```

Fabrika yöntemleri:

```php
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:

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