مقایسه سیستم‌های کنترل نسخه متمرکز و توزیع شده

مقدمه

در حال حاضر، یکی از الزامات و از حیاتی‌ترین پیش‌نیازها در توسعه نرم‌افزار، استفاده از یک سیستم کنترل نسخه مناسب و استاندارد است. هدف و کارکرد اصلی سیستم‌های کنترل نسخه را می‌توان در دو مورد بیان کرد: ۱- امکان دسترسی همه افراد تیم به آخرین نسخه از نرم‌افزار و توسعه نرم‌افزار به صورت هم‌زمان ۲- رصد تغییرات نرم‌افزار در طی زمان و داشتن کنترل کامل بر روی نسخه‌های مختلف. سیستم‌های کنترل نسخه مختلف، امکانات متعدد و بعضا متفاوتی برای این موارد فراهم کرده‌اند.

سیستم‌های کنترل نسخه به دو دسته متمرکز و توزیع‌شده تقسیم می‌شوند. یکی از معروف‌ترین سیستم‌های کنترل نسخه متمرکز، TFVC یا Team Foundation Version Control است و یکی از معروف‌ترین سیستم‌های کنترل نسخه توزیع‌شده، Git نام دارد.

در سیستم‌های کنترل نسخه متمرکز، مخازن کد بر روی یک سرور مرکزی ذخیره شده‌اند و توسعه‌دهندگان برای کار کردن با مخزن کد یک نسخه کاری (working copy) را check-out می‌کنند. هر نسخه کاری، در واقع یک snapshot از کد در یک زمان مشخص است.

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

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

ما در تیم چکاپ شرکت اعوان با هدف کمک به ارتقای سطح کیفی نرم‌افزارها، سامانه‌های نرم‌افزاری و تیم‌های نرم‌افزاری، در کنار تیم‌های مختلف قرار می‌گیریم و با شناسایی نقاط تاثیرگذار در کاهش کیفیت توسعه نرم‌افزار، به آن‌ها کمک می‌کنیم با آگاهی بیشتر گزینه‌های مختلف را بررسی کرده و بهترین راه‌کارها را به منظور بهبود کیفیت توسعه و معماری نرم‌افزار انتخاب و اعمال کنند.

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

در شرکت اعوان سال‌هاست که از Git استفاده می‌شود و در واقع دید خوبی نسبت به کارکردها و ویژگی‌های این سیستم کنترل نسخه داشتیم. اما تجربه کار با سیستم‌های متمرکز مثل TFVC را نداشتیم و باید بررسی می‌کردیم که چه ویژگی‌ها، محدودیت‌ها، مزایا و معایبی دارند تا در نهایت در خصوص ادامه روال استفاده از TFVC در آن تیم خاص و یا پیشنهاد تغییر رویه و مهاجرت به Git به جمع‌بندی برسیم.

در این مقاله قصد داریم به بررسی ویژگی‌ها و تفاوت‌های سیستم‌های کنترل نسخه متمرکز و توزیع‌شده بپردازیم. در نهایت اهمیت استفاده از سیستم‌های توزیع شده و همچنین دلایل مهاجرت از سیستم‌های متمرکز به سیستم‌های توزیع‌شده را بیان می‌کنیم.

از TFVC به‌عنوان نماینده سیستم‌های کنترل نسخه متمرکز و از Git به‌عنوان نماینده سیستم‌های کنترل نسخه توزیع‌شده که معروف‌ترین و پرکاربردترین سیستم‌های کنترل نسخه هستند استفاده می‌کنیم.


سیستم‌های کنترل نسخه متمرکز

در سیستم‌های کنترل نسخه متمرکز، مخازن کد بر روی یک سرور مرکزی ذخیره شده‌اند. توسعه‌دهندگان یک نسخه کاری (working copy) را check-out می‌کنند. هر نسخه کاری، در واقع یک snapshot از کد در یک زمان مشخص است.

معروف‌ترین سیستم کنترل نسخه متمرکز، TFVC یا Team Foundation Version Control نام دارد که در واقع سیستم کنترل نسخه‌ TFS است. TFS یک سیستم راه‌حل جامع (total solution) است و از زیرسیستم‌های مختلفی تشکیل شده. مثل سیستم issue tracking و version control و ...

