با این که بارها گفته شده است، اما اگر یک بار دیگر نیز تکرار کنیم، خالی از لطف نخواهد بود که همه توسعه‌دهندگان نرم‌افزار باید از یک ابزار «کنترل نسخه» (Version Control) استفاده کنند. چه بهتر که این ابزار کنترل نسخه که استفاده می‌کنید، یکی از محبوب‌ترین ابزارها در سراسر دنیا یعنی Git باشد که همه افراد نام آن را شنیده و با آن آشنا هستند. در این مقاله با نکات و ترفندهای گیت (Git) آشنا خواهیم شد.

در صورتی که علاقه ندارید از سرورهای مشهور میزبانی گیت مانند GitHub ،GitLab یا Bitbucket استفاده کنید، یا این کار برای شما مناسب نیست، می‌توانید یک سرور ریپازیتوری را به صورت خصوصی روی سرورهای خودتان میزبانی کنید.

نکات و ترفندهای Git

مبانی Git

در این بخش برخی مفاهیم ابتدایی در خصوص Git و به طور کلی کنترل نسخه مطرح می‌شوند.

منظور از کنترل نسخه چیست؟

کنترل نسخه را می‌توان به عنوان نقاط ذخیره‌سازی کد توصیف کرد. فرض کنید یک فیچر جدید را به تازگی برای یک محصول که در حال استفاده است به اتمام رسانده و همه چیز را مستندسازی کرده‌اید و اینک می‌خواهید کد را به مدل پروداکشن اضافه کنید. به این منظور باید یک «مرور کد» (Code Review) اضافه شود تا بتوانید کد را به کنترل سورس اصلی اضافه (Merge) کنید. اگر شرکتی که در آن کار می‌کنید از کنترل نسخه استفاده نکند، شما مجبور خواهید بود تغییرات را به صورت دستی در پروژه سورس وارد کنید. همه این‌ها در حالی است که یک نفر باید پشت میز شما بنشیند و تغییراتی را که شما ایجاد کرده‌اید به صورت دستی بازبینی کند.

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

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

نکات و ترفندهای Git

چرا باید از کنترل نسخه استفاده کنیم؟

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

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

پس‌زمینه Git

Git از سوی خالق لینوکس، ‌«لینوس تروالدز» (Linus Torvalds) در سال 2005 معرفی شده است. هر ریپازیتوری (به اختصار ریپو یا repo) دارای امکان ردگیری کامل تاریخچه و همچنین کنترل نسخه است که مستقل از هر سرور مرکزی عمل می‌کند. افراد دیگر می‌توانند در صورت اجازه شما، کد را مستقیماً از رایانه شما دریافت کنند، اما ما عموماً از یک سرور مرکزی برای اشتراک و میزبانی فایل‌ها برای تیم کاری استفاده می‌کنیم.

برای کسب اطلاعات بیشتر در مورد گیت و ابزارهای مربوطه می‌توانید از مطالب زیر استفاده کنید:

ریپو چیست؟

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

مقداردهی یک ریپو

مقداردهی اولیه یک ریپو که Initializing نامیده می‌شود، می‌تواند از خط فرمان یا اغلب ابزارهای ارتباط ریموت انجام گیرد. گیت‌هاب ابزاری به نام repo.new link دارد که با استفاده از دستورات آن می‌توان پوشه مورد نظر را مقداردهی کرد:

شما اکنون درون این پوشه my-project، یک پوشه به نام git. دارید چیزی را تغییر ندهید، مگر این که بدانید چه کار می‌کنید. به هم ریختن این پوشه می‌تواند به قیمت از دست رفتن ریپوی لوکال تمام شود.

کلون کردن ریپو

یک روش عالی برای ورود به گیت از طریق کامیت کردن یک پروژه قبل ایجاد شده از طریق کلون کردن یکی از پروژه‌های روی گیت‌هاب، گیت‌لب یا هر میزبان ریموت دیگر با دستور زیر است:

به این ترتیب ریپویی که در آن لینک گیت‌هاب قرار دارد و در دایرکتوری جاری زیر پوشه ‎./my-project کلون می‌شود. اگر تداخل نام پیش آید، از طریق خط فرمان به اطلاع خواهد رسید.

کلون کردن موجب می‌شود که همه داده‌های پروژه در رایانه لوکال قرار گیرد و یک درخت کاری لوکال ایجاد شود. تغییراتی که در این پروژه لوکال انجام می‌شوند تأثیری روی ریپوی ریموت نخواهند داشت، مگر این که از دستور git push به شاخه مرتبط ریپوی ریموت استفاده کنید.

