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
$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:
- Izveido zaru, ja tas neeksistē (no HEAD vai norādītā
$fromkomita) - Izveido metadatu direktoriju šeit:
.git/worktrees/<name>/ - Ieraksta failu
.gitdarba koka direktorijā - Ieraksta metadatu failus
HEAD,commondirungitdir - Izgūst zara koku darba koka direktorijā
- 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.
$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
$wt = $repo->addWorktree('/tmp/hotfix', 'hotfix/urgent', $repo->resolve('v1.0.0'));
Darba koku uzskaitīšana
$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
$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:
- Pārbauda, vai darba koks ir bloķēts (neizdodas, ja vien
$forcenav true) - Noņem failu
.gitno darba koka direktorijas - 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:
$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_HEADun 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
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).
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
// 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
// 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) |