پرش به محتوای اصلی
پرش به محتوای مقاله

قفل Git Worktree مانع حذف خودکار کدها توسط Claude Code می‌شود

·۲۱ شهریور ۱۴۰۵۷ دقیقه مطالعه
راهنما
کد Claude هنگام خروج بدون پرسیدن worktreeهای تمیز را حذف می‌کند؛ قفل git worktree از آن جلوگیری می‌کند.
کد Claude هنگام خروج بدون پرسیدن worktreeهای تمیز را حذف می‌کند؛ قفل git worktree از آن جلوگیری می‌کند.
اشتراک‌گذاری
واقعاً چه چیز جدید است؟

افشای مکانیزم حذف خودکار محیط‌های کاری در Claude Code و ارائه راهکار فنی برای دور زدن آن از طریق قفل‌های دستی گیت.

تصور کنید سناریویی را در نظر بگیرید که در آن محیط توسعه ایزوله شما بدون هیچ هشدار قبلی ناپدید می‌شود. این اتفاق به دلیل یک مکانیزم پاک‌سازی پنهان در Claude Code رخ می‌دهد: اگر جلسه‌ای را که با پرچم --worktree شروع شده است ببندید و در آن لحظه هیچ تغییر ثبت‌نشده‌ای (uncommitted changes) یا کامیت جدیدی وجود نداشته باشد، این ابزار به‌طور خاموش هم محیط کاری (worktree) و هم شاخه (branch) مرتبط با آن را حذف می‌کند.

این رفتار یک باگ نیست، بلکه طبق مستندات Anthropic یک انتخاب طراحی آگاهانه است. این ابزار بر این اصل استوار است که یک جلسه بدون نام و «پاک»، قابل دورریز است. همان‌طور که در تحلیل قبلی ما درباره‌ی نحوه فعال‌سازی مهارت‌ها در دنیای واقعی توسط Claude Code اشاره کردیم، این گردش‌کار خاص نشان‌دهنده رویکردی تهاجمی‌تر در مدیریت بهداشت سیستم فایل است که می‌تواند توسعه‌دهندگان را غافلگیر کند. این در حالی است که پیش از این بررسی کرده بودیم که چگونه استفاده از worktree در Claude Code می‌تواند مانع از تخریب فایل‌ها در جلسات موازی شود، اما اکنون با چالش حذف خودکار این محیط‌ها روبرو هستیم.

تصور کنید ساعت‌ها وقت صرف آماده‌سازی یک محیط خاص کرده‌اید و تنها به این دلیل که آخرین تغییر کوچک خود را کامیت نکردید، تمام آن محیط ناپدید می‌شود. این ریسک به‌ویژه در نسخه ۲.۱.۲۶۳ این ابزار (تست شده روی git ۲.۵۲.۰ و macOS) مشهود است؛ جایی که یک تغییر کوچک ثبت‌نشده می‌تواند تفاوت بین بقا و نابودی محیط کاری شما باشد.

منطق حذف خاموش

به نقل از یک تحلیل فنی منتشر شده در ۱۱ سپتامبر ۲۰۲۶، Claude Code هنگام اجرای دستور /exit دو فرمان گیت خاص را اجرا می‌کند تا تصمیم بگیرد آیا محیط کاری باید باقی بماند یا خیر:

  • git status --porcelain: برای بررسی وجود فایل‌های تغییریافته یا ردیابی‌نشده (untracked).
  • git rev-list --count <HEAD at session start>..HEAD: برای شمارش تعداد کامیت‌های جدیدی که در طول جلسه ایجاد شده‌اند.

اگر هر دو دستور مقدار صفر را برگردانند و جلسه نام‌گذاری نشده باشد، ابزار توالی حذف اجباری را اجرا می‌کند. در این مرحله، ابزار ابتدا قفل محیط کاری را باز می‌کند، مسیر فایل را با پرچم --force حذف می‌کند و در نهایت شاخه را با دستور git branch -D پاک می‌گردد.

