رفتن به مطلب اصلی

مقدمه

چرا Git؟#

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

ولی هر چی پروژه بزرگ تر میشه، تیم هم بزرگ تر میشه. فرض کنید یه وبسایت میخواید بسازید با تیمتون. ممکنه کلی آدم از طراح گرفته تا برنامه نویس و مدیر تولید محتوا و ... بخوان روی پروژه کار کنن. کلی فایل برنامه نویسی و گرافیکی میاد توی پروژه. مدیریتش قطعا سخت میشه. حالا این وسط یکی بخواد روی کدهای قبلی یه تغییری هم بده که دیگه میشه کار حضرت فیل!

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

Git چیه؟#

برای اینکه ببینیم Git چیه باید اول با یه مفهومی آشنا بشید به اسم Version Control.

Version Control یعنی مدیریت تغییرات توی یه اطلاعات، صفحات وبسایت، عکس و فیلم ها، دیتابیس و هر چیزی که به عنوان Data میشه در نظر گرفت. به سیستمی که این تغییرات رو مدیریت میکنه هم میگن Version Control System یا VCS.

مثلا اگر یه فیلمی رو ویرایش کردید یعنی تغییرات دادید توی فیلم و باید ثبت بشه. اگر یه متنی رو توی صفحه یه وبسایت عوض کردید یعنی تغییرات انجام دادید و باید ثبت بشه. اگر یه فیلدی رو توی دیتابیس عوض کردید یعنی تغییرات و باید ثبت بشه.

دو نوع VCS داریم:

  • سیستم مدیریت نسخه مرکزی یا Centralized Version Control System (CVCS)
  • سیستم مدیریت نسخه غیر متمرکز یا Distributed Version Control System (DVCS)

حالا اینا که گفتم یعنی چی؟

قبل اینکه بریم سراغ توضیحات باید بدونید که یه کلمه توی دنیای کامپیوتر هست به اسم Repository یا Repo. یه چیزیه مثل مخزن که توش فایل هامون رو میذاریم. جلوتر متوجه میشین منظورم چیه!

Centralized VCS#

Centralized VCS از یه سرور مرکزی استفاده میکنه که تمام فایل ها رو توش ذخیره کنه و به اعضای تیم اجازه میده که به صورت مستقیم به اون فایلا دسترسی داشته باشن. اون جایی که این فایل ها توش ذخیره میشن رو بهش میگن Repository. شکل زیر یه CVCS رو نشون میده.

اون Repository که توی تصویر بالا هستش همون سروری هست که فایل ها توش ذخیره شدن. حالا این سرور میتونه هر جایی باشه. میشه مثلا توی سرور لوکال شرکت باشه یا سرور اون سر دنیا! ولی مهم اینه که به صورت مستقیم به سیستم هر برنامه نویس وصله.

اینطوری هر برنامه نویسی یه کپی از فایلها برای خودش داره و هر تغییری به اونا بده مستقیم روی Repository اعمال میشه.

شاید به نظرتون این قضیه آسون به نظر برسه و اینکه یه دونه **** رو مدیریت میشه کرد و فلان. ولی خب یکم اگه بررسی کنیم میبینیم چندتا مشکل داره این روش:

  • خود Repository و اطلاعات داخلش به صورت لوکال در دسترس نیستن. یعنی هر وقت یه برنامه نویس بخواد کاری کنه باید وصل شه به اون شبکه ای که اون Repository توش هست.
  • از اونجایی که همه چیز به صورت متمرکز و توی یه دونه Repository نگهداری میشه، هر مشکلی برای اون سرور یا شبکه پیش بیاد باعث میشه کل اطلاعات و پروژه از بین بره!

اینجاست که Distributed VCS میاد وسط.

Distributed VCS#

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

توی Distributed VCS، هر برنامه نویسی یه کپی یا Clone از اطلاعات اون Repository مرکزی در اختیار داره. هر کسی برای خودش یه Repository لوکال داره که تمام اطلاعات Repository مرکزی رو داره تو خودش.

یکم شاید پیچیده شد، تصویر زیر رو ببینید:

هموطور که توی تصویر بالا میبینید، هر برنامه نویسی یه **Repository** مخصوص خودش به صورت لوکال داره. یعنی یه کپی از اطلاعات **Repository** اصلی توی کامپیوتر خودش داره. خب دیگه به راحتی میتونن هر کاری دوست دارن با **Repository** خودشون توی کامپیوترشون کنن بدون اینکه هیچ تداخلی ایجاد بشه. هر کاری کنن فعلا برای خودشونه فقط!

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

یه چیزی دیگه اینکه مثلا یه قسمتی از پروژه رو تموم کردن و میخوان Repository مرکزی هم این تغییرات جدید رو داشته باشه. میتونن اطلاعات Repository لوکال خودشون رو به Repository مرکزی بفرستن. به این کار میگن Push.

حالا اصلا این همه کار کردیم که چی؟ خوبیاش ایناست:

  • اول اینکه هر کاری به جز Push و Pull خیلی به سرعت انجام میشه. چرا که توی کامپیوتر خودمونه. نیازی هم نداره به اینترنت یا هر شبکه دیگه ای وصل باشیم.
  • هر تغییری هم بدیم روی سیستم خودمون فقط انجام میشه و با اون کد اصلی کاری نداره. اینطوری میتونیم یه مجموعه ای از تغییرات رو انجام بدیم، بعدش همه رو با هم بفرستیم برای Repository مرکزی.
  • این تغییراتی که دادیم رو هم میتونیم خودمون بررسی کنیم که مثلا خطا نداشته باشه و به اصطلاح خودمون Debug کنیم.
  • از اونجایی که هر برنامه نویس یه کپی کامل از پروژه رو برای خودش داره، میتونیم کدمون رو با بقیه به اشتراک بذاریم و نظرشون رو بپرسیم بدون اینکه کد اصلی رو تغییر داده باشیم.
  • هر زمانی هم سرور اصلی اگه مشکلی براش پیش بیاد به راحتی میشه اطلاعات از دست رفته رو با استفاده از یکی از این Repository های لوکال برگردوند.

حالا که فهمیدیم Distributed VCS چیه، وقتشه بریم سراغ Git!

ویژگی های Git#

Git یه ابزار Distributed Version Control هستش که از که از روش های غیر خطی هم پشتیبانی میکنه (پایین تر توضیح دادم).

تمام توضیحاتی که بالاتر راجع به Distributed VCS دادیم برای Git هم صادقه. حالا یکم از ویژگی های Git براتون بگم,

رایگان#

کاملا رایگانه (البته توی ایران شاید معنی رایگان و پولی رو خیلی درک نکنیم ولی بدونین خیلی مهمه!) و کدش به صورت Open Source در دسترسه. هر زمان نیاز داشته باشید میتونید کدش رو تغییر بدید خودتون (البته خیلی کم دیدم این کارو حتی شرکت های بزرگ هم انجام بدن).

سرعت بالا#

از اونجایی هم که برای کار باهاش نیاز ندارید به هیچ شبکه ای وصل باشید، خیلی سرعتش زیاده. توضیح دادم که کدتون توی سیستم و کامپیوتر خودتونه پس هر کاری روی کد انجام بدید سریع انجام میشه. خیلی مقایسه ها نشون دادن که تقریبا پرسرعت ترین ابزار Version Control هستش. اصل کار رو هم با زبان C نوشتن که اینطوری دیگه یعنی زمان اجراش خیلی سریع تره نسبت به زبان های سطح بالاتر مثل #C.

مقیاس پذیر#

خیلی به راحتی میتونه بزرگتر شدن تیم رو کنترل کنه. یعنی مثلا هر زمانی که آدم های مختلف میخوان به تیم اضافه بشن، خیلی ساده خود Git اون رو مدیریت میکنه. از طرفی شاید بگین Git تمام Repository اصلی رو نگهداری میکنه، حجمش ممکنه زیاد شه. حرفتون درسته. ولی جالبیش اینه، کدی که سمت لوکال Repository هستش خیلی حجمش کمه چون خود Git کلی فایل ها رو فشرده میکنه بدون اینکه کیفیت رو حتی یک درصد کم کنه (به این روش فشرده سازی میگن Lossless Compression).

قابل اطمینان#

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

ایمن#

امنیتیش هم که خب حرف نداره چرا که از SHA1 (Secure Hash Function) استفاده میکنه تا هر چیزی توی Repository رو صدا بزنه. هر فایل یا Commit که انجام میشه اول Checksum میشه و زمانی که میخوایم استفاده کنیمش با همون Checksum مقایسه میشه. بخونید خودتون که این Checksum چیه. راستی، هر Commit که انجام میشه یه ID میگیره. این ID ها هم مثل یه زنجیر به هم وصلن. یعنی اون وسطا اگه اون ID ها با هم نخونه انگار یه پله نردبون کمه و مشکل ایجاد میشه. برای همین اگر کدی رو منتشر کنید، دیگه قابل پاک کردن نیست و نمیشه نسخه قدیمی رو پاک کرد بدون اینکه هشکی نفهمه! خلاصه اینکه هر کاری کنید اونجا نوشته میشه و یهو نمیشه یه کد از هوا وارد سیستم شما بشه!

مقرون به صرفه#

خیلی هم به صرفه هستش از نظر اقتصادی! اگه خاطرتون باشه توی Centralized VCS یه سرور همیشه بود و هر برنامه نویسی هم برای کار باید همیشه بهش وصل میبود. برای همین یه سیستم خیلی قوی نیازه که بتونه این تعداد از برنامه نویس رو ساپورت کنه. برای یه تیم کوچیک شاید مشکلی نباشه ولی برای یه تیم بزرگ قطعا مشکل سازه! یعنی مثلا اگه سرور خوب نباشه، سرعت کم میشه و کارایی کلا میاد پایین! ولی در عوض توی Distributed VCS شما همیشه با سرور در ارتباط نیستید و هر کاری نیاز هست رو روی کامپیوتر خودتون انجام میدید، یعنی کار اصلی روی کامپیوتر شما انجام میشه. برای همین هم سرور اصلی خیلی هم میتونه خیلی ساده باشه.

غیر خطی#

از روش های غیر خطی (Non-Linear) پشتیبانی میکنه. غیر خطی به صورت مثال بخوام توضیح بدم یعنی اینکه مثلا یه برنامه نویسی روی یه صفحه کار کنه و یه نفر دیگه روی یه صفحه دیگه کار کنه. هر زمانی هم که دوست داشتن بتونن اونها رو بدون دردسر کنار هم بذارن تا پروژه کامل شه. یا اینکه دو نفر هم زمان دارن روی یه صفحه کار میکنن. یکی داره منوی کشویی بالای صفحه رو میسازه و یکی داره یه سری دکمه برای پایین صفحه میسازه. در نهایت هر زمان که بخوان میتونن کاری که کردن رو کنار هم بذارن و هیچ دردسری نداشته باشه. این کار با استفاده از Branch انجام میشه که بعدا بیشتر راجع بهش صحبت میکنیم.

Branching ساده#

فرض کنید کد اصلیتون در حال اجراست و هیچ مشکلی نداره. چندین نفر روش کار کردن و کلی تغییرات دادن. حالا شما میخواین بدون اینکه تغییری توی کد اصلی بدین، یه سری تغییرات جدید انجام بدید و منتشر کنید. تا الان گفتیم اگر تغییرات رو منتشر کنید میره کد اصلی رو تغییر میده. ولی چطور میشه کد جدید رو هم منتشر کنیم بدون اینکه کد اصلی رو تغییر بدیم؟ شما میتونید یه نسخه جدید با تغییرات مد نظرتون رو هم داشته باشید. به این کار میگن Branching. برای این کار شما یه شاخه جدید (Branch) از کد اصلی میسازید. عامیانه یعنی راه خودتون رو از کد اصلی جدا میکنید. دیگه هر تغییری بدید روی Branch خودتون انجام میشه. اینطوری هم کد اصلی سر جاشه، هم نسخه جدید شما منتشر شده. هر وقتی هم که خواستین میتونین درخواست بدین به صاحب کد (Code Owner) که Branch شما رو با Branch اصلی (Master) ادغام کنه (Merge). بعدا بیشتر آشنا میشیم راجع به این اصطلاحات!

Branching توی Git کار ساده ایه که شاید چند ثانیه طول بکشه. اینطوری یه محیط ایزوله درست میشه که هر تغییری میخوایم اونجا بدیم. این باعث میشه که Master Branch همیشه کدی رو داشته باشه که کمترین خطا و ارور رو داره.

غیر متمرکز#

گفتیم که Git یه کپی از Repository اصلی رو توی سیستم ما به صورت لوکال ذخیره میکنه و برای کار باهاش نیاز به اینترنت نداریم. تمام تغییرات انجام شده و همه ی Branch ها رو هم در اختیار ما میذاره. اینطوری هر کاری دوست داریم روی کد میکنیم و بعدا انتقال میدیم به Repository اصلی.

سازگار با همه چیز!#

این ابزار با همه چیز سازگاره یعنی شما میتونید برای انتقال کدتون از http, ftp یا Git protocol روی Socket یا SSH استفاده کنید (نگران نباشین، منم معنی اینارو کامل نمیدونم).

نقش Git در DevOps#

حالا که تا حدی! فهمیدین Git رو، باید در نظر داشته باشین که یه بخش مهم از DevOps رو Git تشکیل میده.

ولی سوال اول اینکه DevOps اصلا یعنی چی؟

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

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

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

اینجا بود که یه مفهومی اسم DevOps اومد سر زبونا. این کلمه از دو بخش IT Operations و Developers تشکیل میشه. این مفهوم اومد فاصله بین بخش های مختلف رو کم کرد. و سرعت کار رو بیشتر کرد. تغییرات هم برای انجامشون نیاز به یه پروسه طولانی نبود دیگه. این قضیه باعث میشد کار موفق تر انجام بشه. شکل زیر رو ببینید:

همونطور که توی شکل بالا میبینید، **DevOps** یه چرخه توی سیستم ایجاد میکنه که این قضیه باعث میشه تغییرات سریعتر انجام بشن و برنامه نویسا با بقیه اعضا راحت تر و بیشتر در ارتباط باشن. همینطور میبینید که جایگاه **Git** کجاست و چقدر مهمه. یعنی باعث میشه تغییرات به سرعت بیان توی چرخه و بتونیم اونها رو ردیابی کنیم تا هم اینکه تغییراتی که میدیم رو گم نکنیم، هم اینکه سیستم خطایی نداشته باشه و هم زمان که محصولمون اون بیرونه، تغییرات جدید رو هم اعمال کنیم. چون ممکنه تغییرات یه برنامه نویس توی کار یکی دیگه اختلال ایجاد کنه. با **Git** میشه این مشکل رو حل کرد. برای همینه که **Version Control** نقش مهمی توی موفقیت یه پروژه بازی میکنه.