Git Workflow
حالا که یک ریپوی گیت داریم، بیاین راجع به جریانِ کلی گیت صحبت کنیم، یعنی چیزی که ما روزانه در حین استفاده از گیت انجام میدیم.
در ویدیویِ زیر، دایرکتوری پروژهمون و ریپوی گیتمون (دایرکتوریِ مخفی در پروژه) رو میبینیم. روزانه ما یک یا چند فایل رو تغییر میدیم. وقتی پروژهمون به یک سطحی میرسه که میخواهیم بایگانیش کنیم (record) اون تغییرات رو در ریپومون، commit (معنایِ لغویش؛ انجام دادن و مرتکب شدن) میکنیم. ساختِ یک commit مثلِ ساختنِ یک snapshot (عکس) از پروژمونه.
حال در گیت، ما یک فضایِ دیگهای یا یک قدمِ میانیِ مشخصی رو هم داریم که در بسیاری از سیستمهایِ Version Control وجود نداره. این area رو staging area یا index میگن. که اساساً فضایی هستش که توش فایلهایی که قراره برای commit یا snapshot بعدی، ارائه و آماده بشن، هستش. یعنی زمانی که تغییرات رو اعمال کردیم، فایلهایِ تغییردادهشده رو به Staging area یا index اضافه میکنیم، تغییرات رو بررسی میکنیم و اگر همه چیز درست بود یک commit میسازیم.
یک snapshot به طورِ دائم، داخلِ ریپومون ذخیره میشه. پس staging area به ما امکانِ بازبینی و بررسیِ کدمون رو قبل از بایگانی و ضبط یک snapshot میده. اگر بعضی از تغییرات نباید به عنوانِ بخشی از snapshot بعدی ضبط بشن میتونیم اونها رو unstage کنیم و به عنوانِ بخشی از یک snapshot دیگه commit کنیم.
این جریانِ کار کلی گیت هست.
حال بذارین یه مثالِ واقعی بزنم. این مثال مهمه. پس خیلی دقیق تا آخر گوش کنین. حتی اگه فکر میکنین که مباحث کلی رو میدونین.
دایرکتوری پروژهی ما الان خالیه. پس یه سری فایل بهش اضافه میکنیم. حال اگه آمادهاین تا این قدم رو ضبط کنین، از دستورِ add برای افزودنِ این فایلها به staging area استفاده میکنیم.
حال این فایلها در staging area هستن.
این قدمیه که به منظور آماده شدن برای commit بعدی انجام میدیم. این فایل رو بررسی میکنیم. همه چیز عالیه. پس از دستورِ commit استفاده میکنیم تا به طورِ دائم داخلِ snapshot در ریپو ذخیرهش کنیم. برای commit یه پیامِ معنادار قرار میدیم تا مشخص کنیم که این snapshot چه چیزی رو ارائه میده. این برای داشتنِ یک هیستوریِ معنادار بسیار ضروریه.
یعنی اگر باگها رو رفع کنیم و یا ویژگیهایِ جدید پیادهسازی کردیم و یا کدمون رو بازساخت (refactor) کردیم یک commit میسازیم و هر commit کامل و واضح وضعیتِ پروژه رو در اون بازهی زمانی توضیح و مشخص میکنه.
حالا یک commit در ریپومون داریم. یک اشتباه در مورد گیت اینه که زمانی که ما تغییرات رو commit میکنیم staging area خالی میشه. این درست نیست و این مسئله یکی از دلایلِ سردرگم کردن خیلیهاست.
چیزی که الان در staging area داریم همان snapshotای است که در ریپو ذخیره کردیم. این staging area در واقع بسیار شبیه به محیط Stagingای هست که ما زمانِ انتشارِ نرمافزار به عنوانِ محصولِ نهایی استفاده میکنیم یا یه انعکاس از چیزیه که در تولید (production) داریم یا نسخهی بعدیایه که قراره در تولید یا production باشه.
ادامهی مثالمون رو از سر بگیریم. بیاین بگیم که به عنوانِ رفع یک باگ، ما یه سری تغییرات رو در یک فایل اعمال میکنیم.
نکته: چیزی که الان در staging area داریم نسخهی قدیمیِ file1 هست. چون ما هنوز تغییرات رو stage نکردیم. دوباره از دستورِ add استفاده میکنیم تا تغییرات رو stage کنیم.
حال چیزی که در staging area داریم همون محتواییه که در دایرکتوریِ کاریمون (Working Directory) داریم. بیاین یه commit برای ضبطِ این سطح انجام بدیم. حالا دو تا commit در repositoryمون داریم. به پیامِ commit توجه کنید که داره باگی رو که تازه رفع کردیم رو توصیف میکنه.
حال بیایین بگیم که ما متوجه شدیم که دیگه فایلِ file2 رو نمیخواهیم و کد غیرقابلِاستفادهای رو داره. خب از دایرکتوریِ کاریمون پاکش میکنیم اما این فایل هنوز در staging area هست. پس دوباره باید از دستورِ add استفاده کنیم تا این تغییر رو هم در stage اعمال کنیم که در این مورد پاک کردنه.
اینجا بخشِ جالبشه. علیرغمِ اینکه میگیم add file2
گیت میدونه که file2 پاک شده. پس از staging area یا snapshot بعدی (next snapshot) (که خواهد شد) هم پاکش میکنه.
دوباره یه commit میسازیم تا به طور دائم این مرحله رو ضبط کنیم.
حالا 3 تا کامیت در ریپومون داریم.
هر کامیت شاملِ یک ID منحصربفرد هستش که توسطِ گیت ساخته میشه. مثل یه عدد بازبینیه (revision number)
💡 The revision number is **the number of times the document has been saved**. That means it should correspond to the Date Modified field in the file manager, sometimes called Date Last Saved. (Note that using Save As resets the revision number to 1 in the new file.)
همچنین هر کامیت شاملِ اطلاعات در مورد اینکه چی تغییر کرده و توسط چه کسی و چه زمانی این تغییر اعمال شده و همینطور یک عکس کامل از پروژهمون، وقتی که ساخته شده، هستش.
پس برخلاف خیلی از سیستمهایِ Version Control دیگه، گیت دلتاها و اینکه چی تغییر کرده رو ذخیره نمیکنه. محتوای کامل رو ذخیره میکنه. اینطوری میتونه سریعاً پروژهمون رو به یک snapshot قبلی، بدونِ محاسباتِ تغییرات، برگردونه.
حالا ممکنه بپرسین که ذخیرهی محتوای کلی در هر snapshot کلی فضا حروم نمیکنه؟ نه. چون گیت خیلی در ذخیره اطلاعات دقیق و کارآمده. محتوایِ فایل رو فشرده میکنه و چند نمونه از یک فایل رو ذخیره نمیکنه (duplicate content).
حال به عنوانِ کسی که از گیت استفاده میکنه اصلاً نیازی نیست که بدونین گیت چطور اطلاعات رو ذخیره میکنه. این یک اطلاعات پیادهسازی داخلِ خودِ گیت هستش و ممکنه که در آینده تغییر هم بکنه. چیزی که باید بدونین اینه که هر کامیت شاملِ یک snapshot کامل از پروژهمون میشه و این به ما این اجازه رو میده که سریعاً برگردیم به یک نسخهی قبلی.
در این جلسه یه دیدِ کلی پیدا کردید. در جلساتِ بعدی، این جریان و نحوهی کار رو در عمل خواهیم دید.