Git: تفاوت میان نسخه‌ها

از shakiba
پرش به ناوبری پرش به جستجو
بدون خلاصۀ ویرایش
بدون خلاصۀ ویرایش
خط ۱: خط ۱:
== Git چیست؟ ==
'''Git''' یک سیستم کنترل نسخه (Version Control System) توزیع‌شده است که برای ردیابی تغییرات در فایل‌ها و هماهنگی کار بین چند نفر روی یک پروژه استفاده می‌شود. با Git می‌توان تاریخچهٔ کامل تغییرات یک پروژه را نگه داشت، به نسخه‌های قبلی بازگشت، و به‌صورت هم‌زمان با دیگران روی بخش‌های مختلف یک پروژه کار کرد.
== مفاهیم پایه ==
== مفاهیم پایه ==


* '''Repository (مخزن)''': پوشه‌ای که Git تاریخچهٔ تغییرات آن را ردیابی می‌کند.
* '''Working Directory''': فایل‌های واقعی روی سیستم که در حال ویرایش آن‌ها هستید.
* '''Staging Area (Index)''': فضای واسط بین Working Directory و مخزن؛ فایل‌هایی که آماده‌ی ثبت (commit) هستند.
* '''Commit''': یک نقطهٔ ذخیرهٔ دائمی در تاریخچهٔ پروژه، مثل عکس لحظه‌ای از وضعیت فایل‌ها.
* '''Commit''': یک نقطهٔ ذخیرهٔ دائمی در تاریخچهٔ پروژه، مثل عکس لحظه‌ای از وضعیت فایل‌ها.
* '''Branch (شاخه)''': یک مسیر جداگانه برای توسعه، بدون تأثیر روی نسخهٔ اصلی.
* '''Branch (شاخه)''': یک مسیر جداگانه برای توسعه، بدون تأثیر روی نسخهٔ اصلی.
* '''HEAD''': اشاره‌گری به آخرین commit در شاخه‌ای که در حال حاضر روی آن هستید.
* '''Merge''': ترکیب کردن تغییرات دو شاخه با هم.
* '''Merge''': ترکیب کردن تغییرات دو شاخه با هم.
* '''Remote''': نسخه‌ای از مخزن که روی یک سرور (مثل GitHub) قرار دارد.
* '''Remote''': نسخه‌ای از مخزن که روی یک سرور (مثل GitHub، GitLab) قرار دارد.
* '''Clone''': کپی کامل یک مخزن از راه دور روی سیستم شما.


== دستورات پرکاربرد ==
== نصب و تنظیمات اولیه ==
{| class="wikitable" style="direction:rtl; width:100%;"
|-
! توضیح !! دستور
|-
| بررسی نصب بودن Git و نسخهٔ آن || <code style="direction:ltr; display:inline-block;">git --version</code>
|-
| تنظیم نام کاربری (سراسری) || <code style="direction:ltr; display:inline-block;">git config --global user.name "نام شما"</code>
|-
| تنظیم ایمیل (سراسری) || <code style="direction:ltr; display:inline-block;">git config --global user.email "email@example.com"</code>
|-
| مشاهدهٔ تمام تنظیمات فعلی || <code style="direction:ltr; display:inline-block;">git config --list</code>
|}


=== شروع کار ===
== شروع کار ==
{| class="wikitable" style="direction:rtl; width:100%;"
{| class="wikitable" style="direction:rtl; width:100%;"
|-
|-
خط ۱۶: خط ۳۷:
|-
|-
| کپی کردن یک مخزن از راه دور || <code style="direction:ltr; display:inline-block;">git clone [آدرس]</code>
| کپی کردن یک مخزن از راه دور || <code style="direction:ltr; display:inline-block;">git clone [آدرس]</code>
|-
| کپی کردن مخزن در یک پوشهٔ مشخص || <code style="direction:ltr; display:inline-block;">git clone [آدرس] [نام پوشه]</code>
|}
|}


=== ثبت تغییرات ===
== ثبت تغییرات ==
{| class="wikitable" style="direction:rtl; width:100%;"
{| class="wikitable" style="direction:rtl; width:100%;"
|-
|-
خط ۳۰: خط ۵۳:
|-
|-
| ثبت یک commit با توضیح || <code style="direction:ltr; display:inline-block;">git commit -m "پیام"</code>
| ثبت یک commit با توضیح || <code style="direction:ltr; display:inline-block;">git commit -m "پیام"</code>
|-
| اضافه کردن و ثبت هم‌زمان (فایل‌های ردیابی‌شده) || <code style="direction:ltr; display:inline-block;">git commit -am "پیام"</code>
|-
| اصلاح آخرین commit || <code style="direction:ltr; display:inline-block;">git commit --amend</code>
|}
== مشاهدهٔ تاریخچه و تغییرات ==
{| class="wikitable" style="direction:rtl; width:100%;"
|-
! توضیح !! دستور
|-
| نمایش تاریخچهٔ commit‌ها || <code style="direction:ltr; display:inline-block;">git log</code>
|-
| نمایش خلاصه و یک‌خطی تاریخچه || <code style="direction:ltr; display:inline-block;">git log --oneline</code>
|-
| نمایش تفاوت فایل‌های تغییر یافته (قبل از add) || <code style="direction:ltr; display:inline-block;">git diff</code>
|-
| نمایش تفاوت فایل‌های staged || <code style="direction:ltr; display:inline-block;">git diff --staged</code>
|-
| نمایش جزئیات یک commit خاص || <code style="direction:ltr; display:inline-block;">git show [commit-id]</code>
|}
|}


=== کار با شاخه‌ها ===
== کار با شاخه‌ها (Branch) ==
{| class="wikitable" style="direction:rtl; width:100%;"
{| class="wikitable" style="direction:rtl; width:100%;"
|-
|-
خط ۴۲: خط ۸۵:
|-
|-
| رفتن به یک شاخه || <code style="direction:ltr; display:inline-block;">git checkout [نام]</code>
| رفتن به یک شاخه || <code style="direction:ltr; display:inline-block;">git checkout [نام]</code>
|-
| رفتن به یک شاخه (روش جدیدتر) || <code style="direction:ltr; display:inline-block;">git switch [نام]</code>
|-
|-
| ساخت و رفتن به شاخهٔ جدید هم‌زمان || <code style="direction:ltr; display:inline-block;">git checkout -b [نام]</code>
| ساخت و رفتن به شاخهٔ جدید هم‌زمان || <code style="direction:ltr; display:inline-block;">git checkout -b [نام]</code>
|-
|-
| ادغام یک شاخه با شاخهٔ فعلی || <code style="direction:ltr; display:inline-block;">git merge [نام شاخه]</code>
| ادغام یک شاخه با شاخهٔ فعلی || <code style="direction:ltr; display:inline-block;">git merge [نام شاخه]</code>
|-
| حذف یک شاخه || <code style="direction:ltr; display:inline-block;">git branch -d [نام]</code>
|-
| حذف اجباری یک شاخهٔ ادغام‌نشده || <code style="direction:ltr; display:inline-block;">git branch -D [نام]</code>
|}
|}


=== کار با ریموت (GitHub و مشابه) ===
== کار با ریموت (GitHub و مشابه) ==
{| class="wikitable" style="direction:rtl; width:100%;"
{| class="wikitable" style="direction:rtl; width:100%;"
|-
|-
خط ۵۴: خط ۱۰۳:
|-
|-
| اتصال به مخزن راه دور || <code style="direction:ltr; display:inline-block;">git remote add origin [آدرس]</code>
| اتصال به مخزن راه دور || <code style="direction:ltr; display:inline-block;">git remote add origin [آدرس]</code>
|-
| نمایش لیست ریموت‌ها || <code style="direction:ltr; display:inline-block;">git remote -v</code>
|-
|-
| ارسال تغییرات به سرور || <code style="direction:ltr; display:inline-block;">git push origin [شاخه]</code>
| ارسال تغییرات به سرور || <code style="direction:ltr; display:inline-block;">git push origin [شاخه]</code>
|-
|-
| دریافت تغییرات از سرور || <code style="direction:ltr; display:inline-block;">git pull origin [شاخه]</code>
| ارسال شاخهٔ جدید و تنظیم ردیابی آن || <code style="direction:ltr; display:inline-block;">git push -u origin [شاخه]</code>
|-
| دریافت و ادغام تغییرات از سرور || <code style="direction:ltr; display:inline-block;">git pull origin [شاخه]</code>
|-
| فقط دریافت تغییرات بدون ادغام || <code style="direction:ltr; display:inline-block;">git fetch origin</code>
|}
|}
== بازگشت و لغو تغییرات ==
{| class="wikitable" style="direction:rtl; width:100%;"
|-
! توضیح !! دستور
|-
| لغو تغییرات یک فایل در Working Directory || <code style="direction:ltr; display:inline-block;">git checkout -- [فایل]</code>
|-
| لغو تغییرات با دستور جدیدتر || <code style="direction:ltr; display:inline-block;">git restore [فایل]</code>
|-
| خارج کردن فایل از staging area || <code style="direction:ltr; display:inline-block;">git reset [فایل]</code>
|-
| بازگشت کامل به یک commit قبلی (خطرناک) || <code style="direction:ltr; display:inline-block;">git reset --hard [commit-id]</code>
|-
| ساخت یک commit جدید که یک commit قبلی را خنثی می‌کند || <code style="direction:ltr; display:inline-block;">git revert [commit-id]</code>
|}
== Stash (ذخیرهٔ موقت تغییرات) ==
{| class="wikitable" style="direction:rtl; width:100%;"
|-
! توضیح !! دستور
|-
| ذخیرهٔ موقت تغییرات فعلی || <code style="direction:ltr; display:inline-block;">git stash</code>
|-
| نمایش لیست stash‌ها || <code style="direction:ltr; display:inline-block;">git stash list</code>
|-
| بازگردانی آخرین stash || <code style="direction:ltr; display:inline-block;">git stash pop</code>
|-
| حذف آخرین stash بدون بازگردانی || <code style="direction:ltr; display:inline-block;">git stash drop</code>
|}
== برچسب‌گذاری (Tag) ==
{| class="wikitable" style="direction:rtl; width:100%;"
|-
! توضیح !! دستور
|-
| ساخت یک تگ ساده || <code style="direction:ltr; display:inline-block;">git tag [نام]</code>
|-
| ساخت تگ با توضیح || <code style="direction:ltr; display:inline-block;">git tag -a [نام] -m "پیام"</code>
|-
| نمایش لیست تگ‌ها || <code style="direction:ltr; display:inline-block;">git tag</code>
|-
| ارسال تگ‌ها به سرور || <code style="direction:ltr; display:inline-block;">git push origin --tags</code>
|}
== Rebase و Cherry-pick ==
{| class="wikitable" style="direction:rtl; width:100%;"
|-
! توضیح !! دستور
|-
| اعمال دوبارهٔ commit‌های شاخهٔ فعلی روی شاخهٔ دیگر || <code style="direction:ltr; display:inline-block;">git rebase [نام شاخه]</code>
|-
| rebase تعاملی برای ویرایش/ترکیب چند commit || <code style="direction:ltr; display:inline-block;">git rebase -i HEAD~[تعداد]</code>
|-
| انتخاب و اعمال یک commit خاص از شاخهٔ دیگر || <code style="direction:ltr; display:inline-block;">git cherry-pick [commit-id]</code>
|}
== حل تعارض (Merge Conflict) ==
وقتی دو شاخه تغییرات متفاوتی روی یک بخش از یک فایل داشته باشند، هنگام merge یا rebase تعارض (conflict) رخ می‌دهد. Git خطوط متعارض را با نشانه‌های زیر در فایل مشخص می‌کند:
<pre style="direction:ltr; text-align:left;">
<<<<<<< HEAD
محتوای شاخهٔ فعلی
=======
محتوای شاخهٔ دیگر
>>>>>>> نام-شاخه
</pre>
برای حل تعارض باید فایل را به‌صورت دستی ویرایش کرد، نشانه‌ها را حذف کرد و نسخهٔ نهایی را انتخاب نمود، سپس:
{| class="wikitable" style="direction:rtl; width:100%;"
|-
! توضیح !! دستور
|-
| اضافه کردن فایل حل‌شده به staging || <code style="direction:ltr; display:inline-block;">git add [فایل]</code>
|-
| ادامهٔ فرآیند merge || <code style="direction:ltr; display:inline-block;">git commit</code>
|-
| ادامهٔ فرآیند rebase بعد از حل تعارض || <code style="direction:ltr; display:inline-block;">git rebase --continue</code>
|-
| لغو کامل عملیات merge || <code style="direction:ltr; display:inline-block;">git merge --abort</code>
|}
== فایل .gitignore ==
فایل <code style="direction:ltr; display:inline-block;">.gitignore</code> برای مشخص کردن فایل‌ها و پوشه‌هایی است که نباید توسط Git ردیابی شوند (مثل فایل‌های موقت، پوشهٔ <code style="direction:ltr;">node_modules</code>، یا فایل‌های تنظیمات حساس).
<pre style="direction:ltr; text-align:left;">
# نمونه محتوای .gitignore
node_modules/
.env
*.log
.DS_Store
</pre>
== نکات و بهترین شیوه‌ها ==
* پیام commit‌ها را کوتاه، واضح و توصیفی بنویسید.
* هر commit باید یک تغییر منطقی و مستقل را نشان دهد، نه چند تغییر نامرتبط با هم.
* قبل از push کردن، همیشه با <code style="direction:ltr;">git pull</code> آخرین تغییرات را دریافت کنید.
* از شاخه‌های جداگانه (feature branch) برای هر ویژگی یا رفع باگ استفاده کنید و شاخهٔ اصلی (main/master) را همیشه پایدار نگه دارید.
* پیش از rebase یا reset --hard، مطمئن شوید که تغییرات مهم را از دست نمی‌دهید.

نسخهٔ ۶ سپتامبر ۲۰۲۶، ساعت ۰۶:۴۳

Git چیست؟

Git یک سیستم کنترل نسخه (Version Control System) توزیع‌شده است که برای ردیابی تغییرات در فایل‌ها و هماهنگی کار بین چند نفر روی یک پروژه استفاده می‌شود. با Git می‌توان تاریخچهٔ کامل تغییرات یک پروژه را نگه داشت، به نسخه‌های قبلی بازگشت، و به‌صورت هم‌زمان با دیگران روی بخش‌های مختلف یک پروژه کار کرد.

مفاهیم پایه

  • Repository (مخزن): پوشه‌ای که Git تاریخچهٔ تغییرات آن را ردیابی می‌کند.
  • Working Directory: فایل‌های واقعی روی سیستم که در حال ویرایش آن‌ها هستید.
  • Staging Area (Index): فضای واسط بین Working Directory و مخزن؛ فایل‌هایی که آماده‌ی ثبت (commit) هستند.
  • Commit: یک نقطهٔ ذخیرهٔ دائمی در تاریخچهٔ پروژه، مثل عکس لحظه‌ای از وضعیت فایل‌ها.
  • Branch (شاخه): یک مسیر جداگانه برای توسعه، بدون تأثیر روی نسخهٔ اصلی.
  • HEAD: اشاره‌گری به آخرین commit در شاخه‌ای که در حال حاضر روی آن هستید.
  • Merge: ترکیب کردن تغییرات دو شاخه با هم.
  • Remote: نسخه‌ای از مخزن که روی یک سرور (مثل GitHub، GitLab) قرار دارد.
  • Clone: کپی کامل یک مخزن از راه دور روی سیستم شما.

نصب و تنظیمات اولیه

توضیح دستور
بررسی نصب بودن Git و نسخهٔ آن git --version
تنظیم نام کاربری (سراسری) git config --global user.name "نام شما"
تنظیم ایمیل (سراسری) git config --global user.email "email@example.com"
مشاهدهٔ تمام تنظیمات فعلی git config --list

شروع کار

توضیح دستور
ساخت یک مخزن جدید در پوشهٔ فعلی git init
کپی کردن یک مخزن از راه دور git clone [آدرس]
کپی کردن مخزن در یک پوشهٔ مشخص git clone [آدرس] [نام پوشه]

ثبت تغییرات

توضیح دستور
نمایش وضعیت فایل‌ها git status
اضافه کردن فایل به staging area git add [نام فایل]
اضافه کردن همهٔ فایل‌های تغییر یافته git add .
ثبت یک commit با توضیح git commit -m "پیام"
اضافه کردن و ثبت هم‌زمان (فایل‌های ردیابی‌شده) git commit -am "پیام"
اصلاح آخرین commit git commit --amend

مشاهدهٔ تاریخچه و تغییرات

توضیح دستور
نمایش تاریخچهٔ commit‌ها git log
نمایش خلاصه و یک‌خطی تاریخچه git log --oneline
نمایش تفاوت فایل‌های تغییر یافته (قبل از add) git diff
نمایش تفاوت فایل‌های staged git diff --staged
نمایش جزئیات یک commit خاص git show [commit-id]

کار با شاخه‌ها (Branch)

توضیح دستور
نمایش لیست شاخه‌ها git branch
ساخت شاخهٔ جدید git branch [نام]
رفتن به یک شاخه git checkout [نام]
رفتن به یک شاخه (روش جدیدتر) git switch [نام]
ساخت و رفتن به شاخهٔ جدید هم‌زمان git checkout -b [نام]
ادغام یک شاخه با شاخهٔ فعلی git merge [نام شاخه]
حذف یک شاخه git branch -d [نام]
حذف اجباری یک شاخهٔ ادغام‌نشده git branch -D [نام]

کار با ریموت (GitHub و مشابه)

توضیح دستور
اتصال به مخزن راه دور git remote add origin [آدرس]
نمایش لیست ریموت‌ها git remote -v
ارسال تغییرات به سرور git push origin [شاخه]
ارسال شاخهٔ جدید و تنظیم ردیابی آن git push -u origin [شاخه]
دریافت و ادغام تغییرات از سرور git pull origin [شاخه]
فقط دریافت تغییرات بدون ادغام git fetch origin

بازگشت و لغو تغییرات

توضیح دستور
لغو تغییرات یک فایل در Working Directory git checkout -- [فایل]
لغو تغییرات با دستور جدیدتر git restore [فایل]
خارج کردن فایل از staging area git reset [فایل]
بازگشت کامل به یک commit قبلی (خطرناک) git reset --hard [commit-id]
ساخت یک commit جدید که یک commit قبلی را خنثی می‌کند git revert [commit-id]

Stash (ذخیرهٔ موقت تغییرات)

توضیح دستور
ذخیرهٔ موقت تغییرات فعلی git stash
نمایش لیست stash‌ها git stash list
بازگردانی آخرین stash git stash pop
حذف آخرین stash بدون بازگردانی git stash drop

برچسب‌گذاری (Tag)

توضیح دستور
ساخت یک تگ ساده git tag [نام]
ساخت تگ با توضیح git tag -a [نام] -m "پیام"
نمایش لیست تگ‌ها git tag
ارسال تگ‌ها به سرور git push origin --tags

Rebase و Cherry-pick

توضیح دستور
اعمال دوبارهٔ commit‌های شاخهٔ فعلی روی شاخهٔ دیگر git rebase [نام شاخه]
rebase تعاملی برای ویرایش/ترکیب چند commit git rebase -i HEAD~[تعداد]
انتخاب و اعمال یک commit خاص از شاخهٔ دیگر git cherry-pick [commit-id]

حل تعارض (Merge Conflict)

وقتی دو شاخه تغییرات متفاوتی روی یک بخش از یک فایل داشته باشند، هنگام merge یا rebase تعارض (conflict) رخ می‌دهد. Git خطوط متعارض را با نشانه‌های زیر در فایل مشخص می‌کند:

<<<<<<< HEAD
محتوای شاخهٔ فعلی
=======
محتوای شاخهٔ دیگر
>>>>>>> نام-شاخه

برای حل تعارض باید فایل را به‌صورت دستی ویرایش کرد، نشانه‌ها را حذف کرد و نسخهٔ نهایی را انتخاب نمود، سپس:

توضیح دستور
اضافه کردن فایل حل‌شده به staging git add [فایل]
ادامهٔ فرآیند merge git commit
ادامهٔ فرآیند rebase بعد از حل تعارض git rebase --continue
لغو کامل عملیات merge git merge --abort

فایل .gitignore

فایل .gitignore برای مشخص کردن فایل‌ها و پوشه‌هایی است که نباید توسط Git ردیابی شوند (مثل فایل‌های موقت، پوشهٔ node_modules، یا فایل‌های تنظیمات حساس).

# نمونه محتوای .gitignore
node_modules/
.env
*.log
.DS_Store

نکات و بهترین شیوه‌ها

  • پیام commit‌ها را کوتاه، واضح و توصیفی بنویسید.
  • هر commit باید یک تغییر منطقی و مستقل را نشان دهد، نه چند تغییر نامرتبط با هم.
  • قبل از push کردن، همیشه با git pull آخرین تغییرات را دریافت کنید.
  • از شاخه‌های جداگانه (feature branch) برای هر ویژگی یا رفع باگ استفاده کنید و شاخهٔ اصلی (main/master) را همیشه پایدار نگه دارید.
  • پیش از rebase یا reset --hard، مطمئن شوید که تغییرات مهم را از دست نمی‌دهید.