# کنترل نسخه به زبان تصویر

> کنترل نسخه چیست، و مخزن، کامیت، دیف، شاخه، ادغام، تعارض، ارسال، دریافت و درخواست ادغام چه هستند؛ با تصویرهایی که قدم به قدم پخش می‌شوند. بدون نیاز به تجربهٔ قبلی.

Source: https://zaryn.xyz/docs/fa/version-control-in-pictures

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

> **نکته:** لازم نیست فرمان‌ها را از حالا حفظ کنید. اول تصویر را بفهمید. [شروع سریع](/docs/fa/quickstart) شما را در پنج دقیقه به نوشتنشان می‌رساند.

## چرا کنترل نسخه وجود دارد

```diagram
type: cards
title: بدون آن، و با آن
---
😩 | گزارش_نهایی_v2_واقعاً_نهایی.docx | نسخه‌ها همه‌جا پخش‌اند و کسی نمی‌داند کدام درست است | bad
🕳️ | «دیروز کار می‌کرد» | راهی برای دیدن اینکه از دیروز چه عوض شده یا برگشتن به آن نیست | bad
📨 | فرستادن فایل با ایمیل | دو نفر یک فایل را ویرایش می‌کنند و کار یکی از دست می‌رود | bad
🕰️ | همهٔ نسخه‌های ذخیره‌شده، برای همیشه | یک پوشهٔ پروژه؛ به هر لحظه‌ای که ذخیره کرده‌اید برگردید | good
🔍 | دقیقاً چه عوض شد | خط به خط، چه کسی و چرا | good
🤝 | کار گروهی بی‌خطر | هر کس روی خط کار خودش، و بعد کارها با هم یکی می‌شوند | good
```

**سامانهٔ کنترل نسخه** (VCS) ابزاری است که هر نسخه‌ای از پروژه را که بخواهید ذخیره کنید به یاد می‌سپارد، تا ببینید چه عوض شده، برگردید، و با دیگران کار کنید بی‌آنکه کار هم را پاک کنید. **zev** یک سامانهٔ کنترل نسخه است؛ **Zaryn** وب‌سایتی است که آنچه zev ذخیره می‌کند را در آن به اشتراک می‌گذارید.

نقطه‌های ذخیرهٔ یک بازی ویدیویی را در نظر بگیرید: پیش از بخش سخت ذخیره می‌کنید و اگر خراب شد، ذخیره را بار می‌کنید. کنترل نسخه به پروژهٔ شما نقطه‌های ذخیره می‌دهد، هر کدام با یادداشتی از کاری که کردید.

## مخزن: پروژهٔ شما، با حافظه

```diagram
type: graph
title: درون یک مخزن چیست
height: 56
alt: یک پوشهٔ پروژه فایل‌های شما و یک تاریخچهٔ پنهان را نگه می‌دارد؛ تاریخچه همهٔ کامیت‌ها را دارد
---
node folder | my-site/ | 12 24 | folder | accent | مخزن: یک پوشهٔ معمولی که در آن کار می‌کنید
node f1 | index.html | 42 6 | file | | فایلی که ویرایش می‌کنید، مثل هر فایل دیگر
node f2 | style.css | 42 20 | file | | فایلی دیگر
node f3 | photo.jpg | 42 34 | file | | فایل‌های بزرگ هم: عکس، داده، مدل
node hist | تاریخچه | 42 47 | log | good | پنهان درون پوشه: هر نسخهٔ ذخیره‌شده از هر فایل، با اینکه چه کسی و چرا ذخیره کرد
node c | ۱۲۸ کامیت | 74 47 | commit | | هر نقطهٔ ذخیره یک کامیت است
link folder f1
link folder f2
link folder f3
link folder hist | پنهان | ghost
link hist c | | path
```

**مخزن** (repository یا repo) پوشهٔ پروژه‌ای است که zev از آن مراقبت می‌کند. شبیه یک پوشهٔ معمولی پر از فایل‌های شماست، به‌اضافهٔ تاریخچه‌ای پنهان از همهٔ نسخه‌هایی که ذخیره کرده‌اید. با `zev init` در پوشه‌ای که دارید، با `zev new` از صفر، یا با `zev clone` برای دانلود از Zaryn یکی می‌سازید.

## سه جایی که کارتان در آن است

```diagram
type: flow
title: از یک ویرایش تا یک نقطهٔ ذخیره
loop: ویرایش، add، commit، باز و باز
---
پوشهٔ کاری | فایل‌هایی که می‌بینید و ویرایش می‌کنید. zev تغییرها را می‌بیند | | ✏️
~ zev add
ناحیهٔ مرحله‌بندی | تغییرهایی که برای نقطهٔ ذخیرهٔ بعدی برگزیده‌اید | accent | 📥
~ zev commit
تاریخچه | یک نقطهٔ ذخیره، برای همیشه، با پیام شما | good | 🕰️
```

چرا قدم میانی؟ فرض کنید یک باگ را درست کرده‌اید و صفحهٔ تازه‌ای هم شروع کرده‌اید. `zev add` به شما اجازه می‌دهد فقط رفع باگ را در این نقطهٔ ذخیره بگذارید و صفحهٔ نیمه‌کاره را برای بعدی نگه دارید، تا هر نقطهٔ ذخیره یک تغییر روشن باشد. `zev status` هر لحظه می‌گوید در هر جا چه هست.

## کامیت: یک نقطهٔ ذخیره

```diagram
type: cards
title: یک کامیت چه چیزهایی را نگه می‌دارد
---
📸 | یک عکس فوری | همهٔ فایل‌ها همان‌طور که هنگام کامیت بودند، نه فقط تغییرها | accent
💬 | یک پیام | یادداشت شما: «افزودن فرم تماس». برای خود آینده‌تان بنویسید |
👤 | چه کسی و کی | نام شما، حساب Zaryn شما، تاریخ و ساعت |
⬅️ | والدش | کامیت پیش از آن: کامیت‌ها این‌طور تاریخچه می‌سازند |
#️⃣ | یک اثر انگشت | هشی ساخته‌شده از همهٔ این‌ها، مثل `7f3a9c2`. یک حرف را عوض کنید و عوض می‌شود | good
```

**کامیت** یک نقطهٔ ذخیره است. کامیت‌ها پشت سر هم می‌آیند و هر کدام به قبلی اشاره می‌کند، و این رشته **تاریخچهٔ** پروژهٔ شماست. ساخته‌شدن چندتایشان را ببینید:

```diagram
type: history
title: یک تاریخچه، کامیت به کامیت
start: یک مخزن تازه
caption: هر نقطه یک کامیت است. برچسب بالای تازه‌ترین کامیت نام شاخه، main، است که همیشه به آخرین کامیت شما می‌رود.
---
branch main | accent
commit A main | صفحهٔ اول | info ساخته‌شده با `zev commit -m "First page"`
step کامیت | یک فایل استایل اضافه می‌کنید و کامیت می‌کنید. B به A اشاره می‌کند.
commit B main | افزودن رنگ‌ها | info والدش A است
step کامیت | یک غلط تایپی را درست می‌کنید و دوباره کامیت می‌کنید.
commit C main | رفع غلط تایپی | info والدش B است
step کامیت | یک فرم تماس. تاریخچه به راست رشد می‌کند؛ هیچ‌چیز قبلی عوض نمی‌شود.
commit D main | فرم تماس | info تازه‌ترین کامیت: main به اینجا اشاره می‌کند
step برچسب نسخه | به C نامی می‌دهید که هرگز جابه‌جا نمی‌شود، v1.0، تا نسخه‌ای را که منتشر کردید همیشه پیدا کنید.
tag C | v1.0
mark C | accent
```

`zev log` تاریخچه را فهرست می‌کند؛ `zev show` یک کامیت را کامل نشان می‌دهد. چون هر کامیت یک عکس فوری کامل با اثر انگشت است، همیشه می‌توانید هر کدام را دقیقاً همان‌طور که بود برگردانید، و هیچ‌کس نمی‌تواند یک کامیت قدیمی را بی‌صدا عوض کند.

## دیف: چه عوض شد

```diagram
type: diff
title: تغییرها میان دو کامیت
file: index.html
---
@@ -3 +3 @@
  <body>
-   <h1>Welcom to my site</h1>
+   <h1>Welcome to my site</h1>
> رفع غلط تایپی: یک خط حذف شد (قرمز) و نسخهٔ تازه‌اش اضافه شد (سبز)
    <p>Hello!</p>
+   <a href="contact.html">Contact me</a>
> یک خط کاملاً تازه: فقط سبز
  </body>
```

**دیف** تفاوت میان دو نسخه است: خط‌های قرمز حذف شده‌اند، خط‌های سبز اضافه شده‌اند، و خط‌های ساده بی‌تغییرند تا جایتان را پیدا کنید. خطی که عوض شده یک قرمز و یک سبز نشان داده می‌شود. **کنار هم** را در بالا بزنید تا نسخهٔ قدیم و تازه را کنار هم ببینید.

- `zev diff` آنچه را عوض کرده‌اید ولی مرحله‌بندی نکرده‌اید نشان می‌دهد.
- `zev diff --staged` آنچه در ناحیهٔ مرحله‌بندی است، یعنی کامیت بعدی، را نشان می‌دهد.
- `zev show` دیفی را که یک کامیت ساخت نشان می‌دهد.

zev کد را هم می‌فهمد: [دیف معنایی](/docs/fa/semantic-diff) می‌گوید کی یک تغییر فقط کد را جابه‌جا یا قالب‌بندی کرده، تا آنچه واقعاً عوض شده را بازبینی کنید.

## شاخه: چیزها را امتحان کنید بی‌آنکه چیزی بشکند

```diagram
type: history
title: شاخه یک خط کاری جداست
start: فقط main
---
branch main | accent
branch new-search | good | from C
commit A main | صفحهٔ اول
commit B main | افزودن رنگ‌ها
commit C main | رفع غلط تایپی | info کامیتی که شاخه از آن شروع می‌شود
step zev checkout -b new-search | یک نام تازه روی C. چیزی کپی نمی‌شود: شاخه فقط نامی است که به یک کامیت اشاره می‌کند.
step کامیت روی شاخه | یک جعبهٔ جست‌وجو می‌سازید. main کامیت D را ندارد؛ سایت زندهٔ شما دست‌نخورده است.
commit D new-search | جعبهٔ جست‌وجو | info فقط روی new-search
step ادامه | کامیت دیگری روی شاخه.
commit E new-search | نتایج جست‌وجو | info فقط روی new-search
step در همین حال روی main | کسی پاورقی را روی main درست می‌کند. حالا دو خط کاری کنار هم هست.
commit F main | رفع پاورقی | info فقط روی main
```

**شاخه** رشته‌ای از کامیت‌هاست که نام دارد. هر مخزن با `main` شروع می‌شود. وقتی می‌خواهید چیزی را امتحان کنید، شاخه بسازید: کامیت‌هایتان روی آن می‌روند و `main` دقیقاً همان‌طور که بود می‌ماند تا وقتی تصمیم بگیرید کار را بیاورید. با `zev checkout <branch>` میان شاخه‌ها جابه‌جا شوید؛ فایل‌هایتان مطابق آن عوض می‌شوند. ببینید: [شاخه‌ها و ادغام](/docs/fa/branches).

## ادغام: کار را برگردانید

وقتی شاخه آماده است، آن را در `main` **ادغام** می‌کنید. دو حالت هست.

**اگر `main` جلو نرفته باشد**، ادغام فقط نام `main` را تا تازه‌ترین کامیت شاخه جلو می‌برد (یک *fast-forward*):

```diagram
type: history
title: ادغام وقتی main عوض نشده
start: پیش از ادغام
---
branch main | accent
branch new-search | good | from C
commit A main | صفحهٔ اول
commit B main | افزودن رنگ‌ها
commit C main | رفع غلط تایپی
commit D new-search | جعبهٔ جست‌وجو
commit E new-search | نتایج جست‌وجو
step zev merge new-search | روی main. چیز تازه‌ای روی main رخ نداده، پس main فقط به E می‌رود. تمام.
point main | E
```

**اگر `main` هم جلو رفته باشد**، zev کامیت‌های تازهٔ خود `main` را روی کامیت‌های شاخه برمی‌گرداند، تا تاریخچه یک خط صاف با کار هر دو طرف بماند:

```diagram
type: history
title: ادغام وقتی هر دو طرف عوض شده‌اند
start: پیش از ادغام
---
branch main | accent
branch new-search | good | from C
commit A main | صفحهٔ اول
commit B main | افزودن رنگ‌ها
commit C main | رفع غلط تایپی
commit D new-search | جعبهٔ جست‌وجو
commit E new-search | نتایج جست‌وجو
commit F main | رفع پاورقی | info کامیت تازهٔ خود main
step zev merge new-search | zev کامیت F را روی E به صورت کامیتی تازه، F′، دوباره اجرا می‌کند: همان تغییر، در جای تازه‌ای از تاریخچه.
commit F′ main | رفع پاورقی | after E | copy F | info همان تغییر F، دوباره اجراشده پس از E
mark F | faded
step نتیجه | حالا `main` این است: `A → B → C → D → E → F′`؛ هم جست‌وجو و هم رفع پاورقی، در یک خط.
mark F′ | good
```

## تعارض: وقتی هر دو همان خط‌ها را عوض کرده‌اند

```diagram
type: diff
title: تعارض در فایل چه شکلی است
file: index.html
---
  <h1>
+ <<<<<<< main
+ Welcome to my site
+ =======
+ Welcome! Search below
+ >>>>>>> new-search
> این‌جا را zev علامت می‌زند: نسخهٔ main بالا، نسخهٔ شاخه پایین
  </h1>
```

اگر `main` و شاخهٔ شما **همان خط‌ها** را عوض کرده باشند، zev نمی‌تواند حدس بزند کدام را می‌خواهید، پس می‌ایستد و چیزی را عوض نمی‌کند. این یک **تعارض** است، و عادی است. آن را دستی درست می‌کنید:

```diagram
type: flow
title: درست کردن یک تعارض
or: یا
---
علامت | `zev merge new-search --resolve` هر جا که هر دو طرف عوض کرده‌اند را علامت می‌زند | warn | ⚠️
~ ویرایش
انتخاب | یک طرف، طرف دیگر یا ترکیبی را نگه دارید؛ خط‌های علامت را پاک کنید | | ✏️
~ zev add
مرحله‌بندی | به zev بگویید فایل درست شده | | ➕
~ zev merge --continue
تمام | ادغام کامل می‌شود | good | ✓
? پشیمان شدید؟ `zev merge --abort` همه‌چیز را برمی‌گرداند
```

ادغام مکرر تعارض‌ها را کوچک و کم نگه می‌دارد. راهنمای کامل در [شاخه‌ها و ادغام](/docs/fa/branches#وقتی-هر-دو-طرف-همان-خطها-را-تغییر-دادهاند) است.

## رایانهٔ شما و Zaryn: کلون، ارسال، دریافت

```diagram
type: sequence
title: یک پروژه، دو رایانه، یک جا در میان
lanes: شما | Zaryn | هم‌تیمی
alt: هم‌تیمی از Zaryn کلون می‌کند؛ شما کامیت‌ها را ارسال می‌کنید؛ او آن‌ها را دریافت و کامیت‌های خودش را ارسال می‌کند؛ شما آن‌ها را دریافت می‌کنید
---
== گرفتن یک نسخه ==
هم‌تیمی -> Zaryn : zev clone
Zaryn --> هم‌تیمی : کل تاریخچه
== به اشتراک گذاشتن کارتان ==
شما -> Zaryn : zev push: کامیت‌های تازه‌تان
note Zaryn : هر کامیت با اثر انگشتش سنجیده می‌شود | good
هم‌تیمی -> Zaryn : zev pull
Zaryn --> هم‌تیمی : فقط کامیت‌هایی که ندارد
== گرفتن کار او ==
هم‌تیمی -> Zaryn : zev push
شما -> Zaryn : zev pull
```

- **کلون**: یک مخزن را با کل تاریخچه‌اش روی رایانه‌تان دانلود کنید.
- **ارسال** (push): کامیت‌های تازه‌تان را به Zaryn بفرستید.
- **دریافت** (pull): کامیت‌هایی را که دیگران فرستاده‌اند بگیرید و فایل‌هایتان را به‌روز کنید.

رایانهٔ شما هم کل تاریخچه را دارد، پس بدون اینترنت می‌توانید کامیت کنید، تاریخچه را ببینید و شاخه بسازید. فقط برای ارسال و دریافت به اتصال نیاز دارید. بیشتر در [ارسال و دریافت](/docs/fa/pushing-and-pulling).

## درخواست ادغام: پیش از ادغام بپرسید

```diagram
type: flow
title: زندگی یک درخواست ادغام
or: یا
---
شاخه | کار را روی یک شاخه انجام دهید و ارسالش کنید | | 🌿
~ zev pr
درخواست ادغام | «لطفاً new-search را در main ادغام کنید»، همراه دیفش | accent | 📬
~ بازبینی و بررسی‌ها
بازبینی | هم‌تیمی‌ها نظر می‌دهند؛ CI آزمون‌ها را اجرا می‌کند | warn | 👀
? تغییر خواستند؟ کامیت‌های بیشتری ارسال کنید: درخواست خودش به‌روز می‌شود
~ تأیید
ادغام | کار روی main می‌نشیند | good | ✓
```

**درخواست ادغام** (pull request یا PR) درخواست ادغام یک شاخه در شاخه‌ای دیگر است، با فرصتی برای گفت‌وگو پیش از آن. دیف را نشان می‌دهد، [بررسی‌های CI](/docs/fa/memoized-ci) را اجرا می‌کند و به هم‌تیمی‌ها اجازه می‌دهد روی هر خط نظر بدهند. وقتی همه راضی‌اند، کسی **Merge** را می‌زند (یا `zev pr merge <number>` را اجرا می‌کند). در پروژهٔ شخصی هم به کار می‌آید: یک PR فهرست بررسی پیش از زنده شدن کار شماست.

## دو مورد دیگر که می‌بینید

```diagram
type: cards
---
🏷️ | برچسب (Tag) | نامی که برای همیشه روی یک کامیت می‌ماند، مثل `v1.0`، برای انتشارها. `zev tag v1.0` | accent
🧺 | Stash | تغییرهای نیمه‌کاره را کنار بگذارید تا شاخه عوض کنید، و بعد برشان گردانید. `zev stash`، `zev stash pop` |
↩️ | بازگردانی | تغییرهای کامیت‌نشدهٔ یک فایل را برگردانید. `zev restore <file>` |
🍴 | فورک | نسخهٔ خودتان از مخزن کس دیگری روی Zaryn، برای تغییر آزادانه و فرستادن با یک PR |
```

## تصویر کامل

```diagram
type: graph
title: همهٔ این صفحه، با هم
height: 58
alt: فایل‌ها را ویرایش می‌کنید، با add و commit به تاریخچهٔ محلی می‌برید، به Zaryn ارسال می‌کنید، درخواست ادغام باز می‌کنید و هم‌تیمی‌ها کارتان را دریافت می‌کنند
---
node edit | فایل‌های شما | 8 22 | file | | پوشهٔ کاری: آزادانه ویرایش کنید
node stage | مرحله‌بندی | 26 22 | folder | | `zev add` تغییرها را برای کامیت بعدی برمی‌گزیند
node hist | تاریخچهٔ شما | 44 22 | log | accent | `zev commit` یک عکس فوری ذخیره می‌کند؛ شاخه‌ها و ادغام‌ها همین‌جا، آفلاین
node zaryn | Zaryn | 66 22 | cloud | good | `zev push` کامیت‌ها را به اشتراک می‌گذارد؛ درخواست ادغام، بازبینی و CI اینجاست
node mate | هم‌تیمی | 90 22 | laptop | | `zev clone` و `zev pull` کار شما را به او می‌رسانند
node pr | درخواست ادغام | 66 46 | branch | warn | بازبینی دیف، اجرای بررسی‌ها، ادغام
link edit stage | zev add | path
link stage hist | zev commit | path
link hist zaryn | zev push | path
link zaryn mate | zev pull | path2
link zaryn pr | بازبینی
```

## هر واژه در یک خط

| واژه | در یک خط | فرمان |
|---|---|---|
| مخزن | پوشهٔ پروژه با کل تاریخچه‌اش | `zev init`، `zev clone` |
| کامیت | یک نقطهٔ ذخیره: عکس فوری، پیام، چه کسی و کی | `zev commit -m "…"` |
| ناحیهٔ مرحله‌بندی | تغییرهای برگزیده برای کامیت بعدی | `zev add` |
| تاریخچه | همهٔ کامیت‌ها، هر کدام اشاره‌گر به قبلی | `zev log` |
| دیف | آنچه میان دو نسخه عوض شد، قرمز و سبز | `zev diff` |
| شاخه | رشتهٔ نام‌دار کامیت‌ها برای کار جدا | `zev checkout -b <name>` |
| ادغام | آوردن کار یک شاخه به شاخهٔ دیگر | `zev merge <branch>` |
| تعارض | هر دو طرف همان خط‌ها را عوض کرده‌اند؛ شما انتخاب می‌کنید | `zev merge --resolve` |
| کلون / ارسال / دریافت | دانلود / فرستادن / گرفتن کامیت‌ها از Zaryn | `zev clone`، `zev push`، `zev pull` |
| درخواست ادغام | درخواست بازبینی پیش از ادغام | `zev pr` |
| برچسب | نامی ثابت برای یک کامیت، برای انتشار | `zev tag` |

آماده‌اید؟ [شروع سریع](/docs/fa/quickstart) را دنبال کنید، [فهرست واژه‌ها](/docs/fa/glossary) را دم دست نگه دارید، و هر جا گیر کردید [چطور…؟](/docs/fa/how-do-i) جواب‌های کوتاه دارد.