بنابراین مصطلح است که سیستم کنترل نسخه‌ای که بر روی TFS قرار دارد را به جای TFVC با همان TFS خطاب می‌کنند. البته در این مقاله سعی می‌کنیم از این دو عبارت در جای درستشان استفاده کنیم.

معایب

  • مفهوم check-in کردن محلی در این سیستم‌ها تعریف‌نشده است. یعنی امکانش وجود ندارد که توسعه‌دهنده بتواند بدون تعامل با مخزن کد اصلی و صرفا به صورت local کد خود را check-in کند.
  • امکانات مربوط انشعاب (branching) و ادغام (merging) در این سیستم‌ها ضغیف است. فرض کنید که به یک پایگاه‌داده رابطه‌ای درست حسابی نیاز دارید. ابتدا Sql server و Oracle و MS Access را بررسی می‌کنیم و در نهایت Access را انتخاب می‌کنیم. چرا؟ چون بهترین GUI را دارد اما به این حقیقت که Access مقیاس‌پذیر نیست و referential integrity را به خوبی اعمال نمی‌کند و مورادی از این دست، توجهی نکرده‌ایم. انشعاب و ادغام از ارکان اصلی یک سیستم کنترل نسخه به شمار می‌روند و نقش گوشت و سیب‌زمینی را در غذا دارند. در حالی که بقیه ویژگی‌ها صرفا نقش دورچین غذا را دارند و متاسفانه افرادی هستند که بر اساس دورچین، غذا را انتخاب می‌کنند.
  • درباره TFS: همانطور که گفته شد، در واقع TFS یک Total Solution است و جدا از امکانات مربوط به کنترل نسخه، امکانات گسترده دیگری هم دارد. مثلا issue tracking.بدی راه‌حل‌های جامع این است که اگر واردشان شوید، تمام و کمال درگیرشان می‌شوید. همه امکاناتی که در اختیارتان می‌گذارد، در سطح متوسط است و ظاهرا چاره‌ دیگری هم ندارید. اما مهم است که بدانیم در هر زمینه‌ای مانند ردیابی کارها، مدیریت پروژه، گزارش‌گیری و ...، ابزارهای خیلی خیلی بهتری وجود دارد.

Azure DevOps

از چندسال پیش (سال ۲۰۱۹)، Visual Studio Team Foundation Server (TFS) به Azure DevOps تغییر نام داده است. در Azure DevOps این امکان وجود دارد که سیستم کنترل نسخه خود را Git انتخاب کنید یا TFS. در این مقاله اطلاعات کامل برای چگونگی استفاده از گیت به عنوان سیستم کنترل نسخه در Azure DevOps توضیح داده شده است.

سیستم‌های کنترل نسخه توزیع‌شده

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

گیت یک سیستم کنترل نسخه توزیع‌شده است که در سال‌های اخیر بسیار مورد توجه قرار گرفته است. برای مطالعه و آشنایی بیشتر با Git می‌توانید از این لینک استفاده بفرمایید.

در بخش‌ بعدی، سعی می‌کنیم مقایسه کاملی بین نماینده سیستم‌های کنترل نسخه متمرکز یعنی TFVC و نماینده سیستم‌های کنترل نسخه توزیع‌شده یعنی Git داشته باشیم.

  • یکی از مزایای داشتن کل مخزن (و نه فقط یک snapshot از آن) بر روی ماشین شخصی، این است که در صورتی که برای سرور مخزن کد مشکلی پیش بیاید، هر توسعه‌دهنده یک کپی از مخزن کد دارد و به راحتی مخزن کد از روی نسخه‌هایی که بر روی ماشین‌های افراد وجود دارد، بازیابی می‌شود. پس در حین کار با سیستم کنترل نسخه توزیع‌شده، به صورت خودکار در حال بکاپ‌گیری از مخزن کد هستیم. هر زمانی که کسی از مخزن مرکزی چیزی را pull کند، تاریخچه تغییرات پروژه را هم به صورت کامل دریافت می‌کند. پس هر فردی که با مخزن تعامل داشته باشد، یک نسخه کامل از مخزن را دارد و اگر یک زمانی مخزن به هر دلیلی از دست برود، به راحتی قابل ریکاوری است (یک نسخه بکاپ از مخزن روی کامپیوتر تمام اعضای تیم وجود دارد).
  • مزیت دیگر این سیستم‌ها این است که می‌توانید نسخه کاری خود را بین revisionهای مختلف جابجا کنید، بدون اینکه لازم باشد با سرور حرف بزنید. این امکان در صورتی که سرور پایین یا به هر دلیلی غیرقابل دسترس باشد، بسیار کمک‌کننده است. پس در این سیستم‌ها به صورت آفلاین به مخزن کد دسترسی داریم. در شرایط دورکاری (یا حتی کارکردن از داخل هواپیما و قطار)، به تاریخچه تغییرات و تک‌تک checkinها به صورت کامل دسترسی داریم. بدون اینکه نیاز به استفاده از VPN برای ارتباط با شبکه محل کار باشد و انگار در داخل شرکت هستیم، هر کاری مثل checkin و checkout و ساخت انشعاب و ... را می‌توانیم انجام دهیم.
  • یک مزیت مهم این است که بدون صحبت با سرور یا تحمیل تغییرات بالقوه ناپایدار به تیم، می‌توان مجموعه تغییرات را در مخزن محلی commit کرد. برای مثال، اگر در حال کار بر روی یک فیچر بزرگ هستیم، ممکن است که یک هفته زمان ببرد تا به طور کامل کدش را بزنیم و کامل تست کنیم. در این شرایط، قطعا مطلوب نیست که کد ناپایدار را در وسط هفته به مخزن کد check-in کنیم و با احتمال بالا یک build شکست‌خورده داشته باشیم. اما در مقابل چه می‌شود اگر در اواخر هفته، به صورت تصادفی کل نسخه کاری‌ لوکال‌‌مان را از دست بدهیم؟ اگر در طول این مدت و به مرور کدمان را commit نکرده باشیم، ریسک از دست رفتن کاری که انجام دادیم وجود دارد. چنین ابزار کنترل نسخه‌ای، کارا و مطمئن نیست و امثال TFVC مستعد این مشکل هستند.
  • با وجود سیستم‌های کنترل‌نسخه توزیع‌شده (DVCS)، بدون نگرانی برای شکست build، می‌توانیم مرتبا کدمان را کامیت کنیم. چرا که تغییراتمان را به صورت محلی کامیت می‌کنیم.

چرا باید به جای TFVC از Git استفاده کنیم؟

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

بسیاری از مقالات هم توسط افرادی نوشته شده بود که سال‌ها با TFS و TFVC کار کرده بودند ولی در نهایت تصمیم گرفته بودند به سمت گیت مهاجرت کنند. به دلیل آشنایی کامل این افراد با اکوسیستم TFVC و گیت، به نظر مقایسه‌های دقیق و کاملی انجام دادند و در نتیجه در این بخش به جای بررسی گیت و TFVC به صورت مستقل و بیان مزایا و معایب هر کدام، سوار بر موج شده و به مرور دلایل مهاجرت از TFVC به سمت گیت می‌پردازیم. به همین دلیل هم هست که بیشتر ادامه این مقاله از زبان کسانی هست که همچنان از مایکروسافت و Azure DevOps استفاده می‌کنند ولی از TFVC به گیت مهاجرت کرده‌اند.

۱. پیشنهاد مایکروسافت

جالب است که سیستم کنترل نسخه پیش‌فرض در Azure DevOps، گیت است و خودشان تاکید کرده‌اند که بهتر است از گیت استفاده کنید مگر اینکه دلیل خاصی برای استفاده از سیستم‌های کنترل نسخه متمرکز داشته باشید و مجبور شوید از TFS استفاده کنید. البته استفاده هم‌زمان گیت و TFS هم ممکن است. برای مقایسه کامل امکانات Git و TFVC در Azure DevOps، به این لینک مراجعه کنید.

Git is the default version control provider for new projects. You should use Git for version control in your projects unless you have a specific need for centralized version control features in TFVC

۲. سرعت بالای مهاجرت از TFVC به گیت

