Chapters ▾ 2nd Edition

10.5 (Git Internals) - نگاشت (The Refspec)

نگاشت (The Refspec)

در سراسر این کتاب، ما از نگاشت‌های ساده بین remote branches و local references استفاده کرده‌ایم، اما این نگاشت‌ها می‌توانند پیچیده‌تر باشند. فرض کنید مراحل چند بخش قبلی را دنبال کرده‌اید و یک مخزن محلی کوچک Git ساخته‌اید و حالا می‌خواهید یک remote به آن اضافه کنید:

$ git remote add origin https://github.com/schacon/simplegit-progit

اجرای دستور بالا بخشی به فایل .git/config مخزن شما اضافه می‌کند که نام remote (origin)، آدرس URL مخزن ریموت و refspec مورد استفاده برای fetching را مشخص می‌کند:

[remote "origin"]
	url = https://github.com/schacon/simplegit-progit
	fetch = +refs/heads/*:refs/remotes/origin/*

فرمت refspec به این صورت است: ابتدا یک + اختیاری، و سپس <src>:<dst>. در اینجا <src> الگوی references در سمت ریموت است و <dst> محلی است که آن references در آن ردیابی خواهند شد. علامت + به Git می‌گوید که reference را حتی اگر fast-forward نباشد، به‌روزرسانی کند.

در حالت پیش‌فرض که به‌طور خودکار توسط دستور git remote add origin نوشته می‌شود، Git تمام references زیر مسیر refs/heads/ روی سرور را دریافت کرده و آن‌ها را به refs/remotes/origin/ در سیستم محلی می‌نویسد. بنابراین، اگر روی سرور یک branch به نام master وجود داشته باشد، شما می‌توانید لاگ آن branch را به‌صورت محلی از طریق هر یک از مسیرهای زیر مشاهده کنید:

$ git log origin/master
$ git log remotes/origin/master
$ git log refs/remotes/origin/master

همه آن‌ها معادل هستند، چون Git همه آن‌ها را به refs/remotes/origin/master بسط می‌دهد.

اگر بخواهید Git فقط branch master را هر بار دریافت کند (و نه همه branches روی سرور ریموت)، می‌توانید خط مربوط به fetch را تغییر دهید تا فقط به همان branch اشاره کند:

fetch = +refs/heads/master:refs/remotes/origin/master

این فقط refspec پیش‌فرض برای git fetch آن remote است. اگر بخواهید تنها یک بار این کار را انجام دهید، می‌توانید refspec موردنظر را مستقیم در خط فرمان مشخص کنید. برای کشیدن branch master از ریموت و ذخیره آن به‌عنوان origin/mymaster محلی، می‌توانید اجرا کنید:

$ git fetch origin master:refs/remotes/origin/mymaster

شما همچنین می‌توانید چندین refspec مشخص کنید. روی خط فرمان می‌توانید چند branch را این‌طور دریافت کنید:

$ git fetch origin master:refs/remotes/origin/mymaster \
	 topic:refs/remotes/origin/topic
From git@github.com:schacon/simplegit
 ! [rejected]        master     -> origin/mymaster  (non fast forward)
 * [new branch]      topic      -> origin/topic

در این حالت، pull مربوط به branch master رد شد چون به‌عنوان یک fast-forward reference لیست نشده بود. می‌توانید با اضافه کردن + جلوی refspec آن را مجبور به انجام کنید.

شما همچنین می‌توانید چندین refspec برای fetching در فایل configuration تعریف کنید. اگر بخواهید همیشه branches master و experiment را از remote به نام origin دریافت کنید، باید دو خط اضافه کنید:

[remote "origin"]
	url = https://github.com/schacon/simplegit-progit
	fetch = +refs/heads/master:refs/remotes/origin/master
	fetch = +refs/heads/experiment:refs/remotes/origin/experiment

از Git نسخه 2.6.0 به بعد می‌توانید از partial globs در الگوها استفاده کنید تا چند branch را همزمان انتخاب کنید، مثلاً:

fetch = +refs/heads/qa*:refs/remotes/origin/qa*

حتی بهتر اینکه می‌توانید از namespaces (یا directories) برای رسیدن به همین نتیجه به شکلی ساخت‌یافته‌تر استفاده کنید. اگر تیم QA تعدادی branches را push کند و شما بخواهید branch master و همه branches آن تیم QA را دریافت کنید (و هیچ چیز دیگری)، می‌توانید بخشی از تنظیمات خود را این‌طور تعریف کنید:

[remote "origin"]
	url = https://github.com/schacon/simplegit-progit
	fetch = +refs/heads/master:refs/remotes/origin/master
	fetch = +refs/heads/qa/*:refs/remotes/origin/qa/*

اگر یک فرآیند کاری پیچیده داشته باشید که در آن تیم QA، تیم توسعه‌دهنده‌ها و تیم یکپارچه‌سازی هر کدام branches خودشان را push کنند و روی remote branches همکاری داشته باشند، با این روش می‌توانید خیلی راحت آن‌ها را با namespace مدیریت کنید.

نگاشت‌های پوش (Pushing Refspecs)

این عالی است که می‌توانید namespaced references را این‌طور دریافت کنید، اما تیم QA چطور باید branches خودشان را درون یک فضای qa/ روی سرور قرار دهند؟ این کار با استفاده از refspecs هنگام push انجام می‌شود.

اگر تیم QA بخواهد branch master خودش را به qa/master روی سرور push کند، می‌تواند اجرا کند:

$ git push origin master:refs/heads/qa/master

اگر بخواهند Git این کار را به‌صورت خودکار هر بار که git push origin اجرا می‌شود انجام دهد، می‌توانند یک مقدار push در فایل تنظیمات اضافه کنند:

[remote "origin"]
	url = https://github.com/schacon/simplegit-progit
	fetch = +refs/heads/*:refs/remotes/origin/*
	push = refs/heads/master:refs/heads/qa/master

در این صورت، اجرای git push origin باعث می‌شود که branch محلی master به branch qa/master روی سرور push شود.

یادداشت

شما نمی‌توانید از refspec برای fetch از یک مخزن و push به مخزن دیگری استفاده کنید. برای نمونه‌ای از این کار، به به‌روز نگه داشتن مخزن عمومی گیت‌هاب شما (Keep your GitHub public repository up-to-date) مراجعه کنید.

Deleting References

همچنین می‌توانید از refspec برای حذف references از روی سرور ریموت استفاده کنید، با اجرای چیزی شبیه این:

$ git push origin :topic

از آنجایی که فرمت refspec به صورت <src>:<dst> است، وقتی بخش <src> را حذف کنید، در واقع می‌گویید که branch topic روی ریموت هیچ چیزی نباشد، و این باعث حذف آن می‌شود.

یا می‌توانید از دستور جدیدتر (که از Git نسخه v1.7.0 به بعد در دسترس است) استفاده کنید:

$ git push origin --delete topic
scroll-to-top