کامیت

کامیت به روش ذخیره‌سازی تغییرات جاری در پوشه کاری گفته می‌شود. زمانی که کار خود را به پایان رساندید، مثلاً یک فایل README.md برای توصیف پروژه اضافه کردید، باید کار خود را ذخیره کنید. البته کار را می‌توانید هر زمان که دوست داشتید ذخیره کنید. زمانی که در نهایت کامیت کردید، همواره از یک پیام کامیت استفاده کنید که تغییرات انجام یافته درون کامیت را توصیف کند.

پیش از اجرای کامیت باید فایل‌هایی که تغییر یافته‌اند را به دایرکتوری staging جاری استفاده کنید. به این منظور از دستور زیر استفاده می‌کنیم:

با استفاده از فلگ all– همه فایل‌های تغییر یافته درون پروژه git کنونی اضافه می‌شوند. برای اجرای عملی دستور کامیت باید دستور زیر را در کنسول اجرا کنید:

ایجاد یک ژورنال کنترل شده نسخه شخصی

نکات و ترفندهای Git

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

یک پنجره ترمینال (اعلان فرمان) را باز کنید. به دلخواه خود به یک دایرکتوری بروید. مثلاً می‌توانید به صورت زیر عمل کنید:

اکنون اپلیکیشن را با دستور زیر مقداردهی می‌کنیم:

ایجاد سند

سپس یک سند جدید به دلخواه ایجاد می‌کنیم. این سند می‌تواند یک سند ورد، Vim ،‌Nano ،‌Pages ،Gedit ،‌PyCharm ،‌notes‌ و یا هر چیز دیگری باشد که بتوان چیزی درون آن نوشت. هر چه که به ذهنتان می‌رسد در این سند متنی بنویسید. زمانی که این متن را نوشتید، باید آن را ذخیره کنیم. به منظور کامیت کردن تغییرات باید از دستورهای زیر در ترمینال استفاده کنیم:

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

نکات کنترل نسخه

نکات و ترفندهای Git

درختکاری

منظور از «درختکاری» (Working Tree) حالت فایل‌ها در یک دایرکتوری است. برای نمونه پروژه می‌تواند از یک ریپوی ریموت کلون شده باشد. در این صورت درخت کاری و نقطه Head بدون هیچ تغییری به صورت همان کامیت است. به محض این که فایل‌ها تغییر یابند، دیگر در همان HEAD نخواهند بود. زمانی که تغییرات کامیت و پوشش شوند، درخت لوکال و ریموت شما دوباره با همان ارجاع کامیت HEAD تطبیق می‌یابند. برای کسب اطلاعات بیشتر به مستندات (+) مراجعه کنید.

نکات و ترفندهای Git

شاخه‌سازی

استفاده از «شاخه» (branch) در ریپوی گیت امری ضروری است. با این که اساساً ما به یک شاخه (یا main یا هر نام دیگر) نیاز داریم، اما استفاده از بیش از یک شاخه در زمان کار در یک تیم امری ضروری است. به خصوص در صورتی که نمی‌خواهید به طور مداوم تداخل‌های هر کامیت را رفع کنید، باید از این روش استفاده کنید.

شاخه‌ها را می‌توان مانند قطارهای مختلف فکری تصور کرد. هر شاخه یا برنچ یک قطار متفاوتی از افکار، یک فیچر متفاوت، اصلاحیه، اثبات مفهوم (proof-of-concept) و یا هر چیز دیگر است. استفاده از شاخه‌ها به این روش کاملاً ضرورت دارد، تا زمانی که ایده پایان یافت، بتوان به سرعت و به طرز مناسبی به منبع اصلی (شاخه پیش‌فرض)‌ اضافه کرد.

برای آغاز کار با شاخه‌ها در یک ریپازیتوری انتخابی، دستور زیر را برای بررسی شاخه‌هایی که هم اینک موجود هستند، اجرا کنید:

فهرست شاخه‌ها

به این ترتیب فهرستی از شاخه‌ها دیده می‌شوند که هم اینک بخشی از ریپازیتوری هستند. این فهرست از نام ریموت (معمولاً origin) پیش از ایجاد شاخه استفاده می‌کند. پیش از آن که با روش ایجاد شاخه آشنا شویم، با روش سوئیچ کردن بین شاخه‌ها آشنا خواهیم شد. برای استفاده از یک شاخه دیگر (مانند dev) کافی است دستور زیر را اجرا کنید:

یا از دستور زیر استفاده کنید:

در زمان ایجاد یک شاخه جدید سه گزینه در اختیار داریم:

  • Checkout

چک‌اوت با فلگ b- برای برنچ موجب به‌روزرسانی درخت کاری برای تطبیق با نسخه مفروض در اندیس یا درخت مشخص شده می‌شود و سپس یک برنچ از نسخه می‌سازد. چک‌اوت ما را مطمئن می‌سازد که هرگز شاخه جدید را به وسیله یک هد جدا شده نساخته‌ایم و از بروز بسیاری از مشکلات جلوگیری می‌کند.

  • Branch

نکته جالب اینجا است که Branch گزینه نخست ما نیست؛ بلکه همواره باید نخست از چک‌اوت استفاده کنیم. با این حال Branch صرفاً برنچ را ایجاد می‌کند و مانند checkout یا switch به صورت خودکار به برنچ سوئیچ نمی‌کند. همچنین با استفاده از دستور برنچ می‌توانیم دو شاخه را در زمان استفاده از مرجع‌های شاخه با دستور زیر ادغام کنیم:

اما این کار به تمیزی دستور چک‌اوت انجام نمی‌یابد.

  • Switch

استفاده از گزینه Switch با فلگ c- برای «ایجاد» موجب ایجاد یک شاخه جدید و سوئیچ به شاخه می‌شود. سوئیچ کردن الزامی برای ایجاد یک ریپازیتوری تمیز ندارد و می‌تواند به صورت detach-شده از شاخه اصلی باشد. همچنین سوئیچ کردن به صورت خودکار از ریپازیتوری ریموت انجام می‌یابد.

گردش گیت

نکات و ترفندهای Git

دستور Git Flow شاخه‌های گیت را مدیریت می‌کند. Flow یک سیستم برای مدیریت شیوه ساخت شاخه‌ها از سوی توسعه‌دهندگان ارائه می‌کند و از این رو دیگر شاهد شاخه‌هایی نخواهیم بود که نامتمرکز هستند و یا روی یک فیچر منفرد آغاز شده باشند، اما سپس به اشتباه به شاخه main تبدیل شوند.

تعریف کردن یک ساختار برای شاخه‌ها موجب حذف نیاز به overbear روی آن چیزی که پروژه متمرکز شده است می‌شود. برای نمونه Flow-یی که مناسب است و بهتر است در اغلب پروژه‌ها استفاده کنید از اصولی که در ادامه ارائه می‌کنیم پیروی می‌کند.

گردش گیت ریپازیتوری

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

به طور کلی چهار نوع شاخه برای یک پروژه می‌توان تعریف کرد:

  • – master
  • – release
  • – hotfix/*
  • – feature/*

شاخه master

شاخه مستر یک شاخه کاملاً خاص است. این شاخه شامل نسخه کنونی «پایدار» (stable) از پروژه است. این شاخه در برابر push-های اجباری حفاظت می‌شود، یعنی کسی نمی‌تواند یک کامیت یا merge را به آن اضافه کند یا پوش نماید. هر چیزی که به مستر اضافه می‌شود، باید از طریق یک درخواست pull باشد تا کد بتواند مرور، تست و پذیرفته شود. فیچرهای جدید باید از master انشعاب بگیرند، اما این کار الزامی نیست.

شاخه Release

شاخه release یا «انتشار» جایی است که نسخه پایدار پروژه میزبانی خواهد شد. زمانی که پروژه به نقطه خاصی برسد و آماده انتشار برای عموم باشد، نسخه پروژه‌ای که توزیع می‌شود، نسخه کنونی شاخه master است که از طریق درخواست pull در شاخه release ادغام می‌شود. درخواست pull آخرین کاری است که پیش از آغاز به کار پایپلاین CI/CD برای توزیع نسخه روی استریم‌های مختلف انجام می‌یابد.

شاخه‌های */Hotfix

شاخه‌های Hotfix (به این جهت از لفظ شاخه‌ها استفاده می‌کنیم که Hotfix/ یک ساختار پوشه است) برای ایجاد یک اصلاحیه باگ از شاخه master مورد استفاده قرار می‌گیرد. هات‌فیکس‌ها به طور خاص برای باگ یا مشکل ساخته شده‌اند و زمانی که باگ رفع شود، مجدداً به درخواست pull مستر اضافه شده و مستقیماً در آن ادغام می‌شوند. به این ترتیب شاخه متمرکز و کوچکی ایجاد می‌شود که تداخلی با شاخه‌های فیچر ندارد.

شاخه‌های */Feature

