
# Worktree'ler

Git worktree'ler, birden fazla çalışma dizininin tek bir depoyu paylaşmasını sağlar. Her worktree'nin kendi teslim alımı (HEAD, dizin, çalışma dosyaları) vardır; ancak nesne deposunu, yapılandırmayı ve paketlenmiş refs'leri ana depoyla paylaşır. Pitmaster bağlantılı worktree'ler oluşturabilir, listeleyebilir, kilitleyebilir ve kaldırabilir; ayrıca bunları depo olarak açabilir. Budama, taşıma ve worktree onarma işlemleri uygulanmamıştır.

## Kavramlar

Normal bir git deposunun tek bir çalışma ağacı vardır:

```
project/
  .git/          (directory)
  src/
  README.md
```

Çalışma ağaçlarıyla ek checkout'lar oluşturabilirsiniz:

```
project/                          (main worktree)
  .git/                           (the actual git directory)
    worktrees/
      review/                     (metadata for linked worktree)
        HEAD
        commondir
        gitdir

/tmp/review/                      (linked worktree)
  .git                            (file, not directory)
  src/
  README.md
```

Bağlı çalışma ağacının `.git` dosyası, çalışma ağacına göreli bir yol içeren (dizin olmayan) bir dosyadır:
```
gitdir: ../../path/to/project/.git/worktrees/review
```

## Çalışma ağacı oluşturma

```php
$repo = Pitmaster::open('/path/to/project');

// Create a linked worktree on a new branch
$wt = $repo->addWorktree('/tmp/review', 'feature/review');

echo $wt->path;        // '/tmp/review'
echo $wt->branch;      // 'feature/review'
echo $wt->gitDir;      // '/path/to/project/.git/worktrees/review'
var_dump($wt->isMain);      // bool(false)
var_dump($wt->isDetached);  // bool(false)
```

`addWorktree()` şunları yapar:
1. Dal mevcut değilse oluşturur (HEAD'den veya belirtilen `$from` commit'inden)
2. Üstveri dizinini `.git/worktrees/<name>/` konumunda oluşturur
3. Çalışma ağacı dizininde `.git` dosyasını yazar
4. `HEAD`, `commondir` ve `gitdir` üstveri dosyalarını yazar
5. Dalın ağacını çalışma ağacı dizinine checkout eder
6. Çalışma ağacı için indeksi yazar

Dal zaten varsa `$from` yok sayılır. git'den farklı olarak `addWorktree()`, başka bir çalışma ağacında zaten checkout edilmiş bir dalı reddetmez ve `post-checkout` hook'unu çalıştırmaz.

### Açık bir üstveri adıyla

Birden fazla bağlı çalışma ağacı aynı checkout temel adını paylaşabiliyorsa isteğe bağlı `name` bağımsız değişkenini kullanın.

```php
$wt = $repo->addWorktree(
    '/tmp/sandboxes/app',
    'feature/review',
    name: 'sandbox-app',
);
```

Bu üstveri adı, `basename($path)` yerine `.git/worktrees/<name>/` altında kullanılır.

### Belirli bir commit'ten

```php
$wt = $repo->addWorktree('/tmp/hotfix', 'hotfix/urgent', $repo->resolve('v1.0.0'));
```

## Çalışma ağaçlarını listeleme

```php
$worktrees = $repo->worktrees();

foreach ($worktrees as $wt) {
    $type = $wt->isMain ? 'main' : 'linked';
    $branch = $wt->branch ?? 'detached';
    $locked = $wt->isLocked ? ' [locked]' : '';

    echo "{$wt->path} ({$type}) [{$branch}]{$locked}\n";
}
```

Liste her zaman önce ana çalışma ağacını, ardından bağlı çalışma ağaçlarını içerir. Ana depo için bir tanıtıcıda `worktrees()` çağırın: bağlı bir çalışma ağacı tanıtıcısında ana girdi, şu anda bağlı çalışma ağacının kendi yolunu bildirir ([#14](https://github.com/inline0/pitmaster/issues/14)).

## Çalışma ağacını kaldırma

```php
$repo->removeWorktree('review');          // by metadata name
$repo->removeWorktree('/tmp/review');     // or by worktree path

// Force remove (even if locked)
$repo->removeWorktree('review', force: true);
```

Bir çalışma ağacını kaldırma:
1. Çalışma ağacının kilitli olup olmadığını denetler (`$force` true değilse başarısız olur)
2. Çalışma ağacı dizininden `.git` dosyasını kaldırır
3. Üstveri dizinini `.git/worktrees/` konumundan kaldırır

Çalışma ağacı dosyaları otomatik olarak silinmez. Dal varlığını sürdürür.

## Bağlı çalışma ağacını açma

Bağlı bir çalışma ağacını herhangi bir depo gibi açabilirsiniz:

```php
$repo = Pitmaster::open('/tmp/review');

// Pitmaster detects the .git file and follows the gitdir reference
echo $repo->isLinkedWorktree();  // true
echo $repo->gitDir();            // '/path/to/project/.git/worktrees/review'
echo $repo->commonGitDir();      // '/path/to/project/.git'
echo $repo->workDir();           // '/tmp/review'
```

Depo işlemleri yolları şu şekilde çözümler:
- **Nesneler**: ortak git dizininden okunur ve bu dizine yazılır (`project/.git/objects/`)
- **Yapılandırma**: ortak git dizininden okunur (`project/.git/config`)
- **Packed-refs**: ortak git dizininden okunur
- **HEAD**: çalışma ağacı başınadır (her çalışma ağacı kendi dalını izler); ayrıca `ORIG_HEAD`, `MERGE_HEAD` ve diğer işlem ref'leri de böyledir
- **İndeks**: çalışma ağacı başınadır (her çalışma ağacının kendi hazırlama alanı vardır)
- **Gevşek ref'ler**: dallar ve etiketler ortak dizinde paylaşılır (`project/.git/refs/`)
- **Hook'lar**: çalışma ağacına özel git dizininden okunur; bu nedenle paylaşılan hook'lar çalıştırılmaz ([#12](https://github.com/inline0/pitmaster/issues/12))

Stash henüz bağlı çalışma ağaçlarını desteklemiyor: kimliği çalışma ağacına özel yapılandırma içermeyen dizinden okuyor ve reflog'unu oraya yazıyor ([#14](https://github.com/inline0/pitmaster/issues/14)).

## Worktree değer nesnesi

```php
use Pitmaster\Worktree\Worktree;

$wt->name;          // Metadata name (null for the main worktree)
$wt->path;          // Working directory path
$wt->gitDir;        // Per-worktree git dir
$wt->branch;        // Branch name (null if detached)
$wt->head;          // ObjectId of HEAD commit
$wt->isMain;        // true for the main worktree
$wt->isDetached;    // true if HEAD is detached
$wt->isLocked;      // true if worktree is locked
$wt->lockReason;    // Lock reason, or null when there is none (an empty reason is also null)
```

## WorktreeManager

Düşük seviyeli çalışma ağacı yönetimi içindir. `WorktreeManager::add()` yalnızca üstveriyi ve `.git` dosyasını yazar; dal oluşturmaz, dosyaları checkout etmez veya indeks yazmaz. Kullanılabilir bir checkout için `$repo->addWorktree()` kullanın. Dal önceden var olmalıdır (veya HEAD'i ayıran `refs/tags/v1.0.0` gibi tam bir ref adı olmalıdır).

```php
use Pitmaster\Worktree\WorktreeManager;

$manager = new WorktreeManager($repo->commonGitDir(), $mainWorkDir);

// List
$worktrees = $manager->list();

// Add
$wt = $manager->add('/tmp/review', 'feature/review');
$wt = $manager->add('/tmp/review', 'feature/review', 'review-app');

// Remove
$manager->remove('review');
$manager->remove('review', force: true);

// Lock/unlock (metadata name only)
$manager->lock('review', 'Do not delete, code review in progress');
$manager->unlock('review');
```

## Çalışma ağaçlarını kilitleme

```php
// Lock (prevents removal)
$manager->lock('review', 'Code review in progress');

// Attempt to remove locked worktree
try {
    $manager->remove('review');
} catch (\RuntimeException $e) {
    // "Worktree is locked: review (Code review in progress)"
}

// Force remove ignores the lock
$manager->remove('review', force: true);

// Unlock
$manager->unlock('review');
```

Kilit, `.git/worktrees/<name>/locked` konumunda bir dosya olarak saklanır. Dosyanın içeriği kilit nedenidir (boş olabilir).

## Çalışma ağaçlarını algılama

```php
// Check if a path is a linked worktree
if (Pitmaster::isWorktree('/tmp/review')) {
    echo "This is a linked worktree\n";
}

// Resolve the common git dir from any path
$common = Pitmaster::commonGitDir('/tmp/review');
// '/path/to/project/.git'

// Resolve a .git file to the actual git directory
$gitDir = WorktreeManager::resolveGitFile('/tmp/review');
// '/path/to/project/.git/worktrees/review'
```

## Dosya düzeni

### Bağlı çalışma ağaçları için ana çalışma ağacı üstverisi

```
.git/worktrees/<name>/
  HEAD         Per-worktree HEAD (symbolic ref or detached hash)
  commondir    Relative path to the shared git dir ("../..")
  gitdir       Path back to the worktree's .git file, as passed to addWorktree()
  locked       Present if locked (content = reason)
  index        Per-worktree index/staging area
```

### Bağlı çalışma ağacının .git dosyası

```
gitdir: <relative path to>/project/.git/worktrees/<name>
```

### Kaynak paylaşımı

| Kaynak | Konum | Paylaşılıyor mu? |
|----------|----------|---------|
| Nesneler | `$commonDir/objects/` | Evet |
| Yapılandırma | `$commonDir/config` | Evet |
| Packed-refs | `$commonDir/packed-refs` | Evet |
| Hook'lar | `$gitDir/hooks/` | Hayır: Pitmaster bağlı çalışma ağaçlarında paylaşılan hook'ları çalıştırmaz |
| HEAD | `$gitDir/HEAD` | Hayır (çalışma ağacı başına) |
| İndeks | `$gitDir/index` | Hayır (çalışma ağacı başına) |
| Gevşek ref'ler | `$commonDir/refs/` | Evet (HEAD ve `MERGE_HEAD` gibi işlem ref'leri çalışma ağacı başınadır) |
