تاریخچه کوتاهی از گیت (git)

5 دقیقه

زمان مطالعه

5

1 رای

۴۵

بازدید

۱۴۰۵/۶/۶

تاریخ انتشار

مانند بسیاری از چیزهای بزرگ، Git هم از دل یک بحران و کمی «ویرانگری خلاق» بیرون آمد. داستان Git داستان یک محصول تجاری با نقشهٔ راه چندساله نیست؛ داستان ابزاری است که در چند هفته و زیر فشار یک ضرب‌الاجل واقعی ساخته شد، چون بزرگ‌ترین پروژهٔ نرم‌افزار آزاد جهان ناگهان بی‌ابزار مانده بود.

پیش از گیت: عصر پچ و آرشیو

کرنل لینوکس یک پروژهٔ نرم‌افزاری متن‌باز با دامنهٔ بسیار وسیع است. در سال‌های نخست نگهداری آن (۱۹۹۱ تا ۲۰۰۲)، تغییرات نرم‌افزار به‌صورت پچ (patch) و فایل‌های آرشیوشده میان توسعه‌دهندگان رد و بدل می‌شد. در عمل یعنی هر مشارکت‌کننده تفاوت تغییرات خود را در قالب یک فایل متنی تولید می‌کرد، آن را به فهرست پستی کرنل می‌فرستاد، و نگهدارنده باید آن پچ را دستی بررسی و روی درخت کد اعمال می‌کرد.

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

  • هیچ تاریخچهٔ ساختاریافته‌ای وجود نداشت؛ فهرست پستی و آرشیو فایل‌ها عملاً جای پایگاه دادهٔ نسخه‌ها را گرفته بود.
  • ردیابی اینکه یک تغییر خاص از کجا آمده، چه‌کسی آن را بازبینی کرده و روی کدام نسخه اعمال شده، دشوار بود.
  • ادغام کار موازی چند زیرسیستم به گلوگاهی انسانی تبدیل می‌شد که همه‌چیز از نگهدارندهٔ اصلی عبور می‌کرد.
  • هر پچ که با تأخیر اعمال می‌شد، احتمال تضاد (conflict) و کار دوباره را بالا می‌برد.

در سال ۲۰۰۲، پروژهٔ کرنل لینوکس استفاده از یک سیستم کنترل نسخهٔ توزیع‌شدهٔ اختصاصی و تجاری به نام BitKeeper — ساختهٔ شرکت BitMover به مدیریت لری مک‌وی (Larry McVoy) — را آغاز کرد. BitKeeper نرم‌افزاری انحصاری بود، اما شرکت سازنده اجازه داده بود توسعه‌دهندگان کرنل به‌صورت رایگان از آن استفاده کنند. برای نخستین بار توسعه‌دهندگان کرنل ابزاری در اختیار داشتند که مدل توزیع‌شده را می‌فهمید: هر کس مخزن کامل خودش را داشت و ادغام تاریخچه‌ها دیگر کار دستی نبود.

بحران مجوز BitKeeper

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

در سال ۲۰۰۵، اندرو تریجل (Andrew Tridgell) — توسعه‌دهندهٔ سرشناس متن‌باز، خالق Samba و در آن زمان شاغل در OSDL — تلاش کرد پروتکل BitKeeper را مهندسی معکوس کند و ابزاری آزاد به نام SourcePuller بسازد تا بتوان بدون کلاینت انحصاری به داده‌ها دسترسی داشت. شرکت BitMover این کار را نقض شرایط مجوز رایگان دانست و اعلام کرد پشتیبانی از نسخهٔ رایگان BitKeeper از ۱ ژوئیهٔ ۲۰۰۵ پایان می‌یابد. پروژهٔ کرنل، با هزاران مشارکت‌کننده و چرخهٔ انتشار فشرده، ناگهان با یک ضرب‌الاجل روبه‌رو شد: یا ابزاری تازه پیدا کند، یا به عصر پچ و آرشیو بازگردد.

هیچ‌یک از سیستم‌های کنترل نسخهٔ آزاد آن روزگار پاسخ‌گوی نیازهای کرنل نبودند؛ نه از نظر سرعت، نه از نظر پشتیبانی از کار توزیع‌شده در این مقیاس. همین بن‌بست بود که لینوس توروالدز، خالق لینوکس، را واداشت تا بر پایهٔ درس‌هایی که از کار با BitKeeper گرفته بود، ابزار خودش را بسازد.

اهداف طراحی و پیامدهای فنی آن‌ها

برخی از اهداف سیستم جدید چنین بودند:

  • سرعت بالا
  • طراحی ساده
  • پشتیبانی قوی از توسعهٔ غیرخطی (هزاران شاخهٔ موازی)
  • معماری کاملاً توزیع‌شده
  • توانایی مدیریت کارآمد پروژه‌های بزرگ مانند کرنل لینوکس، هم از نظر سرعت و هم از نظر حجم داده

نکتهٔ مهم این است که این فهرست صرفاً یک اعلامیهٔ آرزومندانه نبود؛ هر بند از آن پیامد فنی مشخصی در معماری Git داشت که تا امروز باقی مانده است:

  • سرعت و سادگی به مدل ذخیره‌سازی محتوا-آدرس‌پذیر (content-addressable) انجامید. Git به‌جای اینکه تفاوت‌ها (delta) را دنبال کند، خودِ محتوا را ذخیره می‌کند و هر شیء با هش محتوایش آدرس‌دهی می‌شود. نتیجه این است که پایگاه دادهٔ Git در عمل یک نگاشت کلید-مقدار ساده است و بازیابی هر نسخه به جست‌وجوی خطی در زنجیرهٔ تغییرات نیاز ندارد (ببینید مباحث درونی گیت (در آینده اضافه خواهد شد)).
  • یکپارچگی داده پیامد مستقیم همان تصمیم بود: چون شناسهٔ هر شیء از محتوایش محاسبه می‌شود، هر خرابی یا دستکاری در داده‌ها به‌طور خودکار آشکار می‌شود.
  • توسعهٔ غیرخطی شاخه‌بندی را ارزان کرد. در Git یک شاخه چیزی جز یک اشاره‌گر کوچک به یک کامیت نیست، نه یک کپی از درخت فایل‌ها؛ به همین دلیل ساختن و حذف شاخه تقریباً بی‌هزینه است (ببینید انشعاب‌گیری در گیت (در آینده اضافه خواهد شد)).
  • معماری توزیع‌شده یعنی هر کلون یک مخزن کامل با تمام تاریخچه است، نه یک کپی کاری وابسته به سرور. همین ویژگی، کار آفلاین و روندهای کاری متنوع را ممکن کرد (ببینید گیت توزیع‌شده (در آینده اضافه خواهد شد)).

گاه‌شمار سه ماه نخست

سرعت پیشرفت کار چشمگیر بود. فاصلهٔ میان نخستین خط کد و لحظه‌ای که Git تاریخچهٔ کرنل لینوکس را مدیریت می‌کرد، کمتر از سه ماه بود:

  • ۳ آوریل ۲۰۰۵ — توروالدز توسعهٔ Git را آغاز کرد.
  • ۶ آوریل ۲۰۰۵ — پروژه به‌طور عمومی در فهرست پستی کرنل لینوکس معرفی شد.
  • ۷ آوریل ۲۰۰۵ — Git به self-hosting رسید؛ یعنی به مرحله‌ای که می‌توانست تاریخچهٔ توسعهٔ خودش را نگه دارد و نخستین کامیت واقعی Git با خود Git ثبت شد.
  • ۱۸ آوریل ۲۰۰۵ — نخستین ادغام (merge) چند شاخه با موفقیت انجام شد.
  • ۲۹ آوریل ۲۰۰۵ — Git به هدف کارایی موردنظر رسید و توانست ۶٫۷ پچ در ثانیه را روی درخت کرنل اعمال کند.
  • ۱۶ ژوئن ۲۰۰۵ — نسخهٔ 2.6.12 کرنل لینوکس منتشر شد؛ نخستین انتشار رسمی کرنل که به‌طور کامل با Git مدیریت شده بود.

عدد «۶٫۷ پچ در ثانیه» شاید در نگاه اول بی‌معنا به نظر برسد، اما معیار سنجش درستی بود: انبوه پچ‌هایی که در فهرست پستی کرنل جمع می‌شد باید در زمانی معقول اعمال می‌شد، و هر ابزاری که نمی‌توانست با آهنگ ورود تغییرات همگام بماند، عملاً به گلوگاه پروژه تبدیل می‌شد.

یک زایش دوقلو: Mercurial

نکتهٔ کمتر گفته‌شدهٔ این ماجرا آن است که Git تنها پاسخ به بحران BitKeeper نبود. در همان آوریل ۲۰۰۵ و در واکنش به همان رویداد، مت مکال (Matt Mackall) پروژهٔ Mercurial را آغاز کرد؛ سیستمی که آن هم توزیع‌شده بود و همان مسئله را هدف گرفته بود، اما با تصمیم‌های طراحی متفاوت. هر دو پروژه در فهرست پستی کرنل مطرح شدند و مدتی نامزد جانشینی BitKeeper بودند. سرانجام کرنل Git را برگزید، اما Mercurial سال‌ها به‌عنوان یک سیستم کنترل نسخهٔ توزیع‌شدهٔ جدی به کار خود ادامه داد. اینکه دو ابزار مستقل با معماری مشابه در یک ماه از دل یک بحران زاده شدند، نشان می‌دهد فشار مسئله چقدر واقعی و راه‌حل چقدر «در هوا» بود.

از ابزار شخصی تا پروژه‌ای بالغ

در ۲۶ ژوئیهٔ ۲۰۰۵، یعنی تنها چند ماه پس از آغاز پروژه، توروالدز نگهداری Git را به جونیو هامانو (Junio C. Hamano) سپرد. این انتقال زودهنگام اتفاق مهمی بود: توروالدز Git را برای حل مسئلهٔ خودش ساخته بود و رابط کاربری آن در آن مرحله عمدتاً مجموعه‌ای از دستورات سطح پایین بود که با اسکریپت‌های پوسته به هم چسبیده بودند.