شاخه‌های Feature/*‎ نیز تا حدود زیادی شبیه به شاخه‌های hotfix هستند، با این حال گستره آن‌ها کمی وسیع‌تر است و شامل یک فیچر جدید در خود پروژه می‌شوند. شاخه‌های فیچر باید دامنه کوچکی داشته باشند. برای نمونه feature/multiplayer بسیار وسیع است، feature/matchmaking کمی بهتر است، feature/server-and-connection کاملاً مناسب است. کافی است تلاش کنید خاص و متمرکز روی یک موضوع باشد که آماده ادغام در شاخه مستر (محیط پروداکشن) است.

روش‌شناسی فوق در زمانی که روی پروژه‌های تیمی کار می‌کنید، کارایی خود را بیشتر نشان می‌دهد. همواره از شاخه release هر چند در پروژه‌های ساده استفاده کنید. همچنین به خاطر بسپارید که شاخه master|main باید تنها شاخه پایدار release در هر زمان باشد. این بدان معنی است که وقتی فیچرها به پروژه اضافه می‌شوند، فیچرهای کاملی هستند و دست کم مقداری تست روی آن‌ها اجرا شده است.

اکنون که با گیت بیشتر آشنا شدید، شاید حس کنید که درک کامل آن، کاری خسته‌کننده است. بنابراین پیشنهاد می‌کنیم از ابزاری به نام GitKraken (+) استفاده کنید تا به سادگی پروژه‌ها را در نگاه نخست تحلیل نمایید.

سازمان‌دهی کامیت‌ها

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

نکات و ترفندهای گیت

نکات و ترفندهای Git

در این بخش برخی ترفندهای پیشرفته در خصوص گیت را با هم مرور می‌کنیم.

Git Blame

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

حال فرض کنید یک توسعه‌دهنده پنج تغییر و توسعه‌دهنده دیگر دو تغییر در کد ایجاد کرده‌اند. بدون بررسی تک‌تک خطوط کدهای کامیت شده چطور می‌توان مشکل را رفع کرد؟ در این حالت کافی است دستور Git Blame را اجرا کنید. به این ترتیب تمام خطوطی که در کامیت آخر تغییر یافته‌اند نمایان می‌شوند و به این ترتیب مشخص می‌شود که چه کسی را باید برای ایجاد خطا سرزنش (Blame) کرد. همچنین می‌توانید alias را با استفاده از دستور زیر تغییر دهید:

Git Bisect

فرض کنید یک باگ بین 5 کامیت دارید. کامیت 1 آخرین موردی است که به درستی کار می‌کرد و می‌دانید که کامیت 2 و کامیت 4 باگ دارند، اما در مورد کامیت‌های 4 و 5 مطمئن نیستید. با استفاده از زیردستور Git Bisect می‌توانید در میان کامیت‌ها پیمایش کنید و بفهمید که کدام یک به درستی بیلد نمی‌شوند. به طور خاص می‌توانید کامیتی که باگ را وارد برنامه کرده است پیدا کنید. فرض کنید پروژه‌ای که از آن صحبت کردیم، یک پروژه npm است:

نکات و ترفندهای Git

با استفاده از کد فوق می‌توانیم بفهمیم که تست کجا fail می‌شود و فایل‌هایی که با git diff تغییر یافته‌اند را بررسی کنیم. بدین ترتیب یک ایده کلیدی مهم دیگر مشخص می‌شود. مطمئن شوید که در پروژه خود از تست استفاده کرده‌اید تا سیستم کنترل نسخه در زمان شما صرفه‌جویی کرده و باگ‌ها را پیدا کند.

Git Commit Amend

فرض کنید به تازگی چیزی را کامیت کرده‌اید و یک فایل به‌روزرسانی شده است. اکنون می‌خواهید آن را پیش از پوش کردن به کامیت آخر اضافه کنید. در این حالت کافی است از فلگ ‎–amend استفاده کنید.

برای اجرای این کار باید از دستور زیر استفاده کنید:

به این ترتیب فایل‌ها اضافه می‌شوند و مدیریت ادغام در ‎$EDITOR پیکربندی‌شده شما از CLI اجرا می‌شود. اگر از VIM استفاده می‌کنید با وارد کردن ‎:wq از آن خارج می‌شوید.

مدیریت اطلاعات احراز هویت Git

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

سخن پایانی

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

اگر این مطلب برای شما مفید بوده است، آموزش‌ها و مطالب زیر نیز به شما پیشنهاد می‌شوند:

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

بر اساس رای 2 نفر

آیا این مطلب برای شما مفید بود؟

نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *