الگوریتمهای diff چگونه کار میکنند
هر نمای diff در این صفحه توسط الگوریتم Myers تولید میشود — یک تکنیک ۱۹۸۶ توسط Eugene W. Myers که کوتاهترین اسکریپت ویرایش بین دو دنباله توکن را در زمان O((N+M)D) پیدا میکند، جایی که D فاصله ویرایش است. موتور کاملاً در مرورگر شما با استفاده از کتابخانه متنباز jsdiff اجرا میشود.
- توکنسازی ورودیها — قبل از مقایسه، الگوریتم هر ورودی را به دنبالهای از توکنها تقسیم میکند. جزئیات خط روی خطوط جدید تقسیم میکند؛ جزئیات کلمه روی مرزهای فاصله و علائم نگارشی تقسیم میکند؛ جزئیات کاراکتر هر نقطه کد یونیکد را به عنوان توکن مستقل در نظر میگیرد.
- ساخت گراف ویرایش — الگوریتم Myers مقایسه را به عنوان مسیری در یک شبکه ۲ بعدی مدل میکند که حرکت به راست به معنای «حذف از اصلی»، حرکت به پایین به معنای «درج از تغییریافته» و حرکت قطری به معنای «توکن در هر دو مطابقت دارد» است. الگوریتم کوتاهترین مسیر سنگینقطری را پیدا میکند.
- استخراج LCS — حرکات قطری در کوتاهترین مسیر، Longest Common Subsequence را ردیابی میکنند — توکنهایی که در هر دو ورودی به همان ترتیب نسبی ظاهر میشوند. هر توکن در LCS «دستنخورده» است؛ هر چیز دیگری یا اضافه یا حذف شده است.
- اعمال گزینههای پیشپردازش — اگر «نادیده گرفتن حالت» را فعال کنید، هر دو ورودی قبل از گذر LCS کوچک میشوند تا «HELLO» و «hello» یکسان شمرده شوند. «نادیده گرفتن فاصله» چند فاصله را به یکی تبدیل میکند. «برش هر خط» فاصلههای ابتدا و انتهای هر خط را قبل از مقایسه حذف میکند.
- رندر نمای انتخابی — خروجی همان نتیجه LCS است که به سه روش نمایش داده میشود: کنار هم اصلی را در چپ و تغییریافته را در راست در یک شبکه دو ستونه با برجستهسازی قرمز و سبز نشان میدهد. یکپارچه یک ستون واحد با خطوط پیشوند − و + مانند خروجی
git diffنشان میدهد. درونخطی حذفها را با خطخوردگی قرمز و اضافهها را با زیرخط سبز در همان جریان متن نشان میدهد. - محاسبه نوار خلاصه — پس از رندر، ابزار تعداد توکنهای اضافهشده، حذفشده و دستنخورده را میشمارد، سپس شباهت را به عنوان نسبت توکنهای دستنخورده به بزرگتر از دو طول ورودی محاسبه میکند. شباهت ۱۰۰٪ به این معناست که ورودیها پس از پیشپردازش یکسان هستند.
چرا از ابزار مقایسه متن استفاده کنیم
- بررسی کد بدون کلاینت Git — دو نسخه از یک فایل پیکربندی، یک migration SQL یا یک اسکریپت shell را کنار هم پیست کنید و ببینید چه چیزی تغییر کرده بدون clone کردن repository، سوئیچ branch یا انتظار برای pipeline CI. این ابزار برای بررسیهای سریع در طول pair programming، تحویلهای پیمانکاری که طرف مقابل تاریخچه Git خود را به اشتراک نگذاشته، و کدبیسهای قدیمی که کنترل نسخه ندارند مناسب است.
- مقایسه اسناد و قراردادها — diff در سطح کلمه نشان میدهد کدام عبارات بین پیشنویسهای قرارداد جابجا شدهاند. بند الف از پیشنویس اول و بند ب از نسخه نهایی را پیست کنید و دقیقاً عبارتی که تغییر کرده با قرمز-روی-سبز مشخص میشود.
- بازبینی پیشنویس مقاله و متن — نویسندگانی که یک پیشنویس اولیه را با نسخه ویرایششده مقایسه میکنند میتوانند به جزئیات کلمه بروند تا هر جایگزینی، درج و حذف را بدون خواندن مجدد هر دو نسخه ببینند. همین جریان کار برای مترجمان ممیزی تغییرات نسبت به متن منبع نیز کاربرد دارد.
- مقایسه لاگ و پیکربندی — مدیران سیستم که دو snapshot پیکربندی سرور، دو برنامه cron یا دو خروجی
ps auxرا مقایسه میکنند میتوانند از جزئیات خط برای یافتن پارامتر تغییریافته در یک فایل ۲۰۰ خطی در چند ثانیه استفاده کنند.
کاربردهای رایج
diff متن در پایان هر چرخه ویرایش در نوشتار، توسعه و کارهای عملیاتی نمود پیدا میکند.
- بررسی pull request: دو پیادهسازی تابع را کنار هم پیست کنید تا تغییر منطق را قبل از تأیید بدون نیاز به checkout کردن branch درک کنید.
- QA بینالمللیسازی: یک رشته منبع انگلیسی را با معادل ترجمهشده در سطح کلمه مقایسه کنید تا درجها، حذفها یا تعویضهای اصطلاحی که مترجم وارد کرده شناسایی شوند.
- تحلیل حادثه: دو snapshot manifest Kubernetes یا دو خروجی «docker inspect» را در سطح خط مقایسه کنید تا تغییر پیکربندی که پیش از خرابی رخ داده ایزوله شود.
یک نمونه عملی
یک فایل پیکربندی پنج خطی را در نظر بگیرید. اصلی: host=localhost، port=5432، dbname=app_db، user=app، password=secret. تغییریافته: host=db.prod.example.com، port=5432، dbname=app_db، user=app_prod، password=secret. با جزئیات خط و نمای کنار هم، خط ۱ قرمز در چپ (host=localhost) و سبز در راست (host=db.prod.example.com) نشان میدهد، خط ۴ قرمز (user=app) و سبز (user=app_prod) نشان میدهد، و خطوط ۲، ۳ و ۵ در هر دو طرف دستنخورده باقی میمانند. نوار خلاصه ۲ اضافه، ۲ حذف، ۳ دستنخورده و شباهت ۶۰٪ گزارش میدهد.
آیا این در مرورگر من اجرا میشود؟
بله. کل محاسبه diff در سمت کلاینت با استفاده از کتابخانه متنباز jsdiff بارگذاریشده با صفحه اجرا میشود. هیچ چیزی که تایپ، پیست یا مقایسه میکنید به هیچ سروری ارسال نمیشود. میتوانید خودتان تأیید کنید: DevTools مرورگر را باز کنید، به تب Network بروید، لاگ را پاک کنید، مقایسه را کلیک کنید و تأیید کنید که برای مرحله مقایسه هیچ درخواست شبکهای انجام نمیشود.
درصد شباهت به چه معناست؟
شباهت به عنوان توکنهای دستنخورده / max(مجموع توکنهای اصلی، مجموع توکنهای تغییریافته) محاسبه میشود. امتیاز ۱۰۰٪ به این معناست که دو ورودی پس از اعمال گزینههای پیشپردازش یکسان هستند. امتیاز ۰٪ به این معناست که هیچ توکن مشترکی بین ورودیها وجود ندارد. این معیار یک تقریب خشن از فاصله ویرایش است — برای ارزیابی سریع مفید است — نه امتیاز سرقت ادبی.
آیا میتوانم JSON / YAML / XML را به صورت معنایی مقایسه کنم؟
در این ابزار نه. این یک diff در سطح متن است، بنابراین قالببندی مجدد JSON یا XML که تنها فاصلهها را تغییر میدهد هنوز تغییرات زیادی نشان میدهد حتی اگر داده از نظر منطقی یکسان باشد. تغییر ترتیب کلیدهای شی در JSON نیز به عنوان تغییر نشان داده میشود حتی اگر اکثر تجزیهکنندهها ترتیب کلید را بیاهمیت بدانند. برای diff معنایی واقعی، هر دو ورودی را قبل از پیست کردن به همان تورفتگی و ترتیب کلید یکسان درآورید.
تفاوت نمای یکپارچه و کنار هم چیست؟
کنار هم دو ستون رندر میکند: اصلی در چپ و نسخه تغییریافته در راست، با خطوط حذفشده برجستهشده با قرمز در چپ و خطوط اضافهشده برجستهشده با سبز در راست. خطوط دستنخورده در هر دو ستون در همان ردیف تراز میشوند. یکپارچه یک ستون واحد با پیشوند − و پسزمینه قرمز برای خطوط حذفشده و پیشوند + و پسزمینه سبز برای خطوط اضافهشده رندر میکند — همان چیدمانی که git diff در ترمینال چاپ میکند. از یکپارچه زمانی استفاده کنید که میخواهید نتیجه را به عنوان یک فایل patch کپی کنید. از کنار هم زمانی استفاده کنید که تراز بصری اینکه چه چیزی جایگزین چه چیزی شده مهمتر است.
اصل را در چپ، نسخه تغییریافته را در راست پیست کنید، نما و جزئیات را انتخاب کنید و مقایسه در میلیثانیه نمایش داده میشود. حالت زنده را روشن کنید و diff با هر ضربه کلید هنگام ویرایش هر طرف دوباره اجرا میشود. نتیجه را به عنوان یک فایل .patch یکپارچه استاندارد دانلود کنید که git apply مستقیماً مصرف میکند. بدون آپلود، بدون حساب کاربری، بدون کلید API خارجی، بدون سهمیه.