نقش هامانو دقیقاً همین‌جا پررنگ شد: تبدیل یک ابزار قدرتمند اما خام به نرم‌افزاری که برای کاربر عادی هم قابل استفاده باشد. زیر نظر او دستورات سطح بالا (که در فرهنگ Git به آن‌ها porcelain گفته می‌شود) شکل گرفتند و از لایهٔ دستورات سطح پایین (plumbing) جدا شدند — تمایزی که هنوز هم ستون فقرات معماری Git است. نسخهٔ ۱٫۰ در ۲۱ دسامبر ۲۰۰۵ زیر نظر او منتشر شد و نسخهٔ ۲٫۰ نیز در ۲۸ مهٔ ۲۰۱۴. هامانو تا امروز نگهدارندهٔ اصلی Git است و پروژه با چرخه‌ای منظم — تقریباً هر سه ماه یک نسخهٔ اصلی — به‌روزرسانی می‌شود.

دربارهٔ نام

دربارهٔ نام پروژه هم داستان کوتاهی وجود دارد: واژهٔ «git» در انگلیسی بریتانیایی اصطلاحی عامیانه و تحقیرآمیز برای آدمی ناخوشایند و بی‌ارزش است. توروالدز خودش در توضیح انتخاب این نام به شوخی گفته بود:

یادداشت

«I’m an egotistical bastard, and I name all my projects after myself. First ‘Linux’, now ‘git’.»

«من آدم خودشیفته‌ای هستم و همهٔ پروژه‌هایم را به نام خودم می‌گذارم. اول «لینوکس» و حالا «git».» — لینوس توروالدز

در صفحهٔ راهنمای (man page) رسمی Git، این ابزار با عبارت طنزآمیز «ردیاب محتوای احمقانه» (the stupid content tracker) توصیف شده است. این توصیف صرفاً شوخی نیست؛ خلاصه‌ای دقیق از فلسفهٔ طراحی است. هستهٔ Git عمداً «احمق» و ساده نگه داشته شده: کاری که انجام می‌دهد ذخیره و بازیابی محتوا بر پایهٔ هش آن است، و تمام هوشمندی — تشخیص تغییر نام فایل‌ها، الگوریتم‌های ادغام، نمایش تاریخچه — به لایه‌های بالاتر سپرده شده که روی همان هستهٔ ساده ساخته می‌شوند.

میراث گیت

از زمان تولدش در سال ۲۰۰۵، Git رشد کرده و بالغ شده است تا کار با آن آسان‌تر شود، بی‌آنکه ویژگی‌های بنیادین اولیه‌اش را از دست بدهد. Git به‌طرز چشمگیری سریع است، در پروژه‌های بزرگ بسیار بهینه عمل می‌کند و سیستم شاخه‌بندی فوق‌العاده‌ای برای توسعهٔ غیرخطی دارد.

اما شاید مهم‌ترین پیامد Git چیزی باشد که در طراحی اولیه‌اش پیش‌بینی نشده بود. Git برای حل مسئلهٔ نگهداری کرنل لینوکس ساخته شد، اما مدل توزیع‌شده و شاخه‌بندی ارزان آن، شکل جدیدی از همکاری را ممکن کرد: هر کسی می‌توانست یک پروژه را کلون کند، روی شاخهٔ خودش کار کند و تغییرش را برای بازبینی پیشنهاد دهد، بدون آنکه نیاز به مجوز نوشتن روی مخزن اصلی داشته باشد. سکوهایی مانند GitHub، GitLab و Bitbucket همین قابلیت را به یک تجربهٔ کاربری ساده تبدیل کردند و روند کاری «فورک و درخواست ادغام» را به شیوهٔ متعارف مشارکت در نرم‌افزار آزاد بدل ساختند (ببینید گیت‌هاب (در آینده اضافه خواهد شد)).

امروز Git نه‌تنها ابزار توسعهٔ کرنل لینوکس، بلکه زیرساخت مشترک بخش بزرگی از صنعت نرم‌افزار است و میلیون‌ها پروژه بر پایهٔ آن میزبانی می‌شوند. پایان داستان هم کنایه‌آمیز است: در ۹ مهٔ ۲۰۱۶، شرکت BitMover نسخهٔ 7.2ce از BitKeeper را تحت مجوز آزاد Apache 2.0 منتشر کرد و آن را متن‌باز ساخت. یعنی همان نرم‌افزاری که بستهٔ بودنش جرقهٔ ساخت Git را زد، سرانجام آزاد شد — اما تا آن زمان Git یازده سال بود که استاندارد عملی صنعت شده بود.

این محتوا چطور بود؟

نظر شما به بهبود محتوا کمک می‌کند

امیر دایی
امیر دایی
500k دنبال‌کننده

از بچگی عاشق برنامه نویسی بودم