git worktree؛ همزمان روی دو برنچ کار کن، بدون stash و بدون کلون دوم

وسط یک قابلیت نیمه‌کاره‌اید که یک باگ فوری روی شاخه‌ی اصلی سر می‌رسد. سه راه بلدید: git stash، کامیت نیمه‌کاره، یا کلون دوباره. راه چهارمی هم هست که کمتر شناخته شده: git worktree — پوشه‌های کاری اضافی که همه به یک مخزن واحد وصل‌اند.

مشکل: چه‌کار نکنیم

git stash روی کارهای بزرگ حالت ذهنی‌ات را هم به هم می‌ریزد و خطر conflict بعدی دارد. کامیت نیمه‌کاره تاریخچه را شلوغ می‌کند. کلون دوباره هم درست است ولی همه‌ی آبجکت‌ها و ریموت‌ها را از نو می‌سازد و به دو مخزن مستقل می‌رسد که به‌زودی از هم واگرا می‌شوند.

ساخت یک worktree

ساده‌ترین حالت: یک پوشه‌ی خواهر بسازید که روی یک برنچ موجود باز شود:

git worktree add ../site-hotfix hotfix-branch

یا برنچ را همان‌جا بسازید و هم‌زمان باز کنید:

git worktree add -b hotfix-msp ../site-hotfix

از این لحظه دو پوشه دارید که هر دو همان مخزن و همان تاریخچه را می‌بینند، اما HEAD و index و فایل‌های کاری هرکدام جداگانه است. هیچ‌چیزی دانلود نمی‌شود، چون آبجکت‌ها مشترک‌اند.

مدیریت و پاک‌سازی

git worktree list                 # every working folder
git worktree remove ../site-hotfix
git worktree prune                # drop records of worktrees you deleted

اگر پوشه را دستی در فایل‌منیجر حذف کنید، مخزن تا وقتی git worktree prune نزنید از آن خبر ندارد. و اگر لازم شد پوشه را جابه‌جا کنید، git worktree move هست تا پیوند خراب نشود.

برای بازبینی یک نسخه‌ی خاص

حالت --detach اجازه می‌دهد یک کامیت یا تگ مشخص را بیرون از هر برنچ باز کنید؛ عالی برای «قبل و بعد» دیدن یک تغییر:

git worktree add --detach ../site-v2 v2.1
git worktree add --detach ../site-before HEAD~5

قواعدی که باید بدانید

سه کاربرد واقعی

جمع‌بندی

git worktree همان چیزی است که «کلون دوم» را بی‌دردسر می‌کند، ولی بدون هزینه‌ی همگام‌سازی: یک مخزن، چند پوشه، چند برنچ هم‌زمان. سه دستور کافی است: add، list و remove. دفعه‌ی بعد که کار نیمه‌کاره‌تان زیر پای یک باگ فوری گیر کرد، سراغ stash نروید.

اگر برایتان جالب بود که چطور همین عادت‌های توسعه‌ی نرم‌افزار به دنیای برنامه‌ریزی راه پیدا می‌کنند، از کد تا گانت‌چارت را بخوانید.

سوالات متداول

کلون یک مخزن جدا با آسمان (remote) و فضای دیسک جداگانه است؛ برای دیدن تغییرات باید fetch و push کنید. worktree همان مخزن را کامل به اشتراک می‌گذارد، پس آبجکت‌ها و برنچ‌ها فوری در همه‌ی پوشه‌ها دیده می‌شوند.
نه، یک برنچ فقط در یک worktree باز می‌شود. ولی می‌توانید با --detach روی یک کامیت یا تگ مشخص، عملاً دو نسخه‌ی جداگانه از همان کد را کنار هم داشته باشید.
مخزن اصلی سالم می‌ماند؛ فقط یک رکورد یتیم در .git/worktrees/ باقی می‌ماند. با git worktree prune پاکش کنید. برای حذف مرتب هم git worktree remove درست است.
بله؛ فقط مسیر پوشه‌ی جدید را بدون فاصله بگیرید و کنار مخزن اصلی نگه دارید تا ابزارها راحت‌تر پیدایش کنند. با Git for Windows و WSL هر دو کار می‌کند.
← همه‌ی نوشته‌ها RSS