
گیت (git) ابزار بسیار محبوبی است ولی ممکن است برای افراد تازهوارد که تا کنون با سیستمهای کنترل نسخه کار نکردهاند گیجکننده به نظر برسد. برای اغلب مردم شیرجه زدن در آب کار سادهای نیست. هر کاری مقدماتی دارد و گیت نیز از این قاعده مستثنی نیست. در مقالۀ قبلی با مقدمات گیت آشنا شدید. با توجه به اهمیت درک مفاهیم گیت در این مقاله اطلاعات بیشتری در اختیار شما قرار میدهیم. امید که با دید بهتری سراغ این ابزار رفته و بیشترین بهره را از آن ببرید.
گیت چیست؟
قبل از هر چیز این را بگوییم که گیتهاب، گیت نیست. خیلیها تا اسم گیت میآید فکرشان به سایت گیتهاب میرود در حالی که گیتهاب یک سایت میزبانی برای پروژههایی است که از کنترل نسخۀ گیت استفاده میکنند. این در حالی است که گیت یک سیستم کنترل نسخه (VCS: Version Control System) است. سیستمهای کنترل نسخۀ دیگری هم مثل سابورژن و مرکوریال وجود دارند ولی گیت از همه مخاطب بیشتری دارد و اغلب سایتهای میزبانی پروژه مثل گیتهاب، گیتلب و بیتباکت از این سیستم استفاده میکنند.
هنگامی که یک فایل تغییر میکند، گیت کمک میکند تا بفهمید این تغییرات چه زمانی، توسط چه کسی و چرا اعمال شده است. در واقع گیت برای کنترل تغییرات و نگهداری نسخههای مختلف کد استفاده میشود. گیت در کارهای تیمی، در هنگام نوشتن پایاننامه و حتی برای ذخیرۀ تغییرات اعمال شده در پروژههای گرافیکی کاربرد دارد. مثلا در طراحی یک لوگو با ذخیرۀ تغییرات هر مرحله، به راحتی میتوانید طرحهای مختلف تا رسیدن به لوگوی نهایی را جایی امن نگهداری کنید و هر وقت خواستید به هر نسخهای که دوست داشتید برگردید. همین کار در پروژههای برنامهنویسی بخصوص پروژههایی که چندین نفر به صورت تیمی روی آن کار میکنند به یک ضرورت انکارناپذیر تبدیل میشود.
بسیاری از برنامهنویسان از گیت در پروژههای روزانه خود استفاده میکنند. بسیاری از برنامهها و ابزارهای برنامهنویسی حمایت از گیت را به عنوان یک مزیت مطرح میکنند. مثلاً در اندروید استودیو به راحتی میتوانید کدهای پروژه را با یک دکمه به گیتهاب متصل کنید. حتی در رزومهها و مصاحبهها، آشنایی خوب با گیت یک نقطۀ قوت محسوب میشود. در کارهای تیمی به مراتب اتفاق میافتد که تغییرات همزمانی روی فایلهایی اعمال شده و تداخلاتی به وجود آید. در چنین شرایطی وجود یک سیستم کنترل نسخه برای رفع این تداخلات ضروری به نظر میرسد.
دریافت گیت
بسیاری از IDEها و ابزارهای کدنویسی هنگام نصب به صورت پیشفرض گیت را نصب میکنند. با این حال برای دانلود مستقل قدمهای زیر را بردارید:
- نسخۀ خط فرمانی گیت را میتوانید از اینجا دانلود کنید. این کار را هم به مبتدیها و هم حرفهایها توصیه میکنیم. یک متخصص گیت آشنایی بسیار خوبی با نسخۀ خط فرمانی این ابزار دارد؛
- در صورتی که دنبال نسخۀ گرافیکی هستید، گیتهاب دسکتاپ را پیشنهاد میکنیم. این برنامه در دو نسخۀ ویندوز و مک در اختیار شماست. استفاده از آن آسان است ولی به سختی میتوانید بفهمید چه اتفاقی در پسِ کارهایی که انجام میدهید میافتد.
گیت ذاتاً ابزاری است که حرفهای شدن در آن نیازمند آشنایی خوب با دستورات خط فرمان است. به همین خاطر تا حد امکان از ابزارهای گرافیکی استفاده نکنید تا بدعادت نشود. در مثالهای این مقاله و مقالات آتی هم سعی ما این است که روی نسخۀ خط فرمانی و دستورات گیت تمرکز کنیم تا دقیقاً با فلسفۀ دستورات آشنا شوید.
دستورات رایج گیت
در اینجا تعدادی از دستورات رایج گیت که در اغلب پروژهها استفاده میشود را بیان میکنیم بعلاوۀ توضیح عملکرد هر یک از آنها. سعی کنید تمام دستورات را خودتان انجام دهید. در پایان یک مثال واقعی آوردهایم که میتوانید همۀ دستوراتش را یکجا با هم تست کنید.
توجه:
- هر اصطلاحی برای اولین بار که بیان میشود بولد شده است. برای دریافت جزئیات بیشتر از این اصطلاحات شما را دعوت میکنیم به واژهنامه گیت یا رفرنس اصلی آن؛
- راهنمای پیشِ رو یک راهنمای ساده و ابتدایی است که بدون پرداختن به جزئیات تلاش کرده تا مقدمات لازم را منتقل کند؛
- در مطلب حاضر توضیحاتی آمده که خواندن آن به درک بهتر گیت کمک میکند پس حتی اگر قبلاً با دستوری کار کرده بودید باز هم توضیحات ارائه شده را بخوانید تا دید بهتری نسبت به آنها پیدا کنید.
ساخت یک مخزن یا repository جدید
git init
بعد از اجرای این دستور یک فولدر مخفی به نام git. در ریشۀ فولدر ایجاد میشود که همان مخزن یا repository یا به اختصار repo شماست. تمام تغییرات پروژه در این فولدر نگهداری و کنترل میشود. اکنون گیت میتواند هر تغییری در هر فایلی در پروژۀ اصلی را ردیابی کند. فولدر اصلی پروژه، working directory محسوب میشود و محتویات و تغییرات آن در فولدر git. ذخیره و ردیابی میشود.
کپی کردن مخزن
git clone https://github.com/cooperka/emoji-commit-messages.git
کاری که این دستور انجام میدهد کپی کردن مخزن git. از یک پروژه در اینترنت (مثلاً گیتهاب) به کامپیوتر شما و استخراج آخرین snapshot آن مخزن (همۀ فایلهای موجود) به working directory است. در حالت پیشفرض نام فولدر همنام مخزن پروژه خواهد بود (در مثال بالا emoji-commit-message).
آدرس URL مخزن اصلاحاً remote origin (محلی که فایلها به صورت اورجینال از آن دانلود میشود) نام دارد. از این اصطلاح بعداً استفاده میکنیم.
نمایش وضعیت فعلی پروژه
git status
این دستور اطلاعات اولیهای دربارۀ پروژه نمایش میدهد. اطلاعاتی مثل فایلهایی که اخیراً ویرایش شدهاند. هر زمان گیج میشوید اولین کار چک کردن وضعیت پروژه است. به کمک این اطلاعات از سردرگمی نجات مییابید.
ساخت یک شاخۀ جدید
git branch <new-branch-name>
این دستور را میتوانید مثل ساختن یک چک پوینت تصور کنید (یا اصلاحاً reference) که نامی برای آن انتخاب کردهاید. چیزی مثل save as کردن فایل است. شاخه یا انشعاب جدید، رفرنس یا ارجاعی به وضعیت فعلی مخزن شماست. نام شاخه بعدها در دستوراتی که خواهید دید به کار میرود.
همچون شاخه، معمولاً چکپوینتها را هر از چند گاهی به شکل commit ذخیره میکنید. کامت نوع خاصی چکپوینت بوده که نامش revision است. هر کامت یک هشکد تصادفی دارد که ترکیبی از اعداد و حروف مثل e093542 است. این هش کد در بسیاری از دستورات دیگر گیت به کار میرود.
ماهیت اصلی گیت همین ذخیرۀ چکپوینتها (revisionها) و اشتراکشان با افراد دیگر است. هر چیز دیگری حولِ این مفهوم است.
Branching یا کار با شاخهها مفهوم بسیار گستردهای است که در این باره بعداً بیشتر صحبت میکنیم. ولی اگر مایل به مطالعۀ بیشتر هستید میتوانید به این لینک مراجعه کنید.
چکاوت کردن یک شاخه
git checkout <existing-branch-name>
همانطور که در مقالۀ قبلی هم اشاره کردیم، بعد از ساخت یک شاخه هنوز در شاخۀ اصلی پروژه یعنی مستر قرار داریم. برای اینکه به شاخۀ جدید سوئیچ کنیم باید چکاوت کنیم. چکاوت مثل این است که به گیت بگوییم از حالا به بعد شاخۀ کاری را به فلان چکپوینت تغییر بده.
راه سادهتری هم هست که به جای ساخت شاخۀ جدید و سپس چکاوت کردن، هر دو کار با هم انجام شود. با سوئیچ b- در دستور checkout میتوانید این کار را انجام دهید:
git checkout -b <new-branch-name>
دستور فوق ابتدا یک شاخۀ جدید ایجاد کرده سپس به آن شاخه سوئیچ میکند یعنی با یک تیر دو نشان.
مشاهدۀ تفاوت دو چکپوینت (یا دو شاخه)
git diff <branch-name> <other-branch-name>
بعد از ویرایش چند فایل به آسانی میتوانید با تایپ دستور git diff تغییرات حاصل را مشاهده کنید. این کار برای وقتی که میخواهید تغییرات ایجاد شده را قبل از کامت، دو مرتبه چک کنید مفید است. برای هر گروهی از تغییرات، آنچه قبلاً بوده با علامت خط تیره و رنگ قرمز و آنچه بعد از تغییرات اعمال میشود با علامت + و رنگ سبز نشان داده میشود. برای دیدن مثالهای پیشرفتهتر ادامۀ مطلب را بخوانید.
استیج کردن تغییرات برای کامت
git add <files>
بعد از ویرایش هر فایل، این دستور تغییرات اعمال شده را در حالت Staged قرار میدهد که یعنی آمادۀ کامت گرفتن هستند. برای اطمینان از این گفته دستور git status را وارد کنید تا بفهمید چه اتفاقی در حال رخ دادن است. بخشی وجود دارد تحت عنوان Changes to be committed که با عناوین فایلها به رنگ سبز ادامه یافته و بخش دیگری به نام Changes not staged for commit که با اسامی فایلها به رنگ قرمز دنبال میشود. این فایلهایی که رنگشان قرمز است یعنی هنوز استیج نشدهاند. ابتدا باید با دستور git add استیج کنید، سپس با git commit تغییرات را کامت نمایید.
همانند ترمینال یا اکسپلورر ویندوز اینجا نیز میتوانید از wildcard استفاده کنید. مثلا:
git add README.md app/*.txt
این دستور فایل Readme.md و هر فایل متنی منتهی به txt. که در فولدر app قرار دارد را به ناحیه stage اضافه میکند. برای اضافه کردن همۀ فایلها نیز میتوانی از دستور git add –all استفاده نمایید.
کامت کردن تغییرات استیج شده
git commit
با وارد کردن این دستور یک تکست ادیتور خط فرمانی باز شده و از شما پیامی برای آن کامت درخواست میکند. بعد از ذخیره و خروج از ادیتور، کامت مورد نظر با پیام وارد شده ذخیره میشود. همچنین با سوئیچ m- میتوانید مستقیماً پیغام مورد نظر خود را برای آن کامت ثبت کنید:
git commit -m “Add a new feature”
پیام فوق برای اینکه دیگران بفهمند چه تغییراتی و چرا اعمال شده ضروری است. مثلاً رفع فلان باگ یا ریفکتورینگ فلان تابع و … . از آنجایی که یکی از بزرگترین مشکلات برنامهنویسان همین بحث نامگذاری است بهتر است کمی درمورد نوشتن یک commit message خوب بحث کنیم.
به عنوان یک اصل کلی هرچقدر طول پیام کوتاهتر باشد بهتر است. معمولاً ۵۰ کاراکتر و کمتر طول مناسبی برای پیام است. در پیغامهای انگلیسی کاراکتر اول را به صورت بزرگ وارد کنید. برای پیامهای طولانیتر، پاراگراف را به خطوط ۷۲ کاراکتری Wrap کنید. در این پیامها خط اول مثل عنوان ایمیل موضوع کلی است و خطوط بعدی که با یک خط خالی از عنوان جدا میشود جزئیات آن پیام را بیان میکند. این تقسیم ۷۲ کاراکتری سلیقهای نیست و اصولی پشت آن هست:
- در دستور git log هیچ wrap پیشفرضی وجود ندارد. این یعنی در تریمینالی که طول کاراکترهای آن ۸۰ ستون عمودی است خواندن پیامهای طولانی سخت خواهد شد. اگر ۴ ستون از چپ برای تورفتگی و ۴ تا از راست برای حفظ تقارن از این عدد کم کنیم به ۷۲ میرسیم؛
- دستور git format-patch –stdout مجموعهای از کامتها را به مجموعهای ایمیل تبدیل میکند. یک ایمیل خوب به چندین خط کوتاهتر شکسته میشود تا در هنگام ریپلای زیباتر جلوه کند. طول ۷۲ برای خطوط ایمیل مناسب به نظر میرسد؛
پیام را به صورت الزامآور و دستوری بنویسید مثلاً Fix bug نه Fixed bug و نه Fixes bug. این قاعده را میتوان در دستورات git مثلاً git merge و git revert هم مشاهده کرد. پاراگرافهای اضافی حتماً بعد از یک خط خالی نوشته شوند. از بولت پوینتها هم میتوانید استفاده کنید که معمولاً از خط تیرهای که یک فاصله بعد از آن واقع شده استفاده میشود. تورفتگی بولت پوینتها را هم فراموش نکنید.
پوش کردن شاخه برای آپلود کردن در جایی دیگر
git push origin <branch-name>
این دستور انشعاب شما را به origin که روی سرور قرار دارد آپلود خواهد کرد (آدرس url آن را با دستور clone وارد کردید). بعد از پوش موفق، سایر افراد میتوانند با pull کردن، تغییراتی که اعمال کردهاید را در یافت کنند. به عنوان یک شورتکات به جای branch-name میتوانید کلمۀ Head را وارد کنید تا به صورت خودکار شاخهای که در حال کار روی آن هستید در نظر گرفته شود. Head همیشه به آخرین چکپوینتی که آخرین کامت بر روی آن گرفته شده اشاره میکند.
همانطور که قبلاً هم اشاره کردیم، هر چیزی در گیت به چکپوینتها ربط پیدا میکند. فهرست پایین، انواع چکپوینتهایی هستند که تاکنون با آن آشنا شدهاید (باز هم تکرار میکنیم، به لحاظ فنی به این چکپوینتها، رفرنس یا revision گفته میشود):
- Head
- branch-name مثلاً master
- commit-hash مثل: e093542d01d11c917c316bfaffd6c4e5633aba58 (یا به صورت کوتاه e093542 )
- tag-name مثلاً v1.0.0
- stash
کاراکترهای بخصوصی مثل ^ ~ @ {} میتوانند برای اصلاح رفرنسها استفاده شوند. این علامتها واقعاً مفید هستند. در این لینک میتوانید اطلاعات بیشتری به دست آورید.
فچ کردن آخرین اطلاعات مخزن
git fetch
این دستور آخرین اطلاعات دربارۀ مخزن را از شاخۀ origin (یا سایر شاخهها) که روی سروری مثل گیتهاب قرار دارند دریافت میکند. دستور فوق هیچ فایلی را تغییر نمیدهد، فقط اطلاعات ترکینگ فولدر git. را بروزرسانی میکند.
ادغام شاخهها
git merge <other-branch-name>
این دستور تمام کامتهای موجود در شاخۀ other-branch-name را دریافت کرده و آنها را در شاخهای که در آن هستیم ادغام میکند. دستور فوق روی دادههایی که به صورت محلی روی سیستم شما ذخیره شدهاند عمل میکند بنابراین قبل از استفاده از آن ابتدا با دستور git fetch آخرین اطلاعات مخزن را دانلود کنید. به عنوان مثال اگر شخصی تعدادی کامت به شاخۀ master در origin (روی سرور) اضافه کرده باشد. شما میتوانید با دستورات پایین، شاخۀ مستر سیستمتان را به آخرین نسخهای که روی سرور قرار دارد آپدیت کنید:
git checkout master # Make sure you're on the right branch.
git fetch # Download any new info from origin.
git merge origin/master # Merge the 'origin/master' branch
into your current branch.
برای اینکه گیت متوجه شود منظور ما از master کدام مستر است باید origin/master را در دستور آخر وارد کنیم. یعنی آخرین تغییرات مستر در origin را با مسترِ محلی ادغام کن.
برای این کار میانبری هم وجود دارد. دستور pull. این دستور کار fetch و merge را با هم و در یک قدم انجام میدهد. معمولاً از همین روش استفاده میشود.
git pull origin master
در این دستور origin و master را از هم جدا کردهایم و مثل دستور قبلی از اسلش استفاده نکردهایم. دلیلیش این است که قصد ما استفاده از چکپوینت origin/master که به صورت محلی روی سیستم ذخیره شده نیست. اکنون میخواهیم آخرین نسخۀ مستر را از سرور دریافت و مستر محلی را با آن ترکیب کنیم. به تفاوت این دو دستور دقت کنید. برای درک بهتر دستور و آشنایی با روشهای حل تداخلات، مستندات رسمی merge را بخوانید. در این مورد احتمالاً بعدها مطلبی منتشر خواهیم کرد.
یک مثال واقعی
دستورات پایین یک مثال فرضی را نشان میدهند که روی یک پروژه اجرا شده است. سعی کنید ابتدا به ماهیت و عملکرد هر یک فکر کنید، سپس برای اطمینان دستورات را اجرا کنید.
git clone https://github.com/cooperka/emoji-commit-messages.git
cd emoji-commit-messages
git status
git checkout -b my-new-feature
echo “This is a cool new file” > my-file.txt
git status
git add --all
git status
git diff HEAD
git commit -m “Add my-file.txt”
git status
git log
git push origin HEAD
git checkout master
git pull
اغلب این دستورات پارامترهای اضافهای هم دارند که با کمکشان میتوانید دستور را کاستومایز کنید و معمولاً برای انجام یک کار چندین روش مختلف وجود دارد.
دستورات این مقاله آغاز راه حرفهای شدن در گیت است. هنوز چیزهای بیشتری هست که باید بدانید. در قسمت بعدی این مقاله یاد میگیرید چگونه از گیت در یک تیم استفاده کنید.
2 دیدگاه
مرسی دوست خوبم ❤?
سلام خسته نباشید مقاله عالی بود و خیلی بدرد تکمیل اطلاعات من خورد. سپاس از شما