همانطور که در نمودار مشخص است مشتریان TFVC و Subversion و دیگر سیستم‌های کنترل نسخه با سرعت زیادی درحال مهاجرت به سمت Git هستند.

البته دقت کنید که این مهاجرت به این معنی نیست که مشتریان Azure DevOps (یا همان TFS سابق) را ترک می‌کنند، بلکه همانطور که اشاره شد، در حال حاضر در پروژه‌های Azure DevOps به صورت پیش‌فرض مخازن گیت قرار دارند و توسط خود مایکروسافت هم استفاده از آن‌ها پیشنهاد می‌شود.

3. جریان‌های کاری

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

گیت جریان‌های کاری محبوب زیادی دارد و کامیونیتی قوی‌ای حول خودکارسازی این جریان‌های کاری ساخته است. اما ‌TFVC اینطور نیست.

جریان‌های کاری موجود، مزایای زیادی دارند که در ادامه آمده‌اند:

  • جریان‌های کاری معمولا در بلاگ‌های کاربری زیادی همراه با سفارشی‌سازی‌های مرسوم مستند شده‌اند.
  • جنبه‌های سخت و بدقلق‌شان همراه با توضیحات و راه‌حل به وفور به صورت آنلاین مستند شده است.
  • کاربران زیادی از سایت‌هایی مانند StackOverflow دانش زیادی در این زمینه دارند و مشتاق هستند که به سوالات مرتبط با جریان‌های کاری پاسخ دهند.

۴. ترند جهانی

Knowledge of Git is increasingly expected of developers and IT staff in the industry

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

۵. استاندارد سازمانی

It’s best to standardize on a single type of VCS in an organization

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

به همین دلیل، بیشتر سازمان‌ها تصمیم می‌گیرند که روی یک سیستم کنترل نسخه واحد تمرکز کنند. به این معنی که:

  • مهندسان می‌توانند روی چندین پروژه مختلف کار کنند بدون این‌که نیاز باشد با چند نوع سیستم کنترل نسخه مختلف سر و کار داشته باشند.
  • سربار زمانی انتقال افراد بین تیم‌های مختلف، کمتر است.
  • تعامل تیم‌ها با یکدیگر برای به اشتراک‌گذاری دانش، جریان کاری و کد راحت‌تر است.
  • برای افراد IT مرکزی، در صورت self-hosting، پشتیبانی از یک نوع مخزن کد و در صورت cloud-hosting، مستندسازی و مدیریتی سطوح دسترسی برای یک نوع مخزن کد راحت‌تر است.

هر روزه در سازمان‌های مختلف (چه مایکروسافتی و چه غیرمایکروسافتی) سهم گیت به عنوان سیستم‌ کنترل نسخه استاندارد رو به افزایش است.

۶. مدل انشعاب سبک‌تر

گیت مدل انشعاب واقعا سبکی دارد. به طوری که هر شاخه‌ای که ساخته می‌شود، واقعا سبک‌وزن و به جای این‌که یک کپی از کل پروژه باشد، مثل یک لینک به یک کامیت خاص است. این موضوع باعث می شود که ایده ساخت یک شاخه که برای هر فیچر مجزایی که به سامانه اضافه می‌کنید نه تنها ممکن، بلکه توصیه‌شده باشد. با این کار، بسته به ساختار ادغام‌ها (در حالت ایده‌آل با کمک Pull Request) خواندن تاریخچه (history) راحت‌تر می‌شود. در سمت دیگر TFVC، روش سنگینی برای برخورد با انشعاب‌ها دارد. چرا که هر شاخه‌ای که ساخته می‌شود، یک کپی کامل از پروژه همراه با تمام وابستگی‌هایش است.

۷. بروکراسی بسیار کمتر

در TFVC بیشتر بر روی سناریوهای سلسه‌مراتبی معمولی تمرکز وجود دارد. چیزهایی مثل ایجاد یک شاخه معمولا به عنوان کاری دیده می‌شود که تنها افراد سطح بالاتر باید اجازه آن را داشته باشند. در مورد حذف شاخه نیز محدودیت‌های بیشتری وجود دارد. همین مساله باعث می‌شود که ایده یک شاخه به ازای هر فیچر، اصلا ایده خوبی در TFVC نباشد. همچنین حتی زمانی که توسعه‌دهنده دسترسی ساخت و حذف شاخه را داشته باشد، این کار آنقدری زمان‌بر هست که ارزش انجام آن برای هر فیچر را ندارد.

در سمت دیگر گیت، رویکرد کاملا متفاوتی دارد. هر کس می‌تواند هر چقدر که می‌خواهد برحسب نیاز شاخه‌های محلی ایجاد کند. محدودیت‌ها فقط برای زمانی‌هایی وجود دارند که بخواهید شاخه‌های روی سرور را حذف کنید یا شاخه‌ای را بر روی سرور push کنید.

روش خوب این است که شاخه master را همیشه با استفاده از pull request محافظت کنید. به این ترتیب، هر کس می‌تواند شاخه‌های دل‌خواهش را بسازد و هر کاری که دوست دارد با آن‌ها انجام دهد. اما هنگامی که می‌خواهد تغییراتش را با master ادغام کند، باید حتما به صورت کنترل‌شده باشد و در حال ایده‌آل توسط سایر توسعه‌دهندگان تغییراتش مرور شود.

۸. امکان کار به‌صورت آفلاین

‌نکته این است، هر زمان که TFS پایین باشد، کار کل تیم می‌خوابد و در واقع ویژوال استودیو کل تیم را بلاک می‌کند تا هیچ کاری نتوانند انجام دهند. زیرا برای یک تغییر کوچک در یک فایل هم شما مجبورید حتما به سرور اطلاع دهید. البته ظاهرا در Azure DevOps این مساله کمتر است. فقط پایین بودن سرور نیست که دردسر ایجاد می‌کند. حتی کند شدن آن هم بهره‌وری تیم را کاهش می‌دهد. اما در گیت این مساله مشکلات خیلی کمتری را ایجاد می‌کند. اگر سرور پایین باشد، فقط CI/CD از کار می‌افتد و نمی‌توانیم تغییرات را بر روی سیستم deploy کنیم اما می‌توانیم به صورت عادی کارمان را ادامه دهیم و تغییرات را به صورت محلی کامیت کنیم.

9. ویرایش سریع‌تر فایل

به نظر می‌رسد که TFVC هر بار که یک فایل را به یک پوشه‌ای اضافه می‌کنید، ابتدا چک می‌کند که آیا فایل باید ردیابی شود یا خیر. این موضوع فرایندهایی که با تعداد زیادی فایل سر و کار دارند را بسیار کند می‌کند. مثل نصب بسته‌های NuGet. اولین باری که بخواهید تغییری در یک فایل بدهید، باید در سرور check-in شود و تا زمانی که پاسخ برگردد، ویرایش فایل بلاک می‌شود.

اما گیت از استراتژی دیگری استفاده می‌کند. به جای این‌که هر بار که یک فایلی تغییر کرد، notify شود، فقط زمانی که ازش درخواست شود، وضعیت فعلی را چک می‌کند. به این ترتیب، هر بار که شما (یا یک برنامه‌ای مثل ویژوال استودیو) بخواهید وضعیت فعلی فایل را بروز کنید، عملیات git status (که بسیار سریع است) را انجام می‌دهید تا چک شود که آیا چیزی تغییر کرده است یا نه. این کار نه تنها از روش TFVC سریع‌تر بلکه بسیار امن‌تر هم است.

10. سریع‌تر بودن عملیات مربوط به کنترل نسخه

هزینه اجرای عملیات کنترل نسخه معمولا نادیده گرفته می‌شود. چرا که این عملیات خیلی به طور مکرر انجام نمی‌شوند (مخصوصا در TFVC). مساله این است که در زمان بروز مشکل، حتما به این عملیات نیاز دارید و در آن زمان‌ها هم هر دقیقه اهمیت دارد.

اگر بعد از تغییر در کد، باگی پیدا شود، سعی می‌کنیم که ریشه بروز باگ را پیدا کنیم. کاری که معمولا انجام می‌دهیم این است که تمام تغییراتی که در کد داده‌ایم را به نوعی غیرفعال می‌کنیم (stash) و چک می‌کنیم که آیا باگ همچنان وجود دارد یا نه. اگر باگ همچنان دیده می‌شود یعنی منشا آن، تغییرات ما نبوده و از کدهای دیگران ناشی می‌شود. ولی اگر دیگر نتوانیم آن باگ را تولید کنیم، یعنی باید کد خود را دقیق‌تر بررسی کنیم و ببینم چه اشتباهی مرتکب شده‌ایم (معمولا با تست واحد راحت‌ مشخص می‌شود که باگ از کجای آمده است).

چک کردن تاریخچه کد هم گاهی به ما کمک می‌کند که قوانین کسب‌وکاری عجیبی که بیشتر شبیه به باگ هستند را بهتر درک کنیم. می‌توانیم چک کنیم که کد با کدام کامیت اضافه شده‌است و از آنجا هم می‌توانیم Pull Requestای که منجر به اضافه شدن این کد به شاخه master شده است را پیدا کنیم. این Pull Request معمولا نشان می‌دهد که درخواست ادغام از سمت چه کسی بوده و تغییرات کد به چه منظور و هدفی بوده است. همه این کارها با گیت بسیار بسیار ساده‌تر است. در حالی که در TFVC خیلی سخت است که این سطح از تعاملات با سیستم کنترل نسخه را داشته باشیم. چرا که معمولا خیلی کند است و آن‌چنان قابل اعتماد هم نیست.

در آخر هم می‌توان گفت که یک ویژگی بدیهی و به نظر ناقابل در گیت (مثل اجرای دستور git checkout [commit-id])، در TFVC چیزی است که همه از آن می‌ترسند (زیرا بسیار کند است و احتمال بالایی وجود دارد که مشکلاتی را ایجاد کند). در گیت می‌توان تمام فایل‌ها را از روی نسخه‌ای که حتی بیش از یک‌سال از انتشارش گذشته ردیابی کرد و در عرض چند ثانیه به جدیدترین نسخه بازگشت.

11. راهی آسان و صریح برای نادیده گرفتن فایل‌ها

انجام این مورد در گیت خیلی ساده و آسان است ولی هیچ وقت واقعا نفهمیدم که چرا اینقدر طول کشید تا فیچرش به TFVC هم اضافه شود (و چرا وقتی که فیچرش اضافه شد هم هیچ‌وقت آن‌طور که انتظار می‌رفت کار نمی‌کرد). ایده‌اش خیلی ساده است: یک جایی یک لیستی داشته باشیم که بگوید سیستم کنترل نسخه چه فایل‌ها و پوشه‌هایی را باید نادیده بگیرد. در واقع این فایل‌ها هیچ وقت نباید اضافه یا ردیابی شوند. مگر اینکه خلافش را صریحا ذکر کنیم. این فیچر مثلا برای NuGet بسیار مفید است. چرا که راهی است که پوشه packageها را بشود ignore کرد (زیرا باید هر وقت لازم بود دانلود شوند).

در گیت این کار با فایل gitignore. انجام می‌شود. این فایل باید اولین فایلی باشد که روی هر پروژه جدید چک می‌شود و در واقع هر بار که یک پروژه را به سیستم کنترل نسخه اضافه کنید، ویژوال استودیو این فایل را برای شما کامیت می‌کند. خوبی این فایل این است که کاملا صریح و شفاف است: هر فایل، پوشه یا الگویی از فایل‌ها که باید نادیده گرفته شوند، در این فایل ذکر شده باشد و هر تغییری هم که در محتوای آن داده شود، بلافاصله اعمال می‌شود.

در واقع، TFVC هم تلاش می‌کرد که این کار را با فایل tfignore. انجام دهد. تلاش قابل توجهی است اما طبق تجربه، مساله را کامل حل نمی‌کند و حفره‌های زیادی دارد. مثلا اینکه فقط برای workspaceهای محلی کار می‌کند (فایل tfignore. هنگام استفاده از فضای کاری سرور، نادیده گرفته می‌شود) و حتی در فضای کاری محلی هم مواردی به چشم خورده که که فایل‌هایی که باید نادیده گرفته می‌شدند، نادیده گرفته نشدند!

12. مجموعه‌ ابزار و ویژگی‌های بهتر حتی در داخل Azure DevOps

در حال حاضر بیشتر ویژگی‌های جدید مرتبط با کنترل نسخه، فقط به گیت اضافه می‌شوند، گاهی به خاطر این‌که اصلا روی TFVC معنی ندارند. برای مثال فیچر «New Branch» را که به work itemهای برد کانبان اضافه شده است را در نظر بگیرید. اگر از گیت استفاده کنیم، این فیچر به ما اجازه می‌دهد مستقیما از روی تسک بتوانیم شاخه جدید بسازیم و وقتی که درخواست ادغام این شاخه به master را بدهیم، آن تسک به صورت خودکار به Pull Request لینک می‌شود. هم‌چنین هر وقت کسی بخواهد پیشرفت تسک را بررسی کند، می‌تواند خیلی راحت کامیت‌های آن شاخه را از روی خود تسک مشاهده کند.

حالا TFVC را در نظر بگیرید. اصلا امکان ساخت یک شاخه به ازای هر تسک وجود دارد؟ بسته به سایز پروژه، زمان ساخت شاخه روی TFVC بیشتر از زمان تکمیل درخواست و push کردن آن به master در گیت طول خواهد کشید.

ماهیت جریان کاری‌ای که حول Pull Requestهای گیت در TFS و Azure DevOps وجود دارد، به تنهایی یک دلیل محکم برای مهاجرت به سمت آن است. واقعا هیچ چیز نزدیک و مشابهی در TFVC وجود ندارد.

این موضوع در مورد مرور کد هم صدق می‌کند. در TFVC اصلا این امکان وجود ندارد که بتوانید در حالی که درخواست‌دهنده اصلی مشکلات پیداشده را حل می‌کند، همچنان تغییرات را مرور و ردیابی کنید. اما Pull Request در گیت، این امکان را به شما می‌دهد که شاخه فیچر را مرتب بروز کنید تا زمانی که مرورکنندگان کاملا راضی شوند. تمام تغییرات هم ردیابی می‌شوند و افراد دیگر هم از تمام تغییرات مطلع می‌شوند. در کنار همه این‌ها، امکان کامنت‌گذاری با ارجاع مستقیم به کد هم وجود دارد.

13. استفاده بر روی سایر پلتفرم‌ها

TFVC یک محصول ویندوزی است و ایجاد شده تا داخل ویژوال استودیو استفاده شود. البته مشتریانی هم بر روی سایر پلتفرم‌ها دارد ولی آن‌ها نمی‌توانند بدون دردسر از آن استفاده کنند. حتی extensionهای موجود هم نتوانسته‌اند این دردسرها را کم کنند و نظرات منفی بسیار زیادی حول آن وجود دارد. حتی دیده شده که برخی از توسعه‌دهندگانی که روی اکلیپس(Eclipse) کار می‌کنند، به صورت مجزا و صرفا برای کار با سیستم کنترل نسخه، از ویژوال استودیو استفاده می‌کردند زیرا از سر و کله زدن با Team Explorer استرس کمتری دارد.

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

جمع‌بندی

در هر صورت ممکن است که TFVC همچنان بهترین گزینه شما باشد. اگر یک دلیل کاملا محکم برای استفاده از آن داشته باشید (مثلا آیین‌نامه‌هایی که از شما انتظار دارند در هر زمان دسترسی هر توسعه‌دهنده‌ به هر فایلی را متوجه شوید و توانایی قطع دسترسی یک گروه از افراد را به یک فایل خاص داشته باشید). اما در بیشتر موارد، همچنان بهتر است که از TFVC به سمت گیت مهاجرت کنید.

البته مهاجرت به گیت ممکن است در ابتدا شما را سردرگم و ناراحت کند. چرا که از ناحیه امن‌تان خارج شده‌اید و منحنی یادگیری گیت هم خیلی هموار نیست. با این وجود هنوز کسی را ندیدم که به صورت حرفه‌ای با TFVC و گیت کار کرده باشد و ترجیح بدهد که به TFVC برگردد (با وجود اینکه اولش در مقابل پیشنهاد مهاجرت به گیت مقاوت شدیدی داشتند). و حالا همان توسعه‌دهندگانی که به شدت مخالف تغییر بودند، اذعان دارند که با گیت زندگی‌شان راحت‌تر شده است.

منابع