ماتریس تصمیم‌گیری هنگام خروج

منطق داخلی ابزار بر اساس وضعیت محیط کاری و نام جلسه به صورت شاخه‌ای عمل می‌کند:

  • صفر فایل تغییریافته، صفر کامیت جدید، جلسه بدون نام: حذف خودکار محیط کاری و شاخه بدون هیچ‌گونه پرسش یا پیامی از کاربر.
  • صفر فایل تغییریافته، صفر کامیت جدید، جلسه نام‌دار (از طریق /rename): نمایش دیالوگ Keep / Remove برای انتخاب کاربر.
  • هرگونه تغییر ثبت‌نشده یا هر کامیت جدید: نمایش دیالوگ Keep / Remove بدون توجه به اینکه جلسه نام‌دار است یا خیر.

اگر شما در «مسیر خاموش» باشید، تنها چیزی که دریافت می‌کنید یک فلش کوتاه از پیام زیر است: «در حال پاک‌سازی محیط کاری (بدون تغییرات معلق)...»

تله پیش‌ساخت محیط کاری

بسیاری از توسعه‌دهندگان تصور می‌کنند اگر محیط کاری را پیش از شروع جلسه به‌صورت دستی با دستور git worktree add بسازند، از حذف محفوظ می‌مانند. اما اینطور نیست. Claude Code محیط‌های کاری موجود در دایرکتوری .claude/worktrees/ را پذیرفته و همان منطق خروج را روی آن‌ها اعمال می‌کند.

این موضوع یک لبه خطرناک (edge case) ایجاد می‌کند: اگر شما یک شاخه بسازید، کامیت‌هایی انجام دهید و سپس یک جلسه Claude Code را بدون ایجاد کامیت‌های جدید شروع کنید، ابزار جلسه را «پاک» می‌بیند. دلیل این اتفاق این است که بررسی «کامیت‌های جدید» نسبت به HEAD در لحظه شروع جلسه انجام می‌شود؛ بنابراین هر چیزی که قبل از شروع جلسه کامیت شده باشد، در این شمارش لحاظ نمی‌شود. این نوع رفتارهای پیش‌بینی‌ناپذیر در محیط‌های ایزوله، ما را به یاد تحلیل نقص‌های عملیاتی عامل‌ها و توقف کد در محیط‌های ایزوله می‌اندازد.

برای مثال، اگر دستور git worktree add -b worktree-wt-pre4 .claude/worktrees/wt-pre4 را اجرا کنید، فایلی را کامیت کنید و سپس دستور claude --worktree wt-pre4 را بدون ایجاد تغییرات بیشتر اجرا کنید، ابزار هنگام خروج شاخه را به‌طور اجباری حذف می‌کند. در این حالت، شیء کامیت همچنان در دیتابیس گیت وجود دارد و می‌توان آن را از طریق git fsck --lost-found بازیابی کرد، اما ارجاع به شاخه (branch reference) برای همیشه از بین می‌رود.

راهکار: مکانیزم قفل‌گذاری

تنها راه قابل اعتماد برای متوقف کردن این روند، بهره‌گیری از دستور git worktree lock است. Claude Code از قفل‌های داخلی خود برای مدیریت جلسات استفاده می‌کند. وقتی یک جلسه در حال اجراست، دلیل قفل (lock reason) از یک عبارت منظم (regex) خاص پیروی می‌کند:
/^claude (?:agent|session) .{1,255} \(pid (\d{1,10})(?: start (.{1,255}))?\)$/.

Claude Code طوری برنامه‌ریزی شده است که هرگز قفلی را که خودش ایجاد نکرده، آزاد نکند. اگر دلیل قفل با آن عبارت منظم مطابقت نداشته باشد، یا اگر PID متعلق به یک پروسه زنده دیگر باشد، سیستم پیام cleanupWorktree: kept <path> — locked by another live Claude Code process, or with a reason we did not write را ثبت کرده و از عملیات حذف عقب‌نشینی می‌کند.

برای تثبیت (pin) دستی یک محیط کاری، باید ابتدا قفل موجود ابزار را باز کرده و سپس قفل شخصی خود را اعمال کنید:

۱. git worktree unlock .claude/worktrees/<name>
۲. git worktree lock --reason "pinned by user" .claude/worktrees/<name>

دقت کنید که اجرای یک دستور ساده git worktree lock در حالی که قفل ابزار از قبل وجود دارد، منجر به شکست عملیات و یک خطای fatal می‌شود که اعلام می‌کند محیط کاری از قبل قفل شده است.

اتوماسیون حفاظت با هوک‌ها

برای کسانی که به‌طور مکرر از محیط‌های کاری استفاده می‌کنند، قفل‌گذاری دستی خسته‌کننده است. بهینه‌ترین راهکار، استفاده از یک هوک SessionStart است. با ایجاد یک اسکریپت شل که به‌طور خودکار قفل Claude Code را با یک قفل کاربر جایگزین می‌کند، می‌توانید تضمین کنید که هر جلسه به‌صورت پیش‌فرض تثبیت شده است. در واقع، این رویکرد مشابه پیاده‌سازی ۵ قلاب گیت برای جلوگیری از تخریب مخازن کد توسط عامل‌های هوش مصنوعی است که لایه‌ای از امنیت را به ساختار گیت اضافه می‌کند.

جزئیات پیاده‌سازی

  • اسکریپت: این اسکریپت باید از git rev-parse برای استخراج مسیر محیط کاری استفاده کند، نه متغیر محیطی $CLAUDE_PROJECT_DIR؛ زیرا متغیر مذکور حتی پس از ورود به یک worktree، همچنان به مسیر اصلی (main checkout) اشاره می‌کند.
  • منطق: اسکریپت باید بررسی کند که آیا در محیط کاری اصلی قرار دارد (جایی که --git-dir و --git-common-dir یکسان هستند) یا خیر، تا از قفل شدن غیرضروری ریشه اصلی پروژه جلوگیری شود.
  • ثبت: این هوک در فایل تنظیمات تحت مسیر hooks -> SessionStart به عنوان یک نوع دستور (command type) ثبت می‌شود.

مکان فایل‌های تنظیمات

محل قرارگیری فایل تنظیمات شما تعیین می‌کند که آیا هوک اجرا شود یا خیر:

  • .claude/settings.json (ثبت شده در مخزن): بله، زیرا در محیط کاری checkout شده قرار دارد.
  • .claude/settings.local.json (ردیابی‌نشده): خیر، زیرا محیط کاری checkout شده فاقد این فایل است.
  • فایل خارجی (که از طریق --settings پاس داده شده): بله.
  • ~/.claude/settings.json (تنظیمات کاربر): بله.

برای جلوگیری از ثبت هوک‌ها در مخزن کد، پیکربندی را در تنظیمات جهانی کاربر در مسیر ~/.claude/settings.json با استفاده از مسیر مطلق (absolute path) به اسکریپت قرار دهید.

جایگزین: جلسات نام‌دار

اگر نمی‌خواهید با قفل‌های گیت درگیر شوید، ساده‌ترین راهکار موقت، نام‌گذاری جلسه است. استفاده از دستور /rename در طول جلسه باعث می‌شود هنگام خروج، حتی اگر محیط کاری کاملاً پاک باشد، دیالوگ Keep / Remove ظاهر شود. در این حالت، ابزار صراحتاً می‌پرسد: «این جلسه نام 'keepme' داشت. آیا محیط کاری را برای بازگشت در آینده نگه دارید یا برای پاک‌سازی آن را حذف کنید؟»

پاک‌سازی دستی

از آنجایی که Claude Code دیگر به محیط‌های قفل‌شده دست نمی‌زند، مسئولیت پاک‌سازی بر عهده کاربر منتقل می‌شود. برای جلوگیری از شلوغ شدن مخزن، باید این توالی را به‌صورت دستی اجرا کنید:

۱. git worktree unlock .claude/worktrees/<name>
۲. git worktree remove .claude/worktrees/<name>
۳. git branch -D worktree-<name>

این تغییر در رفتار، رابطه توسعه‌دهنده با ابزار را از یک تجربه مدیریت‌شده به یک تجربه دستی تبدیل می‌کند. این موضوع تنش موجود بین اتوماسیون مبتنی بر هوش مصنوعی و الزامات سخت‌گیرانه ایمنی در سیستم‌های کنترل نسخه را برجسته می‌سازد.

برای اطمینان از بقای کارهای شما، باید فایل .claude/settings.json خود را بازبینی کرده و پیاده‌سازی یک اسکریپت تثبیت جهانی در تنظیمات کاربر در مسیر ~/.claude/settings.json را مد نظر قرار دهید.

گام بعدی شما

  • فایل ~/.claude/settings.json خود را بررسی کنید و یک اسکریپت تثبیت جهانی (Global Pinning) تعریف کنید.
  • در جلسات حساس، بلافاصله از دستور /rename برای جلوگیری از حذف تصادفی استفاده کنید.
  • اگر محیط کاری شما ناپدید شده است، از دستور git fsck --lost-found برای بازیابی اشیاء کامیت استفاده کنید.

اما داستان سخت‌افزاری این تحول حتی شگفت‌انگیزتر است — به تحلیل ما درباره‌ی تراشه‌های Blackwell مراجعه کنید.

چرا این موضوع مهم است؟

این موضوع بر اساس تجربه عملی نشان می‌دهد که اتوماسیون‌های هوشمند می‌توانند در صورت عدم شفافیت، به تخریب داده‌ها منجر شوند. اعتماد به ابزارهای AI در محیط‌های تولیدی مستلزم درک دقیق لایه‌های زیرساختی مانند Git Worktree است.

تأثیر برای ایران

برای توسعه‌دهندگان ایرانی که در پروژه‌های Open Source یا تیمی فعالیت می‌کنند، درک این مکانیزم برای جلوگیری از دست رفتن کدها در محیط‌های ایزوله ضروری است.

·نگاه ما
تحریریه دات‌هوش

این رفتار نشان‌دهنده یک تضاد بنیادین در فلسفه طراحی ابزارهای AI-native است؛ جایی که سرعت و «بهداشت فایل‌ها» بر امنیت داده‌های محلی اولویت می‌یابد. در حالی که گیت برای حفظ تاریخچه طراحی شده، Claude Code سعی می‌کند آن را مانند یک حافظه موقت (Cache) مدیریت کند. این رویکرد می‌تواند منجر به کاهش اعتماد توسعه‌دهندگان به ابزارهای عامل‌محور در پروژه‌های حساس شود مگر اینکه کنترل‌های دستی سخت‌گیرانه‌تری اضافه شود.

منابع

این گزارش با خط‌لولهٔ خودکار دات‌هوش از منابع معتبر جهانی تدوین و زیر نظر تحریریه منتشر شده است. روش کار ما

گفتگو

پنج‌شنبه‌های هوش‌محور

بسته‌ی هفتگی دات‌هوش

۵ خبر، ۲ ابزار، ۱ پرامپت در هر شماره. به‌زودی راه‌اندازی می‌شود — هر پنج‌شنبه صبح.

خبر کلیدی
ابزار کاربردی
پرامپت حرفه‌ای
تحلیل پژوهش
به‌زودی
زاویه‌ی ایرانی
به‌زودی
تمرین این هفته
به‌زودی

راهنماهای دات‌هوش

راهنماهای کاربردیِ دات‌هوش برای کار با هوش مصنوعی — از همین‌جا شروع کنید:

دات‌هوش

راهنمای فارسی هوش مصنوعی — با نگاه به ایران

اخبار روزانه، معرفی ابزارها و مدل‌ها، و آموزشِ کار با هوش مصنوعی؛ همیشه با این پرسش که از ایران چه چیزی کار می‌کند و چه چیزی نه.