آموزش گیت – قسمت هشتم

نویسنده : سید ایوب کوکبی ۲۴ اردیبهشت ۱۳۹۸
آموزش گیت - قسمت هشتم

به زبان ساده، در گیت مخزن ریموت (Remote Repository) به مخزنی گفته می‌شود که شما مالک آن نیستید. این مخزن می‌تواند یک مخزن دیگر در شبکۀ داخلی شرکت باشد یا در کامپیوتر دیگری آن سرِ دنیا. نکتۀ اصلی اینجاست است که مخزن ریموت کاملاً از my-git-repo جداست.

قبلا با چگونگی ساخت شاخه روی مخزن محلی (لوکال local) آشنا شدیم. شاخۀ ریموت (Remote Branch) نیز مانند یک شاخۀ محلی است، با این تفاوت که متعلق به مخزن شخص دیگر است.

دسترسی به شاخه‌ای در مخزن ریموت در گیت
دسترسی به شاخه‌ای در مخزن ریموت

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

کلون کردن مخزن (ماری)

در ابتدا ماری نیازمند این است که یک کپی از مخزن کد داشته باشد. معمولاً از دستور clone برای دانلود و کلون کردن مخازن تحت شبکه (مثلاً دریافت مخزن از گیت‎هاب و …) استفاده می‌کنند ولی روی شبکۀ داخلی یا سیستمم خودتان هم می‎توانید با کمک این دستور مخزن را به فولدر دیگری کپی کنید. در این درس تمرکزخود را بر روی کلون کردن در محیط لوکال می‌گذاریم تا مفاهیم اولیه را به خوبی درک کنید. در درس‎های بعدی راجع کلون کردن مخازن ریموت نیز حرف می‌زنیم.

cd /path/to/my-git-repo
cd ..
git clone my-git-repo marys-repo
cd marys-repo

در سطراول، خط فرمان را به فولدر پروژه یعنی my-git-repo برده‌ایم. سپس با ..cd خط فرمان را یک سطح از فولدر فعلی عقب رانده‌ایم. در cmd هربار که این دستور را می‌زنید یک فولدر به عقب برمی‌گردد. سپس با دستور clone از گیت درخواست می‌کنیم یک نسخه از my-git-repo را به فولدر marys-repo کپی کند. اگر فولدر وجود نداشته باشد، ساخته می‌شود. به فولدر marys-repo بروید و با دستور git log اطمینان یابید که فولدر حاضر کپی کاملی از مخزن اصلی پروژه است.

پیکربندی مخزن (ماری)

ماری برای شروع کار باید مخزنش را پیکربندی کند تا هویتش در هنگام مشارکت با پروژه مشخص باشد.

git config user.name "Mary"
git config user.email mary.example@rypress.com

احتمالاً از درس‌های قبلی به خاطر دارید که از فلگ global– در این دستوراستفاده می‌کردیم تا تنظیمات روی تمام گیت اعمال شود. ولی اینجا چون مخزن جدید روی سیستم لوکال قرار گرفته از این فلگ استفاده نمی‌کنیم تا تنظیمات فقط روی فولدر marys-repo اعمال شود. برای اینکه بدانید تنظیمات فوق کجا ذخیره می‌شود فایل‌های مخفی را آشکار کنید. سپس به فولدر git. در فولدر ماری بروید و فایل config را باز کنید. این فایل تمام تنظیمات لوکال را ذخیره می‌کند. در انتهای فایل اطلاعات ماری را می‌بینید که در دستورات بالا وارد کرده‌ایم. تنظیمات فوق، تنظیمت global یا عمومی گیت را override می‌کند؛ البته فقط برای این مخزن.

شروع کار (ماری)

ماری قصد دارد روی صفحۀ بیوگرافی خود کار کند. پس ابتدا یک شاخۀ جدید درست می‌کن:

git checkout -b bio-page

ماری این کاررا دقیقاً به همان صورتی انجام می‌دهد که ما قبلا انجام می‌دادیم. مخزن او کاملاً ایزوله و مستقل از مخزن my-git-repo است و بدون نگرانی می‌تواند پروژه را توسعه دهد.

ساخت صفحۀ ماری (ماری)

اجازه دهید صفحۀ بیوگرافی ماری را در فولدر marys-repo به صورت زیر تغییر دهیم:

<!DOCTYPE html>
<html lang="en">
<head>
  <title>About Mary</title>
  <link rel="stylesheet" href="../style.css" />
  <meta charset="utf-8" />
</head>
<body>
  <h1>About Mary</h1>
  <p>I'm a graphic designer.</p>

  <h2>Interests</h2>
  <ul>
    <li>Oil Painting</li>
    <li>Web Design</li>
  </ul>
<p><a href="index.html">Return to about page</a></p>
</body>
</html>

تغییرات فوق را در شاخۀ مجزایی که ساختیم استیج و کامیت می‌کنیم. به خاطر دارید که شاخۀ مستر فقط برای کدهای تست شده و پایدار است.

git commit -a -m "Add bio page for Mary"
git log -n 1

اکنون باید فیلد Author در دستور log نام و ایمیل ماری که در پیکربندی مشخص کردیم را نمایش دهد. این را هم می‌دانید که ۱ n- خروجی لاگ را به یک کامیت محدود می‌کند.

بخوانید  آموزش گیت - قسمت دوازدهم (آخر)

انتشار صفحۀ بیو (ماری)

حالا می‌توانیم تغییرات صفحۀ بیو را در شاخۀ مستر ادغام کنیم.

git checkout master
git merge bio-page

ادغام فوق به روش fast-forward انجام می‌شود. این تغییرات را بعداً باید به فولدر اصلی پروژه یعنی my-git-repo اعمال کنیم. در حال حاضر وضعیت مخزن ماری در مقایسه با مخزن ما به شکل زیر است:

ادغام شاخۀ bio-page با شاخۀ مسترِ ماری

همانطور که می‌بینید هر دو مخزن، شاخه‌های مجزای خود را دارند. یک شاخۀ مستر متعلق به مخزن ماری است و دیگری مستری که متعلق به ماست. هنوز هیچ ارتباطی بین دو مخزن برقرار نکرده‌ایم؛ به همین خاطر شاخۀ ریموتی در تصویر مشاهده نمی‌کنید. قبل از سوییچ کردن به my-git-repo اتصالات ریموت ماری را بررسی می‌کنیم.

نمایش مخازن ریموت (ماری)

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

git remote

ظاهراً او یک اتصال ریموت به نام origin دارد. در هنگام کلون کردن مخزن، گیت با این فرض که شاید بعدها بخواهید با آن تعامل داشته باشید به صورت خودکار یک اشاره‌گر ریموت به نام origin به مخزن اصلی پروژه اضافه می‌کند. با پرچم v می‌توانیم اطلاعات بیشتری به دست آوریم:

git remote -v

این دستور با نمایش مسیر کامل مخزن اصلی (Original) اطمینان می‌دهد که origin یک اتصال ریموت به my-git-repo است. مسیر مشابهی نیز برای fetch و push در نظر گرفته شده است. در موردشان به زودی توضیح خواهیم داد.

بازگشت به مخزن خودتان (شما)

خب حالا می‌خواهیم به مخزن خودمان برگردیم.

cd ../my-git-repo

توجه داشته باشید که در مخزن ما هنوز صفحۀ بیوگرافی ماری خالی است. بسیار مهم است که بدانید مخزن شما کاملاً از مخزن ماری جداست. ماری صفحۀ بیوی خود را تغییر داده است و با شاخۀ مستر خودش ادغام کرده ولی اینجا هیچ خبری نیست. حتی ما هم می‌توانیم فایل بیوی ماری را تغییر دهیم که در هنگام ادغام با مخزن ماری به تداخل یا conflict منجرمی‌شود.

اضافه کردن ماری به عنوان ریموت (شما)

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

git remote

همانطور که می‌بینید هیچ ریموتی وجود ندارد. ریموت origin نیز ساخته نشده چون از هیچ جایی کلون نکرده‌ایم. برای اضافه کردن ماری به عنوان یک مخزن ریموت دستورات زیر را وارد کنید:

git remote add mary ../marys-repo
git remote -v

اکنون با کلمۀ mary به مخزن او دسترسی داریم. در واقع کاری که دستور git remote add انجام می‌دهد، ساخت یک بوکمارک برای دسترسی سریع به مخزن است. اکنون مطابق تصویر زیر به مخزن ماری دسترسی داریم:

اتصال به مخزن ریموت

بعد از اتصال به مخزن ریموت باید دربارۀ شاخه‌های ریموت صحبت کنیم.

فچ کردن شاخه‌های مخزن ماری (شما)

ما می‌توانیم از شاخه‌های ریموت برای دسترسی به اسنپ‌شات‌های سایر مخازن استفاده کنیم. ابتدا شاخه‌های ریموتی که در حال حاضر داریم را فهرست می‌کنیم:

git branch -r

همانطور که می‌بینید هیچ شاخۀ ریموتی وجود ندارد. برای اضافه کردن شاخه‌های مخزن ماری از دستور fetch استفاده می‌کنیم:

git fetch mary
git branch -r

اکنون شاخه‌های bio-page و master مخزن ماری را می‌بینید. دستور fetch با دیدن mary به همان مکانی که مخزن او را مشخص کردیم مراجعه کرده (با git remote -v می‌توانید آدرس را ببینید) و شاخه‌ها را دریافت می‌کند.

mary/bio-page
mary/master

شاخه‌های ریموت همیشه به فرم <remote‑name>/<branch‑name> نمایش داده می‌شوند تا با شاخه‌های محلی اشتباه گرفته نشوند. لیست بالا شاخه‌های مخزن ماری را در لحظۀ fetch نشان می‌دهد. بنابراین اگر ماری شاخۀ جدیدی به مخزن اضافه کند به صورت خودکار به شاخه‌های ریموت مخزن ما اضافه نخواهد شد. در واقع اتصال به شاخه‌های ریموت یک اتصال زنده و درلحظه نیستبلکه صرفاً یک کپی فقط خواندنی از شاخه‌های مخزن ماری است که در مخزن ما ذخیره شده است. این یعنی برای دریافت شاخه‌های جدید باید دوباره عمل fetch را انجام دهیم.

شاخه‌های ریموت ماری در مخزن ما

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

بخوانید  آموزش گیت - قسمت نهم

چک‌اوت کردن شاخۀ ریموت

بیایید یک شاخۀ ریموت را چک‌اوت کنیم تا آخرین تغییرات ماری را ببینیم:

git checkout mary/master

از آنجایی که شاخۀ ریموت، کپی برابر اصل شاخۀ ماری است، دستور فوق، HEAD را به شاخۀ ریموتِ mary/master واقع در مخزن ما برده و وضعیت را به detached HEAD تغییر می‌دهد مطابق تصویر زیر:

‌اوت کردن شاخۀ مسترِ ماری

ما این اجازه را نداریم که در شاخه‌ای غیر از لوکال به توسعه ادامه دهیم. برای توسعۀ شاخۀ mary/master یا باید آن را در شاخۀ مستر خودمان ادغام کنیم یا کلاً یک شاخۀ جدید بسازیم. راه‌حل دوم را در قسمت اول شاخه‌ها در درس‌های قبلی توضیح دادیم؛ آنجایی که باید روی یک کامیت قدیمی کار می‌کردیم. راه‌حل اول را هم مبنی بر بازیابی کامیت‌ از دست رفته در درس‌های قبلی شرح دادیم. اما چیزی که الان دنبالش هستیم، تغییرات اعمال شده توسط ماری است. بنابراین detached HEAD کمکی به ما نمی‌کند.

پیدا کردن تغییرات ماری

برای مشاهدۀ تغییرات ماری می‌توانیم از همان سینتکسِ فیلترینگ درس قبل استفاده کنیم:

git log master..mary/master --stat

دستور فوق تغییراتی که ماری به شاخۀ مسترش اضافه کرده را نشان می‌دهد. اما فکر خوبی است که چک کنیم آیا تغییرات جدیدی در مخزن ما هست که در مخزن ماری وجود نداشته باشد:

git log mary/master..master --stat

چیزی در خروجی نمایش داده نمی‌شود؛ بنابراین ما از وقتی که ماری مخزنمان را کلون کرده تغییری اعمال نکرده‌ایم.

ادغام تغییرات ماری

برای ادغام تغییرات ماری با شاخۀ مسترمان از دستورات زیر استفاده می‌کنیم:

git checkout master
git merge mary/master

با اینکه mary/master یک شاخۀ ریموت است، گیت کماکان از روش fast-forward برای دستور merge استفاده می‌کند چون تاریخچۀ آن به صورت خطی در ادامۀ شاخۀ مستر ما قرار گرفته است:

وضعیت مخزن قبل از ادغام شاخۀ مستر ماری با شاخۀ مستر خودمان

بعد از ادغام، اسنپ‌شات‌های شاخۀ ریموتِ ماری، بخشی از شاخۀ مستر در مخزن ما می‌شود. در نهایت مستر ما با مستر ماری همگام خواهد شد:

وضعیت مخزن بعد از ادغام شاخۀ مستر ماری در مستر خودمان

توجه داشته باشید با اینکه به شاخۀ bio-page ماری دسترسی داشتیم ولی فقط با شاخۀ مستر آن تعامل کردیم.

پوش کردن یک شاخۀ ساختگی

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

git branch dummy
git push mary dummy

با دستورات بالا یک شاخه به نام dummy ساخته می‌شود و سپس به مخزن ماری ارسال می‌شود. به مخزن ماری سوئیچ کنید تا تغییرات را مشاهده کنید:

cd ../marys-repo
git branch

شما باید شاخۀ جدید dumy را در فهرست شاخه‌های محلی او مشاهد کنید. ما گفتیم فچ و پوش در مقابل هم قرار دارند چون دستور پوش یک شاخۀ جدید لوکال ایجاد می‌کند در حالی که فچ، کامیت‌ها را به شاخۀ ریموت وارد می‌سازد. خودتان را جای ماری بگذارید. در حال کدنویسی هستید که ناگهان شاخۀ dummy را در فهرست شاخه‌های محلی‌ خود می‌بینید. جا نمی‌خورید؟ واضح است که پوش کردن شاخه‌ها به مخزن افراد دیگر باعث به وجود آمدن بی‌نظمی می‌شود. بنابراین، به عنوان یک قاعدۀ کلی به خاطر بسپارید که هیچ‌وقت نباید به مخزن سایر توسعه‌دهندگان پوش کنید. پس اگر اینطور است، فایدۀ وجود چنین دستوری چیست؟

بخوانید  آموزش گیت - قسمت سوم

در درس‌های آینده خواهیم دید که عمل پوش یکی از ضروری‌ترین ابزارها برای نگهداری مخازن عمومی است. تا آن موقع همین قدر یادتان باشد که هیچ وقت نباید به مخزن دوستان خود پوش کنید. اجازه دهید این شاخۀ dummy را هنوز دردسرساز نشده حذف کنیم.

git branch -d dummy
cd ../my-git-repo
git branch -d dummy

پوش کردن یک تگ جدید

یکی از خصوصیات مهم دستور git push این است که به صورت خودکار تگ‌های مرتبط به یک شاخۀ خاص را پوش نمی‌کند. برای فهم بهتر ابتدا یک تگ جدید ایجاد کنید:

git tag -a v2.0 -m "An even stabler version of the website"

حالا یک تگ v2.0 در my-git-repo داریم که می‌توانیم با اجرای دستور git tag آن را مشاهده کنیم. اکنون سعی می‌کنیم شاخۀ مستر را به مخزن ماری پوش کنیم:

git push mary master

گیت اعلام می‌کند که شاخۀ مستر از قبل بروز بوده پس چیزی برای پوش ارسال نمی‌شود و مخزن ماری هیچ تغییری نسبت به گذشته نمی‌کند. این نشان می‌دهد که گیت در هنگام پوش کردن شاخه‌ها، کاری به تگ‌ها ندارد. برای پوش کردن تگ‌ها باید نام تگ را به جای شاخه قرار دهیم:

git push mary v2.0

اکنون باید تگ v2.0 را در مخزن ماری هم ببینید (git tag). به سادگی ممکن است، پوش کردن تگ‌های جدید را فراموش کنید. بنابراین پوش کردن تگ‌ها نیز ایدۀ خوبی نیست.

جمع‌بندی

در این درس آموختیم که چگونه می‌توانیم از شاخه‌های ریموت برای دسترسی به مخزن یک فرد دیگر استفاده کنیم. ریموت‌های فهرست شده در دستور git remote تنها بوکمارکی برای مسیر کامل یک مخزن دیگر هستند. آدرس‌های ما در این درس مسیر فایل روی سیستم بود ولی به زودی خواهید دید که گیت حتی می‌تواند با پروتکل HTTPS یا SSH به مخزن سایر کامپیوترها در هر جای دنیا دسترس داشته باشد.

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

طبق آنچه گفتیم، از ریموت‌ها برای افراد و از شاخه‌ها برای موضوعات استفاده می‌کنیم. هیچ‌وقت برای هر توسعه‌دهنده یک شاخۀ مجزا ایجاد نکنید؛ به جای اینکار به هر کدام یک مخزن جدا اختصاص دهید و با دستور gir remote add بوکمارکشان کنید. از شاخه‌ها فقط برای توسعۀ پروژه استفاده کنید نه مدیریت کاربران.

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

چکیدۀ دستورات

  • <git clone <remote-path : ساخت یک کپی از مخزن ریموت؛
  • git remote : فهرست مخازن ریموت یا به اختصار فهرست ریموت‌ها؛
  • <git remote add <remote-name> <remote-path : اضافه کردن مخزن ریموت؛
  • <git fetch <remote-name : دانلود اطلاعات از شاخۀ ریموت بدون ادغام؛
  • <git merge <remote-name>/<branch-name : ادغام ریموت به شاخۀ چک‌اوت شده؛
  • git branch -r : فهرست شاخه‌های ریموت؛
  • <git push <remote-name> <branch-name : پوش کردن شاخۀ لوکال به مخزنی دیگر؛
  • <git push <remote-name> <tag-name : پوش کردن یک تگ به یک مخزن دیگر.

سید ایوب کوکبی

نویسنده و مترجم...

مطالب مرتبط

آموزش گیت – قسمت یازدهم

۲۷ اردیبهشت ۱۳۹۸

آموزش گیت – قسمت دهم

۲۷ اردیبهشت ۱۳۹۸

0 دیدگاه

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