Pāriet uz saturu

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:

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

Izmantojot darba kokus, var pievienot papildu darba kopijas:

Kods
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:

Kods
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).

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)

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

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

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

Kods
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)