Організація виконання
Worktrees та ізольовані середовища
У главі 45 ми простежили шлях зміни від наміру до злиття, а глава 46 показала, як домовитися з агентом про результат, межі й докази. Тут розглянемо…
У главі 45 ми простежили шлях зміни від наміру до злиття, а глава 46 показала, як домовитися з агентом про результат, межі й докази. Тут розглянемо фізичне та технічне середовище, у якому працює агент. Це продовження контракту завдання: вкажіть не лише репозиторій і гілку, а й те, які файли, процеси, дані та облікові записи виконавець справді має окремими.
Навчальний результат. Після цієї глави читач може пояснити, що саме Git worktree ізолює, які стани лишаються спільними, чим worktree відрізняється від гілки, звичайного клону, контейнера та пісочниці, і як перевірити межі перед паралельною роботою. Здатність назвати конкретний ресурс важливіша за загальне твердження «агенти працюють ізольовано».
Передумови й межі. Глава спирається на поняття гілки, коміту, незбережених змін і перевірки результату з попередніх розділів. Вона не є переліком команд для запам’ятовування й не описує запуск чи видалення реальних середовищ. Розділ 58 розгляне керування середовищами продукту ширше; тут зосередимося на різниці між файловою копією, Git-станом, процесом і зовнішніми ресурсами.
47.1. Ізоляція завжди стосується конкретної межі
Слово «ізольований» неповне без відповіді на питання: ізольований від чого саме? Worktree може відокремити файли однієї гілки від файлів іншої, але не створює автоматично окремої бази даних, користувача операційної системи, мережевого простору чи хмарного облікового запису. І навпаки, контейнер може окремо запускати програму, але його змонтований каталог може лишатися спільним із хостом.
| Шар | Що зазвичай відокремлено | Що може лишатися спільним |
|---|---|---|
| Гілка Git | Вказівник на іншу вершину історії комітів | Файли в тому самому робочому дереві та незбережені зміни |
| Worktree Git | Checkout-файли, індекс і поточний HEAD кожної робочої копії |
Більшість сховища об’єктів, посилань, конфігурації репозиторію та всі зовнішні ресурси |
| Звичайний клон | Директорія репозиторію та його локальні Git-метадані | Віддалений репозиторій, спільні сервіси, користувачі й локальні кеші |
| Контейнер | Налаштований файловий простір процесу та частина його середовища виконання | Змонтовані каталоги, опубліковані порти, передані облікові дані та доступні служби |
| Пісочниця | Ті дозволи на файли, мережу чи команди, які встановлено політикою | Усе, що політика дозволила; сама назва не визначає набір дозволів |
| Зовнішній сервіс | Лише окремі облікові записи, простори імен або екземпляри, які справді створили | База даних, черга, сховище файлів чи програмний інтерфейс застосунку (API, application programming interface), якщо обидва виконавці мають до них доступ |
Це не рейтинг надійності інструментів. Кожен механізм розв’язує іншу задачу. Для контракту корисніше записати «окрема копія файлів, спільна тестова база та спільний порт сервера», ніж назвати середовище просто ізольованим.
47.2. Що відокремлює Git worktree
Гілка — рухоме посилання на вершину послідовності комітів. Робоче дерево — файли репозиторію на диску: певний checkout та можливі незбережені зміни. Worktree — це робоче дерево разом із Git-метаданими, потрібними саме цій копії.
Зазвичай Git має одне основне робоче дерево та може мати кілька пов’язаних робочих дерев. Кожне linked worktree має власні файли checkout, індекс і HEAD — назву, якою Git позначає поточну ревізію в цьому робочому дереві. Тому незбережене редагування settings.py в одній директорії не перезаписує файл з такою самою назвою в іншій. Коміт також створюється в конкретному робочому дереві, хоча новий Git-об’єкт одразу належить спільному локальному сховищу цього репозиторію.
При цьому worktree — не клон репозиторію в мініатюрі. Робочі дерева спільно використовують більшість Git-даних, зокрема сховище комітів і файлів. Більшість посилань на гілки спільні; окремий HEAD кожного дерева вказує, яку ревізію воно зараз показує. Конфігурація репозиторію за замовчуванням теж спільна. Git підтримує спеціальне налаштування окремої конфігурації worktree, але це опція з умовами сумісності, а не автоматична поведінка (довідник git worktree).
Є практичне обмеження: одну й ту саму локальну гілку зазвичай не можна одночасно зробити поточною у двох worktree. Це захищає від непорозуміння, коли два робочі дерева змагалися б за зміну одного вказівника гілки. Окремі worktree мають працювати з окремими гілками або окремими ревізіями без прикріпленої гілки; сам вибір базової ревізії все одно треба зафіксувати.
Клон дає іншу межу. Звичайний git clone створює окрему директорію репозиторію зі своїми локальними Git-метаданими й налаштуванням віддаленого репозиторію. Щоб побачити коміти з іншого клону, зазвичай треба їх отримати з віддаленого сховища або надіслати туди. Worktree економить місце та повторне отримання історії, коли потрібні кілька checkout одного локального репозиторію; клон краще відокремлює Git-конфігурацію та локальну історію. Це компроміс, а не універсальна перевага: звичайний клон теж не створює окремий сервер, базу даних чи обліковий запис. Спеціальні варіанти клонування можуть повторно використовувати сховище об’єктів, тому слово «клон» саме по собі також не гарантує повної фізичної незалежності.
Важливо розрізняти видимість коміту й видимість файлу. Два worktree можуть бачити спільний Git-об’єкт та різні гілки. Якщо агент в одному робочому дереві створив коміт, інша директорія не переписується автоматично й лишається на своєму checkout. Щоб інтегрувати зміну, її гілку треба звести з цільовою через обраний командою спосіб і перевірити отриманий стан.
47.3. База ревізії та локальний стан
Два агенти, які почали з однієї гілки, можуть мати різні підстави для висновку. До створення worktree зафіксуйте базову ревізію: наприклад, ідентифікатор коміту, з якого почалася робота. Назва main може надалі пересунутися. Запис на кшталт «почав з main» не відповідає, який саме код агент бачив.
Окрема папка не відновлює автоматично все середовище. Файл залежностей і його lockfile можуть бути закомічені, але встановлені пакети, скомпільовані артефакти й кеші часто ігноруються Git. У новому worktree їх може не бути. Якщо їх скопіювали чи встановили, кеш пакетного менеджера може бути спільним на рівні користувача, як і глобально встановлена версія середовища виконання. Символічне посилання чи спільний директорійний кеш здатні пов’язати вміст, який на перший погляд здавався локальним.
Згенерований каталог може бути окремим у кожній копії, тоді як налаштування збірки вказує обидві копії в один і той самий абсолютний шлях поза репозиторієм. І навпаки, локальна залежність у кожній папці може відрізнятися, хоча обидва агенти почали з однакового lockfile. Умова «обидва агенти на тій самій гілці» не доводить тотожності повного середовища.
Ігноровані локальні файли — окрема пастка. Git не включає їх у коміти, тому типовий checkout нового робочого дерева не гарантує наявності .env, локальної бази SQLite чи власного сертифіката. Codex Desktop і Claude Desktop описують копіювання файлів, перелічених у .worktreeinclude, для керованих сценаріїв; у Codex це стосується лише локальних desktop worktree, а не віддалених чи створених вручну через Git (Codex worktrees, Claude Desktop). Це поведінка клієнта, не Git. Передавати секрети слід свідомо: копія файла не створює нового ключа, користувача чи межі доступу. Окремі текстові конфігурації можуть указувати на той самий зовнішній обліковий запис.
Для двох паралельних агентів визначте не просто «однакові залежності», а потрібний рівень відтворюваності: який файл фіксує версії, як готуються встановлені залежності, що треба генерувати, чи є кеш спільним і які змінні конфігурації вказують на локальні або спільні ресурси. Якщо підготовка нового worktree запускає продуктову setup-процедуру, її поведінка належить до налаштувань конкретного клієнта, а не до Git.
47.4. Процеси, порти й зовнішні дані
Worktree створює робочу копію, але не запускає кожен процес у власній операційній системі. Два агенти можуть підняти сервери на одному комп’ютері й попросити їх слухати той самий порт. Перший процес може зайняти його, а другий — завершитися з помилкою або непомітно під’єднати перевірку до вже запущеного сервера. Перевірка, яка повернула сторінку з потрібним текстом, не доводить, що відповідь надійшла з нового коду.
Подібне відбувається з фоновими серверами, збиранням, блокуванням файлів, тимчасовими файлами і кешами, створеними поза checkout. Локальна адреса localhost означає мережевий простір поточної машини чи контейнера, залежно від налаштування; кілька процесів у тому самому мережевому просторі все одно можуть конкурувати за порт. Окремі мережеві простори контейнерів змінюють картину, але опублікований назовні порт теж потребує унікального розподілу. Переконайтеся, який процес працює, звідки він запущений і до якого каталогу звертається; не зупиняйте невідомий процес тільки через те, що він слухає очікуваний порт.
Найочевидніший спільний стан часто стоїть поза Git зовсім. Два набори файлів можуть звертатися до однієї бази даних, черги повідомлень, сховища об’єктів, зовнішнього програмного інтерфейсу застосунку чи тестового облікового запису. Тоді застосування міграції, очищення таблиць або обробка черги з однієї копії впливає на іншу.
Відокремлення зовнішніх даних може вимагати окремої тестової бази або ізольованої схеми, унікального простору імен для черги й файлів, спеціальних тестових облікових даних, малих контрольованих fixtures — підготовлених даних для перевірки — та явного прибирання. Важлива межа — саме та послуга, на яку вказує конфігурація. Окрема схема не допоможе, якщо міграція змінює спільну схему; окрема назва бази не допоможе, якщо змінна середовища все одно переадресована на спільний сервер з іншим ідентифікатором; тестова черга не ізолює спільне сховище файлів.
Те саме стосується прав доступу. Два файли .env можуть містити один і той самий ключ. Два агенти можуть діяти від імені одного хмарного користувача або надсилати запити у спільне тестове середовище. Для розробки слід використовувати найменші потрібні права та тестові облікові дані без доступу до виробничих даних. Фізична копія каталогу — не дозвіл застосовувати міграцію чи записувати до живої системи.
47.5. Worktree, контейнер і пісочниця — різні осі
Контейнер — спосіб запустити процес у налаштованому середовищі виконання. Межа залежить від образу, томів, змінних оточення, мережі, процесних дозволів та інструмента, який ним керує. Монтування директорії хоста може дозволити контейнеру редагувати файли на хості; монтування лише для читання змінює саме цю властивість, але не відокремлює дані, до яких процес має мережевий доступ. Docker прямо документує, що bind mount за замовчуванням придатний для запису, якщо його не змонтовано в режимі лише читання (Bind mounts).
Пісочниця — набір обмежень на дії: доступ до файлових шляхів, мережі, дочірніх процесів та інших ресурсів. Вона може обмежити поведінку команди, запущеної з будь-якого каталогу, але не зобов’язана створювати окремий Git-репозиторій чи окремі дані. Наявність діалогу підтвердження також не є доказом файлової або мережевої ізоляції: це правило керування дозволом, а не нове середовище.
Тому корисно описувати незалежно щонайменше три рішення: який checkout бачить агент; де і з якими інструментами виконується його процес; до яких зовнішніх систем і прав він має доступ. Наприклад, Codex може працювати у Git worktree в локальному режимі, у віддаленому контейнері Cloud або в іншій конфігурації; ці режими відрізняються не одним прапорцем. Claude Code має власну підтримку worktree та власні обмеження пісочниці, які також залежать від платформи. Функція одного клієнта не є гарантією поведінки іншого.
Продуктова документація задає окремий життєвий цикл. Станом на дату перевірки Codex Desktop створює кероване робоче дерево від HEAD вибраної гілки; якщо там є локальні незбережені зміни, документація вказує, що вони переносяться до цього дерева, яке починається у detached HEAD. Такі дерева пов’язані з окремими чатами; постійне worktree існує як довготривале середовище та не видаляється автоматично. .worktreeinclude у Codex стосується локальних керованих desktop worktree, а не віддалених чи створених вручну через Git (Codex worktrees). Claude Desktop створює сесійні дерева в <project-root>/.claude/worktrees/ за замовчуванням і дозволяє змінити розташування; завершену локальну сесію можна архівувати. Claude Code у командному рядку також підтримує параметр --worktree і за замовчуванням створює дерево в <repo>/.claude/worktrees/<name> (Claude Desktop, Claude Code worktrees, CLI reference). Ці деталі залежать від версій і поверхонь продукту; їх треба перевіряти окремо, а не переносити на кожен Git worktree.
Git описує worktree платформно-нейтрально, але підтримка інструментів, оболонок і правил пісочниці різниться. Claude Desktop вимагає Git for Windows для worktree-сесій; пісочниця Bash у Claude Code працює на macOS, Linux та Windows Subsystem for Linux 2 (WSL 2), але не в нативній Windows. Звіряйте команди, шляхи й доступ із документацією поточного продукту та середовища, а не переносіть їх з іншої операційної системи.
47.6. Три завершені сценарії
Сценарій 1. Окремі worktree, одна тестова база
Уявімо тестовий сервіс бронювання. Агентка Марта отримує окреме робоче дерево для міграції таблиці бронювань. Агент Тарас працює у другому дереві над обробником скасування. Їхні гілки та незбережені файли незалежні. Обидва .env посилаються на booking_test, ту саму тестову базу даних.
Марта запускає міграцію, яка перейменовує таблицю; перед своєю перевіркою очищає старі дані. У цей час тест Тараса читає ту саму таблицю. Він падає через відсутню назву, а потім Марта засіває набір бронювань, і Тарас отримує чужі результати. Це не конфлікт файлової системи: кожен worktree лишився неушкодженим. Конфлікт виник у спільному зовнішньому сховищі.
Достатній захист починається з перевірки фактичного кінцевого вузла з’єднання, а не лише з порівняння .env. Для незалежної паралельної перевірки кожна гілка отримує власну тестову базу або керований простір даних, де міграції, fixtures і прибирання обмежені цією роботою. Якщо така ізоляція неможлива, команді слід серіалізувати роботу зі схемою й даними, заборонити руйнівне очищення та явно записати, що перевірки ділять стан. Тестові права не мають давати змогу під’єднатися до виробничої бази.
Це узгоджується з конкретним користувацьким повідомленням у дискусії Cline Kanban №254: один оператор, який описує роботу кількох агентів у Laravel і Sail з базою PostgreSQL (реляційна система керування базами даних, що використовує SQL — Structured Query Language, структуровану мову запитів), повідомив про спільну базу, конфлікти міграцій і вплив на основну локальну базу. Це самозвіт одного учасника обговорення, а не вимірювання частоти проблем або доказ для всіх систем. Він допомагає сформулювати ризик, але не замінює перевірки власної конфігурації.
Сценарій 2. Порт зайнятий, а сторінка все одно відповідає
У двох копіях застосунку запускають сервер попереднього перегляду на стандартному порту 3000. Перша копія запускає процес правильно. Другий запуск не займає порт, але тестовий браузер лишається відкритим на адресі першої копії. Відповідь виглядає правдоподібно, тож агент може помилково повідомити, що перевірив власну зміну.
Перш ніж робити висновок, треба встановити, який процес слухає порт, у якій директорії він працює й з якою гілкою його запущено. Сервер другої копії має отримати окремий порт або окремий мережевий простір з коректною публікацією порту. Звіт має назвати точний сервер і checkout, на якому виконано перевірку. Якщо джерело відповіді невідоме, результат — не «перевірено», а «не вдалося підтвердити, що запущено потрібну ревізію».
Реальний технічний приклад проблеми спільного простору портів описано в об’єднаному запиті на злиття змін (Pull Request, PR) Paperclip №9642 (опис і перевірки). Дві робочі копії могли користуватися спільним каталогом worktree, але однаковими портами сервера й вбудованої PostgreSQL. Початкове сканування сусідніх конфігурацій не виявляло копії з іншої кореневої директорії, а паралельне відновлення конфігурації допускало дубльовані призначення. PR додав спільний реєстр резервування з блокуванням. Це приклад конкретної гонки розподілу ресурсу, а не доказ того, що будь-які worktree автоматично конфліктують; у PR зазначено 14 сфокусованих тестів, успішну перевірку типів і 24 пройдені перевірки GitHub.
Ще один обмежений звіт показує, як можна перевірити не ту копію. Автор issue Claude Code №63008 описав macOS-сесію в worktree, з якої механізм Claude Preview запустив дочірній сервер із робочим каталогом основного репозиторію. За звітом, сторінка віддавала основну гілку, записувала кеш у .next основної копії та займала порт 3000; автор підтвердив каталог процесу утилітою lsof (list open files — «перелік відкритих файлів»). Issue закрито зі статусом «не планується», що не означає ані виправлення, ані загальної поведінки продукту. Це самоописаний випадок на конкретній версії macOS та Claude Code (issue №63008), тож перед висновком треба перевірити робочу директорію процесу власного середовища.
Сценарій 3. Дві зміни по черзі інтегруються в актуальну базу
Два агенти стартують від коміту M0. Перший змінює схему бронювання, другий — форму скасування та очікування її API. Початково їхні файли різні, тому кожна гілка проходить власні вузькі перевірки. Після злиття гілки першого виникає нова ревізія M1. Зміна другого все ще походить від M0 і може бути несумісною з новою схемою, навіть якщо текстові конфлікти відсутні.
Перед інтеграцією автор перевіряє, чи змінився цільовий коміт після початку другої роботи та які контракти залежать від першої зміни. Далі друге відгалуження оновлюють і узгоджують з M1 погодженим способом, не втрачаючи його незбережених змін і не переписуючи чужу гілку. Після цього знову перевіряють сумісність схеми, запитів, міграцій і користувацького сценарію в інтегрованій ревізії. Перевірки, виконані кожною гілкою окремо на M0, залишаються доказом саме для M0 — вони не засвідчують спільний результат.
Коли обидві гілки інтегровані, перевіряють об’єднану ревізію з її фактичними залежностями та потрібним середовищем. Чисте злиття підтверджує, що система зуміла об’єднати історію; воно не доводить логічної сумісності змін. Перед видаленням будь-якої робочої копії з’ясуйте, чи лишилися там незбережені файли, незаписані докази або потрібний незлитий коміт. Інтеграція й очищення мають зберігати цей стан, доки відповідальність за нього не передано.
47.7. Як домовитися про паралельне середовище
Перед роботою автор, агент або оркестратор мають відповісти на питання нижче в контракті завдання чи в пов’язаному налаштуванні середовища. Не кожне завдання потребує всіх ресурсів, але відповідь «не застосовується» має бути свідомою.
| Питання | Ясна домовленість |
|---|---|
| З якого стану починається робота? | Точний коміт або інша позначена ревізія; назва гілки; умова оновлення після змін цільової гілки |
| Які файли окремі? | Шлях worktree, очікуваний стан ignored/local-файлів, setup-залежності, каталоги збірки й кеші |
| Де працюють процеси? | Окремі порти або процесний/мережевий простір; власник кожного фонового сервера; звідки запущено перевірку |
| Які дані змінюються? | Тестова база, схема, черга й сховище; простір імен; fixtures, заборонені дії та межа очищення |
| Які доступи є? | Тестовий обліковий запис і найменші потрібні дозволи; заборона виробничих секретів, якщо вони не потрібні й не схвалені |
| Де межа контейнера чи пісочниці? | Монтування, доступні шляхи, мережеві правила, передані змінні та винятки |
| Як відбувається інтеграція? | Власник інтеграції, момент синхронізації з базою, обов’язкові повторні перевірки на інтегрованій ревізії |
| Що дозволяє прибирання? | Хто може зупиняти процес, видаляти тимчасові ресурси та коли дані вже не потрібні; невідомі процеси й незбережені зміни зберігаються |
Не перетворюйте цей перелік на зайві формальності для короткого завдання. Він потрібен, коли помилка межі може знищити дані, підмінити перевірену ревізію або відкрити агенту доступ, якого автор не мав на увазі.
47.8. Завершення роботи та очищення
Кінець задачі не настає автоматично після того, як гілку злито. Переконайтеся, що зміни й потрібні докази зафіксовано або передано; перевірте, що робочий процес не залишив запущеного сервера; приберіть лише ті тимчасові дані, процеси й середовища, якими справді володієте. Видалення директорії не повинне бути способом позбутися чужої роботи або незбережених файлів.
Git захищає від деяких випадкових дій: стандартне видалення linked worktree відмовляється прибирати неочищене робоче дерево. Цей захист корисний, але не замінює перевірки власника та стану, і примусове видалення його обходить. Так само очищення локальної тестової бази має бути обмежене власним тимчасовим простором, а не робитися на підставі схожої назви чи припущення, що її ніхто не використовує.
Практичний критерій завершення простий: відомо, де лишилися коміти, незбережені зміни, процеси та тестові дані; їхній власник погодив наступну дію; перевірку виконано на потрібній інтегрованій ревізії; прибирання не зачепило стан поза цією домовленістю.
Короткий підсумок
Git worktree дає кілька фізично відокремлених checkout-ів одного репозиторію. Він зберігає локальні індекси й HEAD окремими, а більшість історії та Git-метаданих спільними. Він сам не ізолює кеші, фонові процеси, мережеві порти, бази даних, черги, облікові записи, контейнери чи доступ до мережі.
Називайте ресурс, його власника, межу та спосіб перевірки. Окрема директорія не засвідчує, що тест торкнувся потрібного сервера або даних. Окремий контейнер не гарантує ізоляції змонтованих каталогів і зовнішніх сервісів. Після об’єднання змін повторно перевірте сумісність на фактичній інтегрованій ревізії; перед очищенням збережіть незавершений стан і зупиняйте лише власні процеси.
Джерела та подальше читання
- Git, git-worktree і глосарій Git — офіційні терміни, спільні й per-worktree метадані, обмеження гілки, стану та очищення.
- Git, git-clone — межа звичайного клону і зауваження щодо варіантів, які використовують спільне сховище об’єктів.
- OpenAI, Git worktrees, середовища Codex і пісочниця — можливості та налаштування конкретних режимів Codex; не правила Git і не припущення про інші клієнти.
- Anthropic, Claude Desktop, Claude Code worktrees, довідник інтерфейсу командного рядка (CLI, command-line interface) і пісочниця Claude Code — продуктова підтримка worktree та платформні межі пісочниці.
- Docker, Bind mounts — як змонтована директорія може залишати контейнер із доступом на запис до файлової системи хоста.
- Paperclip, PR №9642 — реалізований механізм резервування однакових портів між worktree; конкретний приклад гонки.
- Cline Kanban, обговорення №254 — самозвіт оператора про спільну PostgreSQL базу в паралельних агентських робочих копіях; обмежене свідчення, не загальна статистика.
- Anthropic Claude Code, issue №63008 — окремий самозвіт про сервер попереднього перегляду, запущений з основної копії під час сесії в worktree; не подавати як універсальну поведінку продукту.
Мінливі продуктово-залежні можливості та стани репозиторіїв перевірено 26 вересня 2026 року. Git-сторінка зазначала, що її останнє змістовне оновлення — версія 2.54.0; для сумісності з установленою версією слід звіряти локальну документацію.