Git — یک سیستم کنترل نسخه توزیعشده با متن باز است که توسط لینوس توروالدز در سال ۲۰۰۵ برای توسعه هسته لینوکس ایجاد شد. برخلاف سیستمهای متمرکز مانند SVN، Git یک کپی کامل از مخزن را بر روی هر دستگاه توسعهدهنده ذخیره میکند که امکان کار بدون اتصال دائمی به سرور را فراهم میکند. طبق دادههای Git SCM، ۲۰۲۴، Git در بیش از ۹۰٪ از تمام پروژههای تجاری توسعه نرمافزار استفاده میشود.
نکات اصلی
Git — یک سیستم کنترل نسخه توزیعشده (VCS) است که تغییرات فایلها را ردیابی میکند و به چندین توسعهدهنده اجازه میدهد همزمان روی یک پروژه کار کنند. برخلاف سیستمهای متمرکز، در Git هر توسعهدهنده یک کپی کامل از مخزن شامل تمام تاریخچه تغییرات دارد که سیستم را در برابر از دست دادن داده مقاوم میکند و نیاز به اتصال دائمی به سرور مرکزی ندارد.
تاریخچه Git در سال ۲۰۰۵ آغاز شد، زمانی که لینوس توروالدز یک VCS جدید پس از آنکه شرکت BitKeeper مجوز رایگان سیستم خود را برای توسعهدهندگان هسته لینوکس لغو کرد، ایجاد نمود. اهداف عبارت بودند از: سرعت، سادگی معماری، پشتیبانی از توسعه غیرخطی از طریق شاخهبندی و توزیع کامل. در ۳ ماه توروالدز هسته Git را نوشت و پس از یک سال پروژه تحت مدیریت جونیو هامانو به خودگردانی منتقل شد.
طبق نظرخواهی Stack Overflow (۲۰۲۴)، ۹۳.۹٪ از توسعهدهندگان حرفهای از Git استفاده میکنند که آن را به سیستم کنترل نسخه غالب در صنعت تبدیل میکند. نزدیکترین رقیب — Subversion (SVN) — تنها در ۵.۲٪ از پروژهها، عمدتاً در محیطهای شرکتی بزرگ با فرآیندهای متمرکز استفاده میشود.
مخزن Git — دایرکتوریای است که Git در آن تغییرات همه فایلها را ردیابی میکند. درون این دایرکتوری یک پوشه مخفی .git قرار دارد که همه اشیاء سیستم در آن ذخیره میشوند: کامیتها، درختها، بلابها و ارجاعها. هنگامی که توسعهدهنده یک کامیت ایجاد میکند، Git فایلها را به طور کامل کپی نمیکند — بلکه یک عکس فوری (snapshot) از وضعیت ایجاد کرده و یک ارجاع به آن ذخیره میکند.
هر کامیت شامل: هش SHA-1 منحصربهفرد (۴۰ کاراکتر)، ارجاع به کامیت قبلی (parent)، نویسنده، تاریخ، پیام کامیت و ارجاع به درخت (tree) که وضعیت فایلها را در زمان کامیت توصیف میکند. زنجیره کامیتها یک گراف جهتدار بدون چرخه تشکیل میدهد که در آن هر کامیت به یک یا چند والد اشاره میکند.
# مقداردهی اولیه مخزن
git init my-project
cd my-project
# ایجاد کامیت
echo "Hello, Git" > README.md
git add README.md
git commit -m "Initial commit"
# مشاهده تاریخچه
git log --oneline --graph --all
Git از سه ناحیه اصلی استفاده میکند: working directory (فایلهای روی دیسک)، staging area (شاخص، جایی که فایلهای آماده شده قرار میگیرند) و repository (تاریخچه کامیتها). دستور git add تغییرات را از دایرکتوری کاری به staging منتقل میکند و git commit محتوای staging را در مخزن ثبت میکند. این جداسازی به توسعهدهنده اجازه میدهد یک کامیت معنادار از مجموعهای از تغییرات جمعآوری کند، بدون اینکه هر اصلاحیه را جداگانه ثبت کند.
دستورات پایه Git ۹۰٪ از عملیات روزانه توسعهدهنده را پوشش میدهند. دستور git clone یک کپی محلی از مخزن راه دور ایجاد میکند، git pull تغییرات را از سرور دریافت کرده و با شاخه فعلی ادغام میکند و git push کامیتهای محلی را به سرور ارسال میکند. این سه دستور چرخه اصلی کار با Git را تشکیل میدهند.
برای مشاهده وضعیت از git status استفاده میشود — نشان میدهد کدام فایلها تغییر کردهاند، کدام به staging اضافه شدهاند و کدام ردیابی نمیشوند. git diff تغییرات مشخص در فایلها را قبل از اضافه شدن به staging نمایش میدهد. در زیر جدولی با پرکاربردترین دستورات آورده شده است:
| دستور | عمل | مثال |
|---|---|---|
| git clone | مخزن راه دور را کپی میکند | git clone https://example.com/repo |
| git add | فایلها را به staging اضافه میکند | git add src/main.kt |
| git commit | تغییرات را در تاریخچه ثبت میکند | git commit -m "Fix login bug" |
| git push | کامیتها را به سرور ارسال میکند | git push origin main |
| git pull | تغییرات را از سرور دریافت میکند | git pull origin feature |
برای لغو تغییرات Git چند گزینه ارائه میدهد. git reset اشارهگر شاخه را به کامیت مشخص شده منتقل میکند و میتواند staging یا دایرکتوری کاری را بازنشانی کند. git revert یک کامیت جدید ایجاد میکند که تغییرات کامیت مشخص شده را لغو میکند — این یک روش ایمن برای لغو در شاخههای اشتراکی است، زیرا تاریخچه بازنویسی نمیشود.
شاخهها در Git — اشارهگرهای سبک و قابل جابجایی به یک کامیت مشخص هستند. ایجاد یک شاخه جدید فایلها را کپی نمیکند، بلکه فقط یک اشارهگر جدید ایجاد میکند که شاخهبندی را عملاً آنی میکند. شاخه main (قبلاً master) — شاخه اصلی پروژه است که کد پایدار و آماده انتشار را شامل میشود.
روش استاندارد استفاده از Git Flow یا GitHub Flow است. در Git Flow از شاخهها استفاده میشود: main (کد انتشار)، develop (شاخه یکپارچهسازی)، feature/* (ویژگیهای جدید)، release/* (آمادهسازی انتشارها) و hotfix/* (اصلاحات فوری). GitHub Flow سادهتر است: فقط main و شاخههای feature، و همه تغییرات از طریق Pull Request تحویل داده میشوند.
# ایجاد و جابجایی شاخه
git branch feature-auth
git checkout feature-auth
# یا با یک دستور:
git checkout -b feature-auth
# فهرست شاخهها
git branch --list
git branch -a # همه شاخهها، از جمله حذفشدهها
# حذف شاخه
git branch -d feature-auth
ویژگی مهم شاخهبندی Git — امکان cherry-pick: انتقال یک کامیت جداگانه از یک شاخه به شاخه دیگر با دستور git cherry-pick <hash>. این کار زمانی مفید است که نیاز به انتقال یک رفع اشکال از شاخه feature به release بدون ادغام کل شاخه دارید. Git همچنین از بازبنیاد (rebase) و بازبنیاد تعاملی (git rebase -i) برای چسباندن، مرتبسازی مجدد و ویرایش کامیتها پشتیبانی میکند.
Merge (ادغام) یک کامیت ادغام ویژه ایجاد میکند که دو والد دارد. این کامیت واقعیت ترکیب دو شاخه را ثبت میکند و تاریخچه کامل را حفظ میکند — مشخص است که ادغام کجا و چه زمانی رخ داده است. Merge تاریخچه را به همان شکلی که ایجاد شده حفظ میکند که حسابرسی را ساده میکند اما گراف کامیتها را پیچیدهتر میکند.
Rebase (بازبنیاد) به جای ایجاد کامیت ادغام، کامیتهای شاخه فعلی را به بالای شاخه هدف منتقل میکند. تاریخچه خطی میشود — این تصور ایجاد میشود که توسعه به صورت ترتیبی انجام شده است. با این حال، rebase تاریخچه را بازنویسی میکند و هشهای SHA-1 کامیتها را تغییر میدهد که آن را برای شاخههای اشتراکی که سایر توسعهدهندگان به آن دسترسی دارند خطرناک میکند.
توصیه برای انتخاب: از merge برای شاخههای عمومی که تاریخچه توسط سایر توسعهدهندگان دیده میشود (feature → develop) و از rebase برای کار محلی استفاده کنید، زمانی که نیاز به اعمال تغییرات تازه از main به شاخه feature خود قبل از ایجاد Pull Request دارید. قانون ساده است: اگر کامیت قبلاً به سرور ارسال شده است — آن را بازبنیاد نکنید.
تعارض ادغام زمانی رخ میدهد که Git نمیتواند تغییرات را در یک فایل به طور خودکار ترکیب کند. Git بخشهای دارای تعارض را در فایل با نشانگرهای ویژه مشخص میکند: <<<<<<< (تغییرات ما)، ======= (جداکننده)، >>>>>>> (تغییرات آنها). توسعهدهنده به صورت دستی فایل را ویرایش میکند، گزینه مورد نظر را انتخاب یا هر دو را ترکیب میکند و ادغام را با یک کامیت به پایان میرساند.
مخزن راه دور (remote) — یک کپی از مخزن Git است که بر روی سرور قرار دارد. GitHub، GitLab و Bitbucket محبوبترین پلتفرمهای میزبانی مخازن راه دور هستند. آنها رابط وب برای مشاهده کد، مدیریت دسترسی، بازبینی کد و یکپارچهسازی با سیستمهای CI/CD ارائه میدهند.
در Git میتوان چندین مخزن راه دور برای یک پروژه تنظیم کرد. به طور پیشفرض remote اصلی origin نام دارد. دستور git remote add یک remote جدید اضافه میکند، git fetch تغییرات را بدون ادغام دریافت میکند و git pull مخفف git fetch + git merge است. برای کار با کد از طریق Pull Request، توسعهدهنده یک fork از مخزن ایجاد میکند، آن را کلون میکند، در شاخه feature کار میکند و یک درخواست ادغام به مخزن اصلی ارسال میکند.
# اضافه کردن مخزن راه دور
git remote add origin https://github.com/user/repo.git
# مشاهده مخازن راه دور
git remote -v
# ارسال شاخه به سرور
git push -u origin feature-auth
# دریافت تغییرات از شاخه راه دور
git pull origin main
مخازن راه دور از برچسبگذاری برای علامتگذاری نسخههای انتشار پشتیبانی میکنند. برچسبها میتوانند سبک (فقط یک اشارهگر به کامیت) و حاشیهنویسی شده (شامل ابرداده: نویسنده، تاریخ، پیام) باشند. برچسبهای حاشیهنویسی شده برای نسخههای انتشار توصیه میشوند، زیرا اطلاعات کامل درباره نسخه را منتقل میکنند و میتوانند با کلید GPG برای تأیید نویسندگی امضا شوند.
Git Worktree امکان کار همزمان با چندین شاخه در دایرکتوریهای مختلف بدون جابجایی بین آنها را فراهم میکند. دستور git worktree add ../feature-auth feature-auth یک دایرکتوری کاری جدید feature-auth ایجاد میکند که میتوان بدون تغییر شاخه در دایرکتوری اصلی در آن کد نوشت. Worktree برای اصلاحات سریع در شاخه release مفید است زمانی که دایرکتوری اصلی مشغول توسعه طولانیمدت است.
Git Submodules — مکانیزمی برای گنجاندن یک مخزن Git در مخزن دیگر است. Submodule یک ارجاع به یک کامیت ثابت از مخزن خارجی ذخیره میکند که تکرارپذیری ساخت را تضمین میکند. دستور git submodule add https://github.com/example/lib.git یک کتابخانه خارجی را به عنوان زیرماژول اضافه میکند. هنگام کلون کردن پروژه با زیرماژولها برای بارگذاری همه وابستگیها باید git submodule update --init --recursive اجرا شود.
سوالات متداول
Git — یک VCS توزیعشده با تاریخچه محلی و امکان کار آفلاین. SVN — یک سیستم متمرکز که برای همه عملیات به جز مشاهده فایلها نیاز به اتصال دائمی به سرور دارد.
از git revert HEAD برای لغو ایمن استفاده کنید (یک کامیت جدید ایجاد میشود). اگر کامیت هنوز به سرور ارسال نشده است، میتوانید از git reset --soft HEAD~1 استفاده کنید.
.gitignore — فایلی که در آن الگوهای فایلها و دایرکتوریهایی که Git باید نادیده بگیرد فهرست شده است. برای حذف فایلهای موقت، ساختها و تنظیمات IDE از مخزن استفاده میشود.
git fetch تغییرات را از سرور بارگیری میکند اما آنها را با شاخه فعلی ادغام نمیکند. git pull fetch را انجام داده و بلافاصله merge را اجرا میکند. برای کنترل از fetch + مشاهده diff و سپس merge دستی استفاده کنید.
از git commit --amend استفاده کنید — این دستور ویرایشگر را برای تغییر پیام کامیت باز میکند. اگر کامیت قبلاً روی سرور است، git push --force نیاز خواهد بود که برای شاخههای اشتراکی خطرناک است.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید