
# Darba koki

Git darba koki ļauj vairākām darba direktorijām koplietot vienu repozitoriju. Katram darba kokam ir sava darba kopija (HEAD, indekss, darba faili), bet tas koplieto objektu krātuvi, konfigurāciju un packed-refs ar galveno repozitoriju. Pitmaster var izveidot, uzskaitīt, bloķēt un noņemt saistītos darba kokus, kā arī atvērt tos kā repozitorijus. Darba koku tīrīšana, pārvietošana un labošana nav ieviesta.

## Jēdzieni

Parastam git repozitorijam ir viens darba koks:

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

Izmantojot darba kokus, var pievienot papildu darba kopijas:

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

Saistītā darba koka `.git` ir fails (nevis direktorija), kurā ir relatīvs ceļš uz darba koku:
```
gitdir: ../../path/to/project/.git/worktrees/review
```

## Darba koka izveide

```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()` veic tālāk norādīto:
1. Izveido zaru, ja tas neeksistē (no HEAD vai norādītā `$from` komita)
2. Izveido metadatu direktoriju šeit: `.git/worktrees/<name>/`
3. Ieraksta failu `.git` darba koka direktorijā
4. Ieraksta metadatu failus `HEAD`, `commondir` un `gitdir`
5. Izgūst zara koku darba koka direktorijā
6. Ieraksta darba koka indeksu

Ja zars jau eksistē, `$from` tiek ignorēts. Atšķirībā no git, `addWorktree()` neatsaka zaru, kas jau ir izrakstīts citā darba kokā, un nedarbina `post-checkout` āķi.

### Ar skaidri norādītu metadatu nosaukumu

Izmantojiet izvēles argumentu `name`, ja vairākiem saistītiem darba kokiem var būt vienāds darba kopijas pamata nosaukums.

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

Šis metadatu nosaukums tiek lietots `.git/worktrees/<name>/` vietā, nevis `basename($path)`.

### No konkrēta komita

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

## Darba koku uzskaitīšana

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

Sarakstā vienmēr pirmais ir galvenais darba koks, kam seko saistītie darba koki. Izsauciet `worktrees()` galvenā repozitorija apstrādes objektā: ja to izsauc saistītā darba koka apstrādes objektā, galvenais ieraksts pašlaik uzrāda paša saistītā darba koka ceļu ([#14](https://github.com/inline0/pitmaster/issues/14)).

## Darba koka noņemšana

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

Darba koka noņemšana:
1. Pārbauda, vai darba koks ir bloķēts (neizdodas, ja vien `$force` nav true)
2. Noņem failu `.git` no darba koka direktorijas
3. Noņem metadatu direktoriju no `.git/worktrees/`

Darba koka faili netiek automātiski dzēsti. Zars joprojām pastāv.

## Saistītā darba koka atvēršana

Saistīto darba koku var atvērt tāpat kā jebkuru repozitoriju:

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

Repozitorija darbības ceļus atrisina šādi:
- **Objekti**: lasīšana no kopējā git direktorija un rakstīšana tajā (`project/.git/objects/`)
- **Konfigurācija**: lasīšana no kopējā git direktorija (`project/.git/config`)
- **Packed-refs**: lasīšana no kopējā git direktorija
- **HEAD**: katram darba kokam atsevišķs (katrs darba koks uzskaita savu zaru), tāpat kā `ORIG_HEAD`, `MERGE_HEAD` un citas darbību atsauces
- **Indekss**: katram darba kokam atsevišķs (katram darba kokam ir sava sagatavošanas zona)
- **Vaļīgās atsauces**: zari un tagi tiek koplietoti kopējā direktorijā (`project/.git/refs/`)
- **Āķi**: tiek lasīti no katram darba kokam paredzētā git direktorija, tāpēc koplietotie āķi nedarbojas ([#12](https://github.com/inline0/pitmaster/issues/12))

Pagaidām Stash neapstrādā saistītos darba kokus: tas nolasa identitāti no katram darba kokam paredzētās direktorijas, kurā nav konfigurācijas, un ieraksta tur savu reflog ([#14](https://github.com/inline0/pitmaster/issues/14)).

## Darba koka vērtības objekts

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

Zema līmeņa darba koku pārvaldībai. `WorktreeManager::add()` ieraksta tikai metadatus un failu `.git`: tas neizveido zaru, neizgūst failus no versiju vadības un neieraksta indeksu. Izmantojiet `$repo->addWorktree()`, lai iegūtu lietojamu darba kopiju. Zaram jau jāpastāv (vai arī tam jābūt pilnam atsauces nosaukumam, piemēram, `refs/tags/v1.0.0`, kas atdala HEAD).

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

## Darba koku bloķēšana

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

Bloķēšana tiek glabāta kā fails šeit: `.git/worktrees/<name>/locked`. Faila saturs ir bloķēšanas iemesls (var būt tukšs).

## Darba koku noteikšana

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

## Failu izkārtojums

### Galvenā darba koka metadati saistītajiem darba kokiem

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

### Saistītā darba koka .git fails

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

### Resursu koplietošana

| Resurss | Atrašanās vieta | Koplietots? |
|----------|----------|---------|
| Objekti | `$commonDir/objects/` | Jā |
| Konfigurācija | `$commonDir/config` | Jā |
| Packed-refs | `$commonDir/packed-refs` | Jā |
| Āķi | `$gitDir/hooks/` | Nē: Pitmaster nedarbina koplietotos āķus saistītos darba kokos |
| HEAD | `$gitDir/HEAD` | Nē (katram darba kokam atsevišķs) |
| Indekss | `$gitDir/index` | Nē (katram darba kokam atsevišķs) |
| Vaļīgās atsauces | `$commonDir/refs/` | Jā (HEAD un darbību atsauces, piemēram, `MERGE_HEAD`, ir katram darba kokam atsevišķas) |
