| GITATTRIBUTES(5) | Git Manual | GITATTRIBUTES(5) |
نام (NAME)
gitattributes - تعریف مشخصهها برای هر مسیر
خلاصه دستور (SYNOPSIS)
$GIT_DIR/info/attributes, .gitattributes
توضیحات (DESCRIPTION)
یک فایل gitattributes یک فایل متنی ساده است که به نام مسیرها مشخصهها (attributes) را اختصاص میدهد.
هر خط در فایل gitattributes به این صورت است:
pattern attr1 attr2 ...
یعنی یک الگو (pattern) که به دنبال آن فهرستی از مشخصهها با فاصله (whitespace) جدا شدهاند. فاصلههای ابتدایی و انتهایی نادیده گرفته میشوند. خطوطی که با # آغاز میشوند نادیده گرفته میشوند. الگوهایی که با نقلقول دوتایی شروع میشوند، به سبک C نقلقول میشوند. هنگامی که الگو با مسیر مورد نظر مطابقت داشته باشد، مشخصههای فهرستشده در آن خط به آن مسیر اختصاص داده میشوند.
هر مشخصه میتواند برای یک مسیر دادهشده در یکی از این حالتها باشد:
تنظیمشده (Set)
تنظیمنشده (Unset)
تنظیمشده به یک مقدار (Set to a value)
مشخصنشده (Unspecified)
هنگامی که بیش از یک الگو با مسیر مطابقت داشته باشد، خطوط بعدی خطوط قبلی را بازنویسی (override) میکنند. این بازنویسی برای هر مشخصه به طور جداگانه انجام میشود.
قوانینی که الگوها بر اساس آن با مسیرها مطابقت مییابند همانند فایلهای .gitignore است (به gitignore(5) مراجعه کنید)، با چند استثنا:
هنگام تصمیمگیری در مورد اینکه چه مشخصههایی به یک مسیر اختصاص یابد، Git فایل $GIT_DIR/info/attributes (که بالاترین اولویت را دارد)، فایل .gitattributes در همان شاخهٔ مسیر مورد نظر، و شاخههای والد آن را تا بالاترین سطح درخت کاری (هرچه شاخه حاوی .gitattributes از مسیر مورد نظر دورتر باشد، اولویت آن کمتر است) بررسی میکند. در نهایت فایلهای سراسری (global) و سیستمی (system-wide) در نظر گرفته میشوند (که کمترین اولویت را دارند).
هنگامی که فایل .gitattributes در درخت کاری موجود نباشد، مسیر موجود در نمایه (index) به عنوان جایگزین استفاده میشود. در طول فرایند دریافت (checkout)، فایل .gitattributes در نمایه استفاده شده و سپس فایل موجود در درخت کاری به عنوان جایگزین استفاده میشود.
اگر مایلید تنها بر یک مخزن خاص اثر بگذارید (یعنی مشخصهها را به فایلهایی اختصاص دهید که مختص جریان کاری یک کاربر برای آن مخزن هستند)، مشخصهها باید در فایل $GIT_DIR/info/attributes قرار گیرند. مشخصههایی که باید تحت کنترل نگارش قرار گرفته و به مخازن دیگر توزیع شوند (یعنی مشخصههایی که برای همهٔ کاربران اهمیت دارند) باید در فایلهای .gitattributes قرار گیرند. مشخصههایی که باید بر تمام مخازن یک کاربر اثر بگذارند باید در فایلی که با گزینهٔ پیکربندی core.attributesFile مشخص شده است قرار گیرند (به git-config(1) مراجعه کنید). مقدار پیشفرض آن $XDG_CONFIG_HOME/git/attributes است. اگر $XDG_CONFIG_HOME تنظیم نشده باشد یا خالی باشد، $HOME/.config/git/attributes استفاده میشود. مشخصهها برای تمام کاربران روی یک سیستم باید در فایل $(prefix)/etc/gitattributes قرار گیرند.
گاهی اوقات ممکن است نیاز داشته باشید مقدار یک مشخصه را برای یک مسیر به حالت Unspecified بازنویسی کنید. این کار با درج نام مشخصه همراه با علامت تعجب پیشوند ! انجام میشود.
مشخصههای رزروشدهٔ BUILTIN_* (RESERVED BUILTIN_* ATTRIBUTES)
فضای نام builtin_* برای مقادیر مشخصههای توکار رزرو شده است. هرگونه مشخصهٔ تعریفشده توسط کاربر تحت این فضای نام نادیده گرفته شده و هشداری را ایجاد میکند.
builtin_objectmode
این مشخصه برای پالایش فایلها بر اساس حالت بیتهای فایل (40000, 120000, 160000, 100755, 100644) استفاده میشود؛ مانند :(attr:builtin_objectmode=160000). شما همچنین میتوانید این مقادیر را با git check-attr builtin_objectmode -- <file> بررسی کنید. اگر شیء در نمایه نباشد، git check-attr --cached مقدار unspecified را برمیگرداند.
اثرات (EFFECTS)
برخی از عملیاتهای Git را میتوان با اختصاص مشخصههای خاص به یک مسیر تحت تأثیر قرار داد. در حال حاضر، عملیاتهای زیر به مشخصهها حساس هستند.
دریافت و ثبت (Checking-out and checking-in)
این مشخصهها تعیین میکنند که محتویات ذخیرهشده در مخزن چگونه هنگام اجرای دستورهایی نظیر git switch، git checkout و git merge در فایلهای درخت کاری کپی شوند. آنها همچنین تعیین میکنند که Git چگونه محتویاتی را که در درخت کاری آماده میکنید پس از git add و git commit در مخزن ذخیره کند.
text
این مشخصه مسیر را به عنوان یک فایل متنی نشانهگذاری میکند که تبدیل پایان خط (end-of-line) را فعال میسازد: هنگامی که یک فایل منطبق به نمایه اضافه میشود، پایان خطوط فایل در نمایه به LF تبدیل و استانداردسازی میشود. برعکس، هنگامی که فایل از نمایه به شاخهٔ کاری کپی میشود، پایان خطوط آن ممکن است بسته به مشخصهٔ eol، پیکربندی Git و بستر سیستم، از LF به CRLF تبدیل شود (توضیحات eol را در زیر ببینید).
تنظیمشده (Set)
تنظیمنشده (Unset)
تنظیمشده به مقدار رشتهای "auto"
مشخصنشده (Unspecified)
هر مقدار دیگری باعث میشود Git طوری رفتار کند که گویی text مشخصنشده رها شده است.
eol
این مشخصه مسیری را نشانهگذاری میکند تا هنگام دریافت در درخت کاری از سبک پایان خط خاصی استفاده کند. این مشخصه تنها زمانی مؤثر است که text یا text=auto تنظیم شده باشد، اما تعیین eol در صورتی که text مشخص نشده باشد، به طور خودکار text را تنظیم میکند.
تنظیمشده به مقدار رشتهای "crlf"
تنظیمشده به مقدار رشتهای "lf"
مشخصنشده (Unspecified)
سازگاری
رو به عقب با
مشخصه crlf
برای سازگاری رو به عقب، مشخصهٔ crlf به صورت زیر تفسیر میشود:
crlf text -crlf -text crlf=input eol=lf
تبدیل
پایان خط (End-of-line
conversion)
در حالی که Git به طور معمول محتوای فایل را دستنخورده باقی میگذارد، میتوان آن را طوری پیکربندی کرد که پایان خطوط را در مخزن به LF تبدیل کرده و به صورت اختیاری هنگام دریافت فایلها آنها را به CRLF تبدیل نماید.
اگر صرفاً میخواهید بدون در نظر گرفتن مخزنی که روی آن کار میکنید پایان خطوط CRLF در شاخهٔ کاری خود داشته باشید، میتوانید متغیر پیکربندی "core.autocrlf" را بدون استفاده از هیچ مشخصهای تنظیم کنید.
[core]
autocrlf = true
این کار یکپارچهسازی فایلهای متنی را اجبار نمیکند، اما تضمین میکند فایلهای متنی جدیدی که به مخزن وارد میکنید هنگام اضافهشدن، پایان خطوط آنها به LF تبدیل شده و فایلهایی که از قبل در مخزن یکپارچه شدهاند به همان صورت باقی بمانند.
اگر میخواهید مطمئن شوید فایلهای متنی واردشده توسط هر مشارکتکنندهای یکپارچهسازی میشوند، میتوانید مشخصهٔ text را برای همهٔ فایلها روی "auto" تنظیم کنید.
* text=auto
مشخصهها امکان کنترل دقیق نحوهٔ تبدیل پایان خطوط را فراهم میکنند. در اینجا مثالی آمده است که باعث میشود Git فایلهای .txt، .vcproj و .sh را یکپارچه کند، مطمئن شود فایلهای .vcproj دارای CRLF و فایلهای .sh دارای LF در شاخهٔ کاری باشند، و از یکپارچهسازی فایلهای .jpg صرفنظر از محتوای آنها جلوگیری کند.
* text=auto *.txt text *.vcproj text eol=crlf *.sh text eol=lf *.jpg -text
نکته
هنگامی که تبدیل text=auto در یک پروژهٔ چندبستری با استفاده از push و pull به یک مخزن مرکزی فعال میشود، فایلهای متنی حاوی CRLF باید یکپارچهسازی شوند.
از یک شاخهٔ کاری تمیز:
$ echo "* text=auto" >.gitattributes $ git add --renormalize . $ git status # فایلهایی را که استانداردسازی خواهند شد نمایش میدهد $ git commit -m "Introduce end-of-line normalization"
اگر فایلی که نباید استانداردسازی شود در git status ظاهر شد، قبل از اجرای git add -u مشخصهٔ text آن را لغو کنید.
manual.pdf -text
برعکس، برای فایلهای متنی که Git آنها را تشخیص نداده است میتوان یکپارچهسازی را به صورت دستی فعال کرد.
weirdchars.txt text
اگر core.safecrlf روی "true" یا "warn" تنظیم شده باشد، Git بررسی میکند که آیا تبدیل با تنظیمات فعلی core.autocrlf برگشتپذیر است یا خیر. برای "true"، تبدیلهای برگشتناپذیر را رد میکند؛ برای "warn"، فقط هشدار میدهد اما تبدیل را میپذیرد. این ویژگی ایمنی برای جلوگیری از اعمال چنین تبدیلی روی فایلهای درخت کاری فعال میشود، با این حال چند استثنا وجود دارد:
working-tree-encoding
ابزار Git فایلهای کدگذاریشده در ASCII یا یکی از ابرمجموعههای آن (مانند UTF-8، ISO-8859-1 و ...) را به عنوان فایل متنی میشناسد. فایلهای کدگذاریشده در برخی کدگذاریهای دیگر (مانند UTF-16) به عنوان باینری تفسیر میشوند و در نتیجه ابزارهای پردازش متن توکار Git (مانند git diff) و اکثر رابطهای وب Git به طور پیشفرض محتوای این فایلها را نمایش نمیدهند.
در این موارد میتوانید با استفاده از مشخصهٔ working-tree-encoding کدگذاری یک فایل در شاخهٔ کاری را به Git اطلاع دهید. اگر فایلی با این مشخصه به Git اضافه شود، Git محتوا را از کدگذاری مشخصشده به UTF-8 بازکدگذاری (re-encode) میکند. در نهایت، محتوای کدگذاریشده در UTF-8 را در ساختار دادههای داخلی خود (به نام "index") ذخیره میکند. هنگام دریافت (checkout)، محتوا مجدداً به کدگذاری مشخصشده تبدیل میشود.
لطفاً توجه داشته باشید که استفاده از مشخصهٔ working-tree-encoding ممکن است چالشهایی به همراه داشته باشد:
به عنوان مثال، فایلهای منابع Microsoft Visual Studio با پسوند (*.rc) یا اسکریپتهای PowerShell با پسوند (*.ps1) گاهی به صورت UTF-16 کدگذاری میشوند. اگر *.ps1 را به عنوان UTF-16 اعلان کنید و فایل foo.ps1 را با یک کلاینت پشتیبانیکننده از working-tree-encoding اضافه کنید، foo.ps1 به صورت داخلی به شکل UTF-8 ذخیره میشود. کلاینتی که از این مشخصه پشتیبانی نمیکند، فایل foo.ps1 را به عنوان یک فایل UTF-8 دریافت میکند که معمولاً برای کاربران این فایل مشکل ایجاد خواهد کرد.
اگر کلاینتی که از این مشخصه پشتیبانی نمیکند فایل جدید bar.ps1 را اضافه کند، فایل به همان صورت در مخزن ذخیره میشود (احتمالاً UTF-16). کلاینت با قابلیت پشتیبانی، محتوای داخلی را UTF-8 فرض کرده و تلاش میکند آن را به UTF-16 تبدیل کند که این عملیات با خطا مواجه خواهد شد.
از مشخصهٔ working-tree-encoding تنها در صورتی استفاده کنید که نمیتوانید فایل را با کدگذاری UTF-8 ذخیره کنید و میخواهید Git بتواند محتوا را به عنوان متن پردازش کند.
به عنوان مثال، اگر فایلهای *.ps1 شما به صورت UTF-16 با نشانگر ترتیب بایتها (BOM) هستند و میخواهید Git تبدیل خودکار پایان خط را بر اساس بستر سیستم شما انجام دهد، از مشخصههای زیر استفاده کنید:
*.ps1 text working-tree-encoding=UTF-16
اگر فایلهای *.ps1 به صورت UTF-16 little endian بدون BOM هستند و میخواهید Git از پایان خطوط ویندوز در شاخهٔ کاری استفاده کند، از مشخصههای زیر استفاده کنید (در صورت نیاز به BOM از UTF-16LE-BOM به جای UTF-16LE استفاده کنید). لطفاً توجه داشته باشید برای جلوگیری از ابهام، تعریف صریح پایان خطوط با eol هنگام استفاده از working-tree-encoding اکیداً توصیه میشود.
*.ps1 text working-tree-encoding=UTF-16LE eol=crlf
میتوانید فهرست تمام کدگذاریهای موجود در بستر خود را با دستور زیر مشاهده کنید:
iconv --list
اگر از کدگذاری یک فایل اطلاعی ندارید، میتوانید با دستور file آن را حدس بزنید:
file foo.ps1
ident
هنگامی که مشخصهٔ ident برای یک مسیر تنظیم شود، Git هنگام دریافت عبارت $Id$ را در شیء blob با $Id: و به دنبال آن نام شیء blob با ۴۰ نویسهٔ هگزادسیمال و یک علامت دلار $ جایگزین میکند. هر توالی بایتی که با $Id: شروع و با $ در فایل درخت کاری پایان یابد، هنگام ثبت با $Id$ جایگزین میشود.
filter
مشخصهٔ filter را میتوان روی یک مقدار رشتهای تنظیم کرد که نام یک گردانندهٔ فیلتر (filter driver) مشخصشده در پیکربندی را تعیین میکند.
یک گردانندهٔ فیلتر شامل یک دستور clean و یک دستور smudge است که هر کدام میتوانند تعریفنشده باقی بمانند. هنگام دریافت، وقتی دستور smudge مشخص شده باشد، شیء blob از ورودی استاندارد به آن داده میشود و خروجی استاندارد آن برای بهروزرسانی فایل در درخت کاری استفاده میشود. به طور مشابه، دستور clean برای تبدیل محتویات فایل درخت کاری هنگام ثبت استفاده میشود. به طور پیشفرض این دستورها تنها یک blob را پردازش کرده و خاتمه مییابند. اگر یک فیلتر process با اجرای طولانی به جای فیلترهای clean و/یا smudge استفاده شود، Git میتواند تمام blobها را با یک بار اجرای دستور فیلتر در تمام طول عمر یک دستور Git (مانند git add --all) پردازش کند. اگر یک فیلتر فرایندی پیکربندی شده باشد، همیشه بر فیلترهای تکحبابی اولویت دارد. بخش زیر را برای توضیحات پروتکل ارتباط با فیلتر process ببینید.
یک کاربرد پالایش محتوا، تغییر شکل آن به صورتی است که برای بستر، سیستم فایل و کاربر راحتتر باشد. برای این حالت، عبارت کلیدی "راحتتر بودن" است و نه "تبدیل چیزی غیرقابل استفاده به قابل استفاده". به عبارت دیگر، هدف این است که اگر فردی تعریف فیلتر را لغو کرد یا برنامهٔ فیلتر مناسب را نداشت، پروژه همچنان قابل استفاده باشد.
کاربرد دیگر پالایش محتوا، ذخیره محتوایی است که نمیتواند مستقیماً در مخزن استفاده شود (مانند یک UUID که به محتوای واقعی خارج از Git اشاره دارد، یا محتوای رمزگذاریشده) و تبدیل آن به یک فرم قابل استفاده هنگام دریافت (مانند دانلود محتوای خارجی یا رمزگشایی محتوا).
این دو فیلتر رفتار متفاوتی دارند و به طور پیشفرض، فیلتر به عنوان حالت اول در نظر گرفته میشود. نبودن تعریف گرداننده در پیکربندی یا خروج با وضعیت غیر صفر خطا محسوب نمیشود و تنها باعث عبور بدون تغییر محتوا (no-op passthru) میگردد.
شما میتوانید با تنظیم متغیر پیکربندی filter.<driver>.required روی true اعلام کنید که فیلتر محتوایی را که به خودی خود غیرقابل استفاده است به محتوای قابل استفاده تبدیل میکند.
نکته: هر زمان که فیلتر clean تغییر کرد، مخزن باید بازیکپارچهسازی شود: $ git add --renormalize .
به عنوان مثال، در .gitattributes مشخصهٔ filter را برای مسیرها تعیین میکنید:
*.c filter=indent
سپس در فایل .git/config خود پیکربندیهای "filter.indent.clean" و "filter.indent.smudge" را تعریف میکنید تا جفتدستوری را برای تغییر محتویات برنامههای C هنگام ثبت (اجرای "clean") و دریافت (عدم تغییر به دلیل استفاده از "cat") مشخص کنید.
[filter "indent"]
clean = indent
smudge = cat
برای بهترین نتیجه، clean در صورت دو بار اجرا نباید خروجی خود را تغییر دهد ("clean→clean" باید معادل "clean" باشد)، و دستورهای متعدد smudge نباید خروجی clean را تغییر دهند ("smudge→smudge→clean" باید معادل "clean" باشد). بخش ادغام را در زیر ببینید.
فیلتر "indent" در این زمینه خوشرفتار است: ورودیای را که از قبل تورفتگی درست دارد تغییر نمیدهد. در این حالت، عدم وجود فیلتر smudge به این معنی است که فیلتر clean باید خروجی خود را بدون تغییر بپذیرد.
اگر فیلتر باید موفق شود تا محتویات ذخیرهشده قابل استفاده باشند، میتوانید در پیکربندی اعلام کنید که فیلتر required است:
[filter "crypt"]
clean = openssl enc ...
smudge = openssl enc -d ...
required
توالی "%f" در خط فرمان فیلتر با نام فایلی که فیلتر روی آن کار میکند جایگزین میشود. یک فیلتر ممکن است از این برای جایگزینی کلمات کلیدی استفاده کند. برای مثال:
[filter "p4"]
clean = git-p4-filter --clean %f
smudge = git-p4-filter --smudge %f
توجه داشته باشید که "%f" نام مسیری است که روی آن کار میشود. بسته به نگارشی که فیلتر میشود، ممکن است فایل مربوطه روی دیسک وجود نداشته باشد یا محتوای متفاوتی داشته باشد. بنابراین، دستورهای smudge و clean نباید به فایل روی دیسک دسترسی پیدا کنند، بلکه باید تنها به عنوان فیلتر روی محتوای ارائهشده از ورودی استاندارد عمل کنند.
فرایند
فیلتر با
اجرای
طولانی (Long Running Filter
Process)
اگر دستور فیلتر (یک مقدار رشتهای) از طریق filter.<driver>.process تعریف شود، Git میتواند تمام blobها را با یک بار اجرای فیلتر برای کل طول عمر یک دستور Git پردازش کند. این کار با استفاده از پروتکل فرایند طولانیمدت انجام میشود (که در Documentation/technical/long-running-process-protocol.adoc شرح داده شده است).
هنگامی که Git با اولین فایلی که نیاز به clean یا smudge دارد مواجه میشود، فیلتر را شروع کرده و دستتکانی (handshake) را انجام میدهد. در این دستتکانی، پیام خوشآمدگویی ارسالشده توسط Git عبارت "git-filter-client" است، تنها نسخهٔ ۲ پشتیبانی میشود، و قابلیتهای پشتیبانیشده "clean"، "smudge" و "delay" هستند.
سپس Git فهرستی از جفتهای "key=value" را که با یک بستهٔ تخلیه (flush packet) پایان مییابد ارسال میکند. این فهرست دستکم شامل دستور فیلتر و نام مسیر فایل برای فیلتر کردن نسبت به ریشهٔ مخزن خواهد بود. بلافاصله پس از بستهٔ تخلیه، Git محتوا را که در صفر یا چند بستهٔ pkt-line تقسیم شده و یک بستهٔ تخلیه در انتها ارسال میکند. فیلتر نباید قبل از دریافت محتوا و بستهٔ تخلیهٔ نهایی پاسخی ارسال کند. همچنین مقدار "value" در جفت "key=value" میتواند حاوی نویسهٔ "=" باشد در حالی که کلید هرگز شامل آن نخواهد بود.
packet: git> command=smudge packet: git> pathname=path/testfile.dat packet: git> 0000 packet: git> CONTENT packet: git> 0000
انتظار میرود فیلتر با فهرستی از جفتهای "key=value" که با یک بستهٔ تخلیه خاتمه مییابد پاسخ دهد. اگر فیلتر با مشکلی مواجه نشود، فهرست باید شامل وضعیت "status=success" باشد. بلافاصله پس از این بستهها، انتظار میرود فیلتر محتوا را در صفر یا چند بستهٔ pkt-line و یک بستهٔ تخلیه در انتها ارسال کند. در نهایت، فهرست دومی از جفتهای "key=value" که با بستهٔ تخلیه پایان مییابد مورد انتظار است. فیلتر میتواند وضعیت را در فهرست دوم تغییر دهد یا وضعیت را با یک فهرست خالی دستنخورده باقی بگذارد (که در هر صورت باید با بستهٔ تخلیه پایان یابد).
packet: git< status=success packet: git< 0000 packet: git< SMUDGED_CONTENT packet: git< 0000 packet: git< 0000 # فهرست خالی، "status=success" بدون تغییر میماند!
اگر محتوای نتیجه خالی باشد، فیلتر باید با وضعیت "success" و یک بستهٔ تخلیه پاسخ دهد تا خالی بودن محتوا را اعلام کند.
packet: git< status=success packet: git< 0000 packet: git< 0000 # محتوای خالی! packet: git< 0000 # فهرست خالی، وضعیت موفقیت دستنخورده میماند!
در صورتی که فیلتر نتواند یا نخواهد محتوا را پردازش کند، انتظار میرود با وضعیت "status=error" پاسخ دهد.
packet: git< status=error packet: git< 0000
اگر فیلتر حین پردازش با خطایی مواجه شود، میتواند وضعیت "error" را پس از ارسال (جزئی یا کامل) محتوا ارسال کند.
packet: git< status=success packet: git< 0000 packet: git< HALF_WRITTEN_ERRONEOUS_CONTENT packet: git< 0000 packet: git< status=error packet: git< 0000
در صورتی که فیلتر نتواند یا نخواهد محتوای فعلی و همچنین هرگونه محتوای آینده را در طول عمر فرایند Git پردازش کند، میتواند در هر نقطهای از پروتکل با وضعیت "status=abort" پاسخ دهد.
packet: git< status=abort packet: git< 0000
در صورت تنظیم وضعیت "error"/"abort"، ابزار Git فرایند فیلتر را متوقف یا راهاندازی مجدد نمیکند. با این حال، Git کد خروج خود را بر اساس پرچم filter.<driver>.required تنظیم میکند.
اگر فیلتر در طول ارتباط متوقف شود یا از پروتکل پیروی نکند، Git فرایند فیلتر را متوقف کرده و آن را با فایل بعدی که باید پردازش شود مجدداً راهاندازی میکند. بسته به پرچم filter.<driver>.required، گیت آن را به عنوان خطا تفسیر خواهد کرد.
تأخیر (Delay)
اگر فیلتر از قابلیت "delay" پشتیبانی کند، Git میتواند پرچم "can-delay" را پس از دستور فیلتر و نام مسیر ارسال کند. این پرچم نشان میدهد که فیلتر میتواند فیلتر کردن blob فعلی را به تأخیر بیندازد (مثلاً برای جبران تأخیرهای شبکه) و در پاسخ، بدون محتوا وضعیت "delayed" و یک بستهٔ تخلیه ارسال کند.
packet: git> command=smudge packet: git> pathname=path/testfile.dat packet: git> can-delay=1 packet: git> 0000 packet: git> CONTENT packet: git> 0000 packet: git< status=delayed packet: git< 0000
اگر فیلتر از قابلیت "delay" پشتیبانی کند، باید از دستور "list_available_blobs" نیز پشتیبانی کند. اگر Git این دستور را ارسال کند، فیلتر باید فهرستی از مسیرهای نشاندهندهٔ حبابهایی را که قبلاً به تأخیر افتاده بودند و اکنون در دسترس هستند بازگرداند. این فهرست باید با یک بستهٔ تخلیه و به دنبال آن وضعیت "success" که آن هم با بستهٔ تخلیه خاتمه مییابد بسته شود. اگر هیچ حبابی هنوز در دسترس نیست، فیلتر باید پاسخ را مسدود کند تا زمانی که حداقل یک حباب در دسترس قرار گیرد. فیلتر میتواند با ارسال یک فهرست خالی به Git اعلام کند که دیگر حباب با تأخیر ندارد. تمام حبابهایی که Git تا این نقطه دریافت نکرده باشد مفقود در نظر گرفته شده و منجر به خطا میشوند.
packet: git> command=list_available_blobs packet: git> 0000 packet: git< pathname=path/testfile.dat packet: git< pathname=path/otherfile.dat packet: git< 0000 packet: git< status=success packet: git< 0000
پس از اینکه Git نام مسیرها را دریافت کرد، حبابهای مربوطه را دوباره درخواست میکند. این درخواستها شامل یک نام مسیر و بخش محتوای خالی هستند. فیلتر باید با محتوای پالایششده (smudge) به شیوهٔ معمول پاسخ دهد.
packet: git> command=smudge packet: git> pathname=path/testfile.dat packet: git> 0000 packet: git> 0000 # محتوای خالی! packet: git< status=success packet: git< 0000 packet: git< SMUDGED_CONTENT packet: git< 0000 packet: git< 0000 # فهرست خالی، وضعیت دستنخورده میماند!
مثال
یک پیادهسازی نمایشی از فیلتر طولانیمدت را میتوان در contrib/long-running-filter/example.pl واقع در مخزن اصلی Git یافت. اگر فیلتر فرایندی خود را توسعه میدهید، متغیرهای محیطی GIT_TRACE_PACKET میتوانند برای اشکالزدایی بسیار مفید باشند (به git(1) مراجعه کنید).
لطفاً توجه داشته باشید که نمیتوانید از دستورهای موجود filter.<driver>.clean یا filter.<driver>.smudge با filter.<driver>.process استفاده کنید زیرا دو مورد اول از پروتکل متفاوتی نسبت به مورد دوم استفاده میکنند.
تعامل
میان
مشخصههای
ثبت/دریافت
در مسیر کد ثبت (check-in)، فایل درخت کاری ابتدا با گردانندهٔ filter (در صورت تعیین و تعریف گرداننده مربوطه) تبدیل میشود، سپس نتیجه با ident (در صورت تعیین) پردازش شده و در نهایت با text (در صورت تعیین و کاربردپذیری) پردازش میگردد.
در مسیر کد دریافت (check-out)، محتوای blob ابتدا با text تبدیل شده و سپس با ident پردازش و به filter تحویل داده میشود.
ادغام
شاخهها با
مشخصههای
ثبت/دریافت
متفاوت
اگر مشخصههایی را به فایلی اضافه کردهاید که باعث تغییر قالب استاندارد مخزن برای آن فایل میشود (مانند افزودن فیلتر clean/smudge یا مشخصههای text/eol/ident)، ادغام مواردی که مشخصه در آنها اعمال نشده معمولاً باعث تعارضهای ادغام (merge conflicts) میشود.
برای جلوگیری از این تعارضهای غیرضروری، میتوان با تنظیم متغیر پیکربندی merge.renormalize به Git دستور داد تا یک دریافت و ثبت مجازی را برای هر سه مرحله از فایلی که نیاز به ادغام سهطرفه دارد اجرا کند. این کار از ایجاد تعارضهای ادغام ساختگی ناشی از تبدیل در هنگام ثبت جلوگیری میکند.
تا زمانی که یک "smudge→clean" حتی روی فایلهایی که از قبل فیلتر شدهاند نتیجهای یکسان با "clean" داشته باشد، این راهبرد تمام تعارضهای مربوط به فیلتر را به طور خودکار حل میکند. فیلترهایی که اینگونه عمل نمیکنند ممکن است تعارضهای ادغام دیگری ایجاد کنند که باید به صورت دستی حل شوند.
تولید متن تفاوتها (Generating diff text)
diff
مشخصهٔ diff بر نحوهٔ تولید تفاوتها (diffs) برای فایلهای خاص توسط Git تأثیر میگذارد. این مشخصه میتواند به Git بگوید که آیا یک وصله متنی تولید کند یا با مسیر به عنوان یک فایل باینری رفتار کند. همچنین میتواند بر خطی که در سرآیند تکهکد (hunk header) در خط @@ -k,l +n,m @@ نمایش داده میشود تأثیر بگذارد، به Git بگوید از یک دستور خارجی برای تولید تفاوت استفاده کند، یا از Git بخواهد قبل از تولید تفاوت، فایلهای باینری را به یک قالب متنی تبدیل کند.
تنظیمشده (Set)
تنظیمنشده (Unset)
مشخصنشده (Unspecified)
رشته (String)
تعریف یک
گرداننده
تفاوت
خارجی
تعریف گرداننده تفاوت در فایل gitconfig انجام میشود و نه در فایل gitattributes. با این حال:
برای تعریف یک گرداننده تفاوت خارجی jcdiff، بخشی مانند زیر را به فایل $GIT_DIR/config (یا $HOME/.gitconfig) خود اضافه کنید:
[diff "jcdiff"]
command = j-c-diff
هنگامی که Git نیاز به نمایش تفاوت برای مسیری با مشخصهٔ diff=jcdiff دارد، دستور مشخصشده (j-c-diff) را با ۷ پارامتر فراخوانی میکند، درست مانند برنامهٔ GIT_EXTERNAL_DIFF. برای جزئیات به git(1) مراجعه کنید.
اگر برنامه قادر به نادیده گرفتن برخی تغییرات است (مشابه git diff --ignore-space-change)، گزینهٔ trustExitCode را نیز روی true تنظیم کنید. در این حالت انتظار میرود در صورت یافتن تغییرات معنادار با کد خروج ۱ و در غیر این صورت با ۰ خارج شود.
تنظیم
الگوریتم
تفاوت
داخلی
الگوریتم تفاوت را میتوان از طریق کلید پیکربندی diff.algorithm تنظیم کرد، اما گاهی اوقات تنظیم آن به ازای هر مسیر مفید است. برای مثال، ممکن است بخواهید از الگوریتم minimal برای فایلهای .json و histogram برای فایلهای .c استفاده کنید.
ابتدا در .gitattributes مشخصهٔ diff را به مسیرها اختصاص دهید:
*.json diff=<name>
سپس، یک پیکربندی "diff.<name>.algorithm" برای تعیین الگوریتم تعریف کنید؛ با انتخاب از میان myers، patience، minimal، یا histogram.
[diff "<name>"] algorithm = histogram
این الگوریتم برای خروجیهای تفاوت کاربرمحور مانند git-diff(1) و git-show(1) اعمال شده و برای خروجی --stat نیز استفاده میشود. موتور ادغام از این روش استفاده نخواهد کرد.
نکته
اگر diff.<name>.command برای مسیری با مشخصهٔ diff=<name> تعریف شده باشد، به عنوان یک گرداننده تفاوت خارجی اجرا میشود و افزودن diff.<name>.algorithm هیچ تأثیری نخواهد داشت.
تعریف
سرآیند
تکهکد
سفارشی (Custom Hunk-Header)
هر گروه از تغییرات (به نام "hunk" یا تکهکد) در خروجی متنی diff با خطی به این شکل شروع میشود:
@@ -k,l +n,m @@ TEXT
به این خط سرآیند تکهکد (hunk header) میگویند. بخش "TEXT" به طور پیشفرض خطی است که با یک حرف الفبا، زیرخط (_) یا علامت دلار ($) شروع میشود. برای تغییر این الگو میتوانید یک الگوی سفارشی تعریف کنید.
ابتدا در .gitattributes مشخصهٔ diff را برای مسیرها تعیین کنید:
*.tex diff=tex
سپس پیکربندی "diff.tex.xfuncname" را برای تعیین یک عبارت منظم (regular expression) تعریف کنید. بخشی را به فایل $GIT_DIR/config (یا $HOME/.gitconfig) مانند زیر اضافه کنید:
[diff "tex"]
xfuncname = "^(\\\\(sub)*section\\{.*)$"
نکته: یک سطح از بکاسلشها توسط تجزیهکننده فایل پیکربندی مصرف میشود، بنابراین باید بکاسلشها را دو برابر کنید.
چندین الگوی توکار برای سهولت کار وجود دارد و tex یکی از آنهاست، بنابراین نیازی نیست متن فوق را در فایل پیکربندی بنویسید (تنها کافی است آن را در .gitattributes فعال کنید). الگوهای توکار زیر در دسترس هستند:
سفارشیسازی
تفاوت
کلمهای (Customizing word
diff)
میتوانید قواعدی را که git diff --word-diff برای تقسیم کلمات در یک خط استفاده میکند با تعیین یک عبارت منظم در متغیر پیکربندی "diff.*.wordRegex" سفارشی کنید. برای مثال:
[diff "tex"]
wordRegex = "\\\\[a-zA-Z]+|[{}]|\\\\.|[^\\{}[:space:]]+"
برای تمامی زبانهای فهرستشده در بخش قبل، یک الگوی پیشفرض توکار ارائه شده است.
اجرای
تفاوت متنی
برای
فایلهای
باینری
گاهی اوقات مطلوب است که تفاوت نگارش متنی تبدیلشده از برخی فایلهای باینری مشاهده شود. برای مثال، یک سند واژهپرداز را میتوان به نمایش متنی ASCII تبدیل کرد و تفاوت متن را نشان داد. اگرچه در این تبدیل برخی اطلاعات از دست میرود، اما تفاوت حاصل برای مشاهده انسان بسیار مفید است (اگرچه مستقیماً قابل اعمال نیست).
گزینهٔ پیکربندی textconv برای تعریف برنامهای جهت انجام چنین تبدیلی استفاده میشود. برنامه باید یک آرگومان واحد (نام فایل) را دریافت کرده و متن حاصل را در stdout تولید کند.
برای مثال، برای نمایش تفاوت اطلاعات exif یک فایل به جای دادههای باینری:
[diff "jpg"]
textconv = exif
نکته
تبدیل متن معمولاً یک تبدیل یکطرفه است. این بدان معنی است که تفاوتهای تولیدشده توسط textconv برای اعمال کردن با patch مناسب نیستند. به همین دلیل، تنها git diff و خانواده دستورهای git log تبدیل متن را انجام میدهند؛ دستور git format-patch هرگز این خروجی را تولید نخواهد کرد.
از آنجا که تبدیل متن میتواند کند باشد، Git مکانیزمی برای حافظهٔ پنهان (cache) کردن خروجی و استفاده مجدد از آن فراهم میکند. برای فعالسازی، متغیر "cachetextconv" را در پیکربندی گردانندهٔ تفاوت تنظیم کنید:
[diff "jpg"]
textconv = exif
cachetextconv = true
این کار نتیجهٔ اجرای "exif" را برای هر حباب به صورت نامحدود در حافظه پنهان نگه میدارد. برای پاکسازی دستی حافظه پنهان، میتوانید از دستور git update-ref -d refs/notes/textconv/jpg استفاده کنید.
انتخاب
بین textconv و
تفاوت
خارجی
مزیت استفاده از دستور تفاوت خارجی انعطافپذیری است؛ شما مقید به تغییرات خطمحور نیستید. در مقابل، textconv محدودتر است اما مزایایی دارد:
نشانهگذاری
فایلها به
عنوان
باینری
سادهترین راه برای نشانهگذاری یک فایل به عنوان باینری، لغو تنظیم مشخصهٔ diff در فایل .gitattributes است:
*.ps -diff
این کار باعث میشود Git به جای تفاوت معمولی، عبارت Binary files differ را تولید کند.
با این حال اگر میخواهید همزمان از textconv استفاده کنید و با فایل به عنوان باینری رفتار شود، از گزینهٔ diff.*.binary در پیکربندی استفاده کنید:
[diff "ps"] textconv = ps2ascii binary = true
انجام یک ادغام سهطرفه (Performing a three-way merge)
merge
مشخصهٔ merge نحوهٔ ادغام سه نگارش از یک فایل را هنگام نیاز به ادغام در سطح فایل در طول git merge و سایر دستورها مانند git revert و git cherry-pick تعیین میکند.
تنظیمشده (Set)
تنظیمنشده (Unset)
مشخصنشده (Unspecified)
رشته (String)
گردانندههای
ادغام
توکار
چندین گردانندهٔ سطحپایین توکار وجود دارند که میتوان از طریق مشخصهٔ merge آنها را درخواست کرد:
text
binary
union
تعریف یک
گرداننده
ادغام
سفارشی
تعریف یک گرداننده ادغام در فایل .git/config انجام میشود.
برای تعریف یک گردانندهٔ سفارشی filfre، بخشی مانند زیر را اضافه کنید:
[merge "filfre"]
name = feel-free merge driver
driver = filfre %O %A %B %L %P
recursive = binary
متغیر merge.*.name یک نام قابل خواندن برای انسان به گرداننده میدهد.
مقدار متغیر ‘merge.*.driver` برای ساخت فرمانی جهت اجرا روی نگارش نیای مشترک (%O)، نگارش فعلی (%A) و نگارش شاخهٔ دیگر (%B) استفاده میشود. این سه نشانگر با نام فایلهای موقتی جایگزین میشوند. علاوه بر این، %L با اندازه نشانگر تعارض جایگزین میشود.
انتظار میرود گرداننده نتیجه ادغام را با بازنویسی در فایل %A ذخیره کرده و در صورت ادغام موفقیتآمیز با وضعیت صفر، یا در صورت وجود تعارض با وضعیت غیر صفر خارج شود.
متغیر merge.*.recursive مشخص میکند هنگام ادغام داخلی بین نیاهای مشترک از چه گردانندهٔ دیگری استفاده شود.
گرداننده میتواند نام مسیر نتیجه ادغام را از طریق %P دریافت کند. برچسبهای تعارض نیز با %S، %X و %Y قابل ارسال هستند.
conflict-marker-size
این مشخصه طول نشانگرهای تعارض باقیمانده در فایل درخت کاری را در طول ادغام کنترل میکند (پیشفرض ۷ نویسه است).
Documentation/git-merge.adoc conflict-marker-size=32
بررسی خطاهای فاصلههای خالی (Checking whitespace errors)
whitespace
متغیر پیکربندی core.whitespace به شما امکان میدهد آنچه را که diff و apply باید خطای فاصله در نظر بگیرند تعریف کنید (به git-config(1) مراجعه کنید). این مشخصه کنترل دقیقتری برای هر مسیر فراهم میکند.
تنظیمشده (Set)
تنظیمنشده (Unset)
مشخصنشده (Unspecified)
رشته (String)
ایجاد بایگانی (Creating an archive)
export-ignore
فایلها و شاخههای دارای مشخصهٔ export-ignore به فایلهای بایگانی اضافه نخواهند شد.
export-subst
اگر مشخصهٔ export-subst برای فایلی تنظیم شده باشد، Git هنگام افزودن این فایل به بایگانی چندین جاینگهدار (placeholder) را بسط میدهد. جاینگهدارها مشابه گزینهٔ --pretty=format: در git-log(1) هستند، با این تفاوت که باید در فایل به صورت $Format:PLACEHOLDERS$ قرار گیرند (مانند $Format:%H$ برای هش کامیت).
بستهبندی اشیاء (Packing objects)
delta
برای حبابهای مربوط به مسیرهایی با مشخصهٔ delta تنظیمشده روی false، فشردهسازی دلتا انجام نخواهد شد.
مشاهده فایلها در ابزارهای گرافیکی (Viewing files in GUI tools)
encoding
مقدار این مشخصه، کدگذاری نویسهای را تعیین میکند که باید توسط ابزارهای رابط کاربری گرافیکی (مانند gitk(1) و git-gui(1)) برای نمایش محتویات فایل مربوطه استفاده شود.
اگر این مشخصه تنظیم نشده باشد یا مقدار نامعتبر داشته باشد، از متغیر پیکربندی gui.encoding استفاده میشود.
استفاده از مشخصههای ماکرو (USING MACRO ATTRIBUTES)
شما نمیخواهید تبدیل پایان خط یا تفاوت متنی برای فایلهای باینری اعمال شود. ممکن است نیاز باشد بنویسید:
*.jpg -text -diff
اما داشتن مشخصههای فراوان خستهکننده میشود. با استفاده از مشخصههای ماکرو میتوانید مشخصهای تعریف کنید که هنگام تنظیم، چند مشخصهٔ دیگر را همزمان تنظیم یا لغو کند. سیستم دارای ماکروی توکار binary است:
*.jpg binary
تنظیم مشخصهٔ "binary" باعث لغو مشخصههای "text" و "diff" میشود. توجه داشته باشید مشخصههای ماکرو تنها میتوانند در حالت "Set" باشند.
تعریف مشخصههای ماکرو (DEFINING MACRO ATTRIBUTES)
مشخصههای ماکروی سفارشی را فقط میتوان در فایلهای سطح بالای gitattributes تعریف کرد ($GIT_DIR/info/attributes، فایل .gitattributes در ریشهٔ درخت کاری، یا فایلهای سراسری/سیستمی). ماکروی توکار "binary" معادل عبارت زیر است:
[attr]binary -diff -merge -text
نکات (NOTES)
ابزار Git هنگام دسترسی به فایل .gitattributes در درخت کاری از پیوندهای نمادین (symbolic links) پیروی نمیکند.
مثالها (EXAMPLES)
اگر این سه فایل gitattributes را داشته باشید:
(در $GIT_DIR/info/attributes) a* foo !bar -baz (در .gitattributes) abc foo bar baz (در t/.gitattributes) ab* merge=filfre abc -foo -bar *.c frotz
مشخصههای اختصاص داده شده به مسیر t/abc به صورت زیر محاسبه میشوند:
در نتیجه، مشخصههای اختصاصیافته به t/abc به این صورت خواهد بود:
foo set to true bar unspecified baz set to false merge set to string value "filfre" frotz unspecified
همچنین ببینید (SEE ALSO)
گیت (GIT)
بخشی از مجموعهٔ git(1)
| 2026-06-29 | Git 2.55.0 |