sem: کنترل نسخهٔ معنایی روی گیت
خلاصهٔ کاملتر
تو این پروژه اومده که sem یه ابزار کنترل نسخهٔ معناییه که روی گیت سواره. بهجای اینکه بگه «خطهای x تا y عوض شد»، بهت میگه «تابع فلان تغییر کرد». کد رو با tree-sitter پارس میکنه، هر تابع و کلاس و متد رو بهعنوان یه موجودیت (entity) درمیاره و تفاوتها رو در سطح همین موجودیتها میسنجه. تو هر ریپوی گیت بدون هیچ راهاندازیای کار میکنه.
کَش موجودیتها رو هم تو یه دیتابیس SQLite بیرون از خود ریپو نگه میداره (پیشفرض زیر دایرکتوری کش سیستمعامل) تا فایلهای کش، درخت کاری رو کثیف نکنن؛ با متغیر SEM_CACHE_DIR هم میشه مسیر کش رو عوض کرد.
دستور اصلیش sem diff هست که تفاوت در سطح موجودیت رو با تشخیص تغییر نام، هش ساختاری و هایلایتهای درونخطی در سطح کلمه نشون میده و خروجیهای متفاوتی مثل plain، json و markdown داره. چند دستور کاربردی دیگه هم داره: sem impact که گراف وابستگی بینفایلی رو نشون میده و میگه اگه یه موجودیت عوض شه چی میشکنه، sem blame در سطح موجودیت، sem log واسه دنبالکردن تکامل یه موجودیت تو تاریخچه، و sem context که یه بستهٔ متنی بودجهبندیشده با توکن واسه LLMها میسازه.
نحوهٔ تطبیق موجودیتها سهمرحلهایه: اول تطبیق دقیق شناسه (همون موجودیت = تغییریافته یا بدونتغییر)، بعد تطبیق هش ساختاری (ساختار AST یکسان با نام متفاوت = تغییر نام یا جابهجایی، با نادیدهگرفتن فاصله و کامنت)، و در آخر شباهت فازی (بیش از ۸۰٪ همپوشانی توکن = احتمال تغییر نام). به این ترتیب sem تغییر نام و جابهجایی رو هم تشخیص میده، نه فقط اضافه و حذف.
میشه sem رو جایگزین پیشفرض git diff هم کرد. کافیه sem setup رو بزنی تا از اون به بعد هر چیزی که git diff صدا میزنه، بهصورت خودکار خروجی موجودیتی بگیره؛ یه pre-commit hook هم نصب میکنه که شعاع تأثیر تغییرات استیجشده رو نشون میده. با sem unsetup هم برمیگردی به حالت عادی.
از نظر پشتیبانی، sem روی ۲۸ زبان برنامهنویسی استخراج کامل موجودیت داره (از TypeScript و Python و Go و Rust تا PHP و Ruby و Swift و خیلیهای دیگه) و چند فرمت دادهٔ ساختیافته مثل JSON، YAML، TOML و Markdown رو هم میفهمه؛ بقیه به diff مبتنی بر تکه (chunk) برمیگردن. واسه پسوندهای غیراستاندارد میشه یه فایل .semrc ساخت و واسه فایلهای بیپسوند هم زبون رو از روی محتوا حدس میزنه. در نهایت یه سرور MCP با ۶ ابزار داره که دقیقاً معادل همون دستورهای CLI هستن و واسه ایجنتهای هوش مصنوعی ساخته شدن. خود ابزار با Rust نوشته شده و از git2، rayon و xxhash استفاده میکنه.
نکات کلیدی:
- بهجای diff خطبهخط، تفاوتها رو در سطح تابع، کلاس و متد نشون میده
- با tree-sitter پارس میکنه و تو هر ریپوی گیت بدون راهاندازی کار میکنه
- تغییر نام و جابهجایی رو با هش ساختاری و شباهت فازی تشخیص میده
- ۲۸ زبان برنامهنویسی و چند فرمت دادهٔ ساختیافته رو پشتیبانی میکنه
- سرور MCP داره تا همین قابلیتها در اختیار ایجنتهای هوش مصنوعی قرار بگیره




