GIT-LFS-MIGRATE(1)   GIT-LFS-MIGRATE(1)

git-lfs-migrate - مهاجرت تاریخچه به یا از Git LFS

git lfs migrate <mode> [options] [--] [branch ...]

فایل‌ها را در یک مخزن Git به اشاره‌گرهای Git LFS یا برعکس تبدیل می‌کند، یا اندازه‌های فایل‌های Git را بر اساس نوع فایل خلاصه می‌نماید. حالت import فایل‌های Git (یعنی blobها) را به Git LFS تبدیل می‌کند، در حالی که حالت export عمل معکوس آن را انجام می‌دهد، و حالت info یک خلاصه اطلاعاتی ارائه می‌دهد که می‌تواند در تصمیم‌گیری برای وارد کردن یا خارج کردن فایل‌ها مفید باشد.

در همه حالت‌ها، به طور پیش‌فرض git lfs migrate فقط روی شاخه فعلی بررسی‌شده (checked-out) و فقط روی فایل‌هایی (از هر اندازه و نوعی) کار می‌کند که در کامیت‌هایی اضافه شده‌اند که در هیچ مخزن دوردستی وجود ندارند. گزینه‌های متعددی برای لغو این رفتارهای پیش‌فرض در دسترس هستند.

هنگام تبدیل فایل‌ها به یا از Git LFS، دستور git lfs migrate فقط در مخزن محلی و نسخه کاری شما تغییرات ایجاد می‌کند و هرگز روی مخازن دوردست تاثیری نمی‌گذارد. این امر عمدی است زیرا حالت‌های import و export عموماً به این معنا «مخرب» هستند که تاریخچه Git شما را بازنویسی می‌کنند، کامیت‌ها را تغییر می‌دهند و کدهای SHA جدید برای کامیت‌ها تولید می‌نمایند. (استثناء این قاعده، زیرحالت «بدون بازنویسی» import است؛ برای جزئیات به بخش «وارد کردن بدون بازنویسی تاریخچه (IMPORT WITHOUT REWRITING HISTORY)» مراجعه کنید.)

بنابراین باید همیشه پیش از استفاده از حالت‌های import یا export کارهای کامیت‌نشده خود را کامیت یا stash کنید، و سپس پیش از ارسال تغییرات به مخازن دوردست، نتیجه مهاجرت را اعتبارسنجی نمایید، برای مثال با اجرای حالت info و بررسی تاریخچه بازنویسی‌شده کامیت‌ها.

هنگامی که از تغییرات رضایت داشتید، باید تاریخچه جدید Git شاخه‌های بازنویسی‌شده را با force-push به تمام مخازن دوردست خود ارسال کنید. این مرحله‌ای است که باید با دقت انجام شود، زیرا تاریخچه Git را در مخازن دوردست خود دگرگون خواهید کرد.

برای بررسی یا تغییر فایل‌ها در شاخه‌هایی غیر از شاخه بررسی‌شده فعلی، می‌توان ارجاعات شاخه را مستقیماً مشخص کرد، یا در یک یا چند گزینه --include-ref ارائه نمود. همچنین می‌توان آن‌ها را با افزودن پیشوند ^ یا مشخص کردن در گزینه‌های --exclude-ref مستثنی کرد. از گزینه --everything استفاده کنید تا مشخص شود تمام ارجاعات، از جمله تمام ارجاعات دوردست باید بررسی شوند. برای جزئیات به بخش «شامل کردن و مستثنی کردن ارجاعات (INCLUDE AND EXCLUDE REFERENCES)» مراجعه کنید.

برای حالت‌های info و import، تمام انواع فایل‌ها به طور پیش‌فرض در نظر گرفته می‌شوند؛ در حالی که این ویژگی در حالت info مفید است، اغلب هنگام وارد کردن (import) مطلوب نیست، بنابراین در این مورد معمولاً باید الگوهای نام فایل (pathspec) یا گزینه --fixup مشخص شوند. (حداقل یک pathspec برای شامل کردن در حالت export الزامی است.) الگوهای مسیر را می‌توان با استفاده از گزینه‌های --include و --exclude (به اختصار -I و -X) تعریف کرد، همان‌طور که در بخش «شامل کردن و مستثنی کردن (INCLUDE AND EXCLUDE)» توضیح داده شده است.

از آنجا که استفاده معمول از Git LFS به ردیابی انواع فایل خاص با استفاده از الگوهای نام فایل تعریف‌شده در فایل‌های .gitattributes وابسته است، دستور git lfs migrate فایل‌های .gitattributes را در صورت لزوم بررسی، ایجاد و اصلاح خواهد کرد. فایل‌های .gitattributes همیشه با مجوز پیش‌فرض خواندن/نوشتن (یعنی بدون مجوز اجرا) اختصاص داده می‌شوند. هر پیوند نمادین (symbolic link) با این نام باعث توقف زودهنگام فرآیند مهاجرت خواهد شد.

حالت import (به بخش «IMPORT» مراجعه کنید) اشیاء Git از انواع فایل مشخص‌شده (مثلاً با --include) را به اشاره‌گرهای Git LFS تبدیل کرده و مدخل‌هایی برای آن انواع فایل به فایل‌های .gitattributes اضافه می‌کند، و در صورت عدم وجود این فایل‌ها، آن‌ها را ایجاد می‌نماید. نتیجه باید همانند این باشد که دستورات git lfs track در نقاطی از تاریخچه Git شما متناظر با جایی که هر نوع فایل تبدیل‌شده برای اولین بار ظاهر شده است، اجرا شده باشند. استثناء زمانی است که گزینه --fixup داده شود، که در این صورت حالت import فقط فایل‌های موجود .gitattributes را بررسی کرده و سپس اشیاء Git را که باید توسط Git LFS ردیابی شوند اما هنوز ردیابی نشده‌اند، تبدیل می‌کند.

حالت export (به بخش «EXPORT» مراجعه کنید) به عنوان عملیات معکوس برای حالت import عمل می‌کند، و هر اشاره‌گر Git LFS را که با انواع فایل مشخص‌شده با --include مطابقت دارد (که باید حداقل یک بار داده شود) تبدیل می‌نماید. توجه داشته باشید که مدخل‌های .gitattributes حذف نخواهند شد، و فایل‌ها نیز حذف نمی‌شوند؛ در عوض، حالت export مدخل‌های «ردیابی نشود» مشابه آنچه توسط دستور git lfs untrack ایجاد می‌شود درج می‌کند. گزینه --remote در حالت export برای مشخص کردن مخزن دوردستی که اشیاء Git LFS در صورت عدم وجود در حافظه نهان محلی LFS باید از آن واکشی شوند، در دسترس است؛ در صورت عدم ارائه، origin به طور پیش‌فرض استفاده می‌شود.

حالت info (به بخش «INFO» مراجعه کنید) تعداد کل و اندازه فایل‌ها را در یک مخزن بر اساس نوع فایل (یعنی بر اساس پسوند نام فایل) خلاصه می‌کند. توجه داشته باشید که همانند دو حالت دیگر، به طور پیش‌فرض حالت info فقط روی شاخه بررسی‌شده فعلی و فقط روی کامیت‌هایی که در هیچ مخزن دوردستی وجود ندارند عمل می‌کند، بنابراین برای دریافت خلاصه‌ای از کل مخزن در تمام شاخه‌ها، از گزینه --everything استفاده کنید. اگر اشیاء قبلاً به اشاره‌گرهای Git LFS تبدیل شده باشند، به طور پیش‌فرض اندازه اشیاء ارجاع‌شده جمع‌بندی شده و به طور جداگانه گزارش می‌شود. همچنین می‌توانید با استفاده از --pointers=ignore آن‌ها را نادیده بگیرید یا با استفاده از --pointers=no-follow با اشاره‌گرها مانند فایل رفتار کنید. (گزینه دوم مشابه نحوه برخورد با اشاره‌گرهای موجود Git LFS توسط حالت info در نسخه‌های پیشین Git LFS است).

هنگام استفاده از گزینه --everything، توجه داشته باشید که این به معنای در نظر گرفتن تمام کامیت‌های در دسترس از تمام ارجاعات (محلی و دوردست) است، اما لزوماً شامل همه انواع فایل نمی‌شود. حالت‌های import و info به طور پیش‌فرض همه انواع فایل را در نظر می‌گیرند، اگرچه گزینه‌های --include و --exclude این رفتار را محدود می‌کنند.

اگرچه گزینه --everything به این معناست که تمام کامیت‌های در دسترس از هر ارجاعی برای مهاجرت در نظر گرفته می‌شوند، اما پس از مهاجرت حتی در صورت مشخص شدن --everything فقط ارجاعات محلی به‌روزرسانی خواهند شد. این امر همگام ماندن ارجاعات دوردست با مخزن دوردست مربوطه‌شان را تضمین می‌کند. به عبارت دیگر، refs/heads/foo با گزینه --everything به‌روزرسانی خواهد شد، اما refs/remotes/origin/foo به‌روزرسانی نخواهد شد، بنابراین تا زمانی که git push origin foo انجام نشود، با دوردست همگام می‌ماند. پس از بررسی اینکه نتایج یک مهاجرت با --everything رضایت‌بخش است، ارسال تمام شاخه‌های محلی به مخازن دوردست با استفاده از گزینه --all در دستور git push می‌تواند راحت باشد.

مگر اینکه گزینه --skip-fetch داده شده باشد، git lfs migrate همیشه با واکشی فهرست‌های به‌روزشده ارجاعات از تمام مخازن دوردست بازگردانده‌شده توسط git remote آغاز می‌شود، اما همان‌طور که در بالا ذکر شد، پس از اعمال تغییرات در تاریخچه محلی Git در حین تبدیل اشیاء، هرگز آن تغییرات را به طور خودکار به مخازن دوردست شما ارسال نخواهد کرد.

info

نمایش اطلاعات درباره اندازه مخزن. به بخش «INFO» مراجعه کنید.

import

تبدیل اشیاء Git به اشاره‌گرهای Git LFS. به بخش‌های «IMPORT» و «وارد کردن بدون بازنویسی تاریخچه (IMPORT WITHOUT REWRITING HISTORY)» مراجعه کنید.

export

تبدیل اشاره‌گرهای Git LFS به اشیاء Git. به بخش «EXPORT» مراجعه کنید.

-I <paths>, --include=<paths>

به بخش «شامل کردن و مستثنی کردن (INCLUDE AND EXCLUDE)» مراجعه کنید.

-X <paths>, --exclude=<paths>

به بخش «شامل کردن و مستثنی کردن (INCLUDE AND EXCLUDE)» مراجعه کنید.

--include-ref=<refname>

به بخش «شامل کردن و مستثنی کردن ارجاعات (INCLUDE AND EXCLUDE REFERENCES)» مراجعه کنید.

--exclude-ref=<refname>

به بخش «شامل کردن و مستثنی کردن ارجاعات (INCLUDE AND EXCLUDE REFERENCES)» مراجعه کنید.

--skip-fetch

فرض می‌کند که مجموعه ارجاعات دوردست شناخته‌شده کامل است، و هنگام تعیین مجموعه کامیت‌های «ارسال‌نشده» برای مهاجرت نباید تازه‌سازی شود. در صورت ترکیب با --include-ref یا --exclude-ref هیچ تاثیری ندارد.

--everything

به بخش «شامل کردن و مستثنی کردن ارجاعات (INCLUDE AND EXCLUDE REFERENCES)» مراجعه کنید.

نکته: ارجاعات Git در تمام پلتفرم‌ها در حالت «بسته‌بندی‌شده (packed form)» به حروف کوچک و بزرگ حساس هستند (حساس به بزرگی و کوچکی حروف؛ به git-pack-refs(1) مراجعه کنید). در سیستم‌های فایلی که به حروف حساس نیستند، مانند NTFS در ویندوز یا APFS پیش‌فرض در macOS، دستور git-lfs-migrate(1) در صورتی که دو یا چند ارجاع فقط از نظر حروف کوچک/بزرگ متفاوت باشند، فقط اولین ارجاع را مهاجرت می‌دهد.

--yes

پاسخ بله را به تمام پرسش‌ها فرض می‌کند و امکان استفاده غیرتعاملی را فراهم می‌سازد. در حال حاضر، تنها پرسش از این دست، پرسشی است که می‌پرسد آیا تغییرات نسخه کاری بازنویسی (نابود) شوند یا خیر. بنابراین، مشخص کردن این گزینه در صورت عدم دقت ممکن است باعث از دست رفتن داده‌ها شود.

[branch ...]

فقط مجموعه شاخه‌های فهرست‌شده را مهاجرت می‌دهد. در صورت عدم ارائه، git-lfs-migrate(1) شاخه فعلی بررسی‌شده را مهاجرت خواهد داد.

ارجاعاتی که با ^ شروع می‌شوند مستثنی خواهند شد، در حالی که شاخه‌هایی که با ^ شروع نمی‌شوند شامل می‌شوند.

اگر هر یک از گزینه‌های --include-ref یا --exclude-ref داده شوند، شاخه بررسی‌شده افزوده نمی‌شود، اما شاخه‌هایی که به صراحت داده شده‌اند اضافه خواهند شد.

حالت info اندازه‌های اشیاء فایل موجود در تاریخچه Git را خلاصه می‌کند. این حالت از تمام گزینه‌های اصلی migrate و گزینه‌های اضافی زیر پشتیبانی می‌کند:

--above=<size>

فقط فایل‌هایی را شمارش می‌کند که اندازه مجزای آن‌ها بالاتر از اندازه داده‌شده باشد. size می‌تواند به صورت تعداد بایت، یا یک عدد به همراه یک واحد ذخیره‌سازی مشخص شود، مانند "1b"، "20 MB"، "3 TiB" و غیره.

اگر در مجموعه‌ای از فایل‌ها با پسوند یکسان، هیچ فایلی وجود نداشته باشد که اندازه مجزای آن بالاتر از حد مشخص‌شده در --above باشد، هیچ مدخلی برای آن مجموعه نمایش داده نخواهد شد.

--top=<n>

فقط n مدخل برتر را نمایش می‌دهد که بر اساس تعداد کل فایل‌های منطبق با الگوی ارائه‌شده مرتب شده‌اند. پیش‌فرض نمایش فقط ۵ مدخل برتر است. هنگامی که اشیاء موجود Git LFS یافت شوند، علاوه بر n مدخل برتر، یک خط جداگانه و اضافی "LFS Objects" در خروجی نمایش داده می‌شود، مگر اینکه از گزینه --pointers برای تغییر این رفتار استفاده شود.

--unit=<unit>

تعداد بایت‌ها در هر مدخل را در قالب مقداری از واحد ذخیره‌سازی ارائه‌شده قالب‌بندی می‌کند. واحدهای معتبر عبارتند از:
•b، kib، mib، gib، tib، pib - برای واحدهای ذخیره‌سازی IEC
•b، kb، mb، gb، tb، pb - برای واحدهای ذخیره‌سازی SI

اگر --unit مشخص نشده باشد، بزرگ‌ترین واحدی که بتواند تعداد بایت‌های شمارش‌شده را به صورت یک مقدار عدد صحیح نمایش دهد انتخاب می‌شود.

--pointers=[follow|no-follow|ignore]

با اشاره‌گرهای موجود Git LFS در تاریخچه بر اساس یکی از سه گزینه رفتار می‌کند. در حالت پیش‌فرض follow، اگر هرگونه اشاره‌گری یافت شود، یک سطر مجزای اضافی "LFS Objects" در خروجی نمایش می‌یابد که تعداد کل و اندازه اشیاء Git LFS ارجاع‌شده توسط اشاره‌گرها را خلاصه می‌کند. در حالت ignore، اشاره‌گرها نادیده گرفته می‌شوند، در حالی که حالت no-follow رفتار حالت info در نسخه‌های قدیمی‌تر Git LFS را تکرار می‌کند و با هر اشاره‌گری که بیابد مانند یک فایل معمولی رفتار می‌کند، بنابراین مجموع‌های خروجی فقط شامل محتویات اشاره‌گرها خواهند بود، نه محتویات اشیایی که به آن‌ها اشاره دارند.

--fixup

فیلترهای --include و --exclude را بر اساس فایل‌های .gitattributes در یک مخزن، به ازای هر کامیت استنتاج می‌کند. در عمل، این گزینه هر مسیر فایلی را که طبق فایل(های) .gitattributes مخزن باید توسط Git LFS ردیابی شود اما هنوز به اشاره‌گر تبدیل نشده است، شمارش می‌کند. برخلاف خروجی معمول حالت info، فایل‌های .gitattributes گزارش نمی‌شوند. این گزینه با فیلترهای صریح --include و --exclude و با هر تنظیم --pointers به جز ignore ناسازگار است، از این رو در صورت عدم تعیین صریح، --fixup مستلزم --pointers=ignore است.

قالب خروجی، الگوی نام فایل، اندازه کل اشیاء فایل (به استثنای مواردی که کمتر از آستانه --above هستند، در صورتی که تعریف شده باشد) و نسبت تعداد فایل‌های بالاتر از آستانه به تعداد کل فایل‌ها را نشان می‌دهد؛ این نسبت به صورت درصد نیز نمایش داده می‌شود. برای مثال:

*.gif               93 MB   9480/10504 files(s)  90%
*.png               14 MB    1732/1877 files(s)  92%

به طور پیش‌فرض فقط پنج مدخل اول نمایش داده می‌شوند، اما گزینه --top امکان نمایش تعداد بیشتر یا کمتری را در صورت تمایل فراهم می‌سازد.

حالت import اشیاء موجود در تاریخچه Git را به فایل‌های اشاره‌گر ردیابی‌شده و ذخیره‌شده با Git LFS مهاجرت می‌دهد. این حالت از تمام گزینه‌های اصلی migrate و این گزینه‌های اضافی پشتیبانی می‌کند:

--verbose

شناسه oid کامیت و نام فایل‌های مهاجرت‌داده‌شده را در STDOUT چاپ می‌کند.

--above=<size>

فقط فایل‌هایی را مهاجرت می‌دهد که اندازه مجزای آن‌ها بالاتر از اندازه داده‌شده باشد. size می‌تواند به صورت تعداد بایت، یا یک عدد به همراه یک واحد ذخیره‌سازی مشخص شود، مانند "1b"، "20 MB"، "3 TiB" و غیره. از این گزینه نمی‌توان همراه با گزینه‌های --include، --exclude، و --fixup استفاده کرد.

--object-map=<path>

فایلی با نگاشت هر یک از کامیت‌های بازنویسی‌شده را در path می‌نویسد. قالب فایل CSV با این الگو است: OLD-SHA,NEW-SHA

--no-rewrite

اشیاء را در یک کامیت جدید به Git LFS مهاجرت می‌دهد بدون اینکه تاریخچه Git بازنویسی شود. لطفاً توجه داشته باشید که با استفاده از این گزینه، دستور migrate import انتظار فهرست متفاوتی از آرگومان‌ها را خواهد داشت، گزینه‌های تخصصی در دسترس قرار می‌گیرند، و گزینه‌های اصلی migrate نادیده گرفته می‌شوند. به بخش «وارد کردن بدون بازنویسی تاریخچه (IMPORT WITHOUT REWRITING HISTORY)» مراجعه کنید.

--fixup

فیلترهای --include و --exclude را بر اساس فایل‌های .gitattributes در یک مخزن، به ازای هر کامیت استنتاج می‌کند. در عمل، این گزینه هر مسیر فایلی را که طبق فایل(های) .gitattributes مخزن باید توسط Git LFS ردیابی شود اما هنوز اشاره‌گر نیست وارد می‌کند. این گزینه با فیلترهای صریح --include و --exclude ناسازگار است.

اگر --no-rewrite داده نشود و گزینه‌های --include یا --exclude (به ترتیب -I و -X) داده شوند، فایل .gitattributes برای گنجاندن هرگونه الگوی جدید مسیر فایل مطابق با آن فلگ‌ها اصلاح خواهد شد.

اگر --no-rewrite داده نشود و هیچ‌یک از این فلگ‌ها داده نشوند، gitattributes به صورت افزایشی اصلاح خواهد شد تا پسوندهای مسیر فایل جدید را همان‌طور که در تاریخچه بازنویسی می‌شوند شامل شود.

حالت import دارای یک زیرحالت ویژه است که با فلگ --no-rewrite فعال می‌شود. این زیرحالت مانند حالت پایه import اشیاء را به اشاره‌گرها مهاجرت می‌دهد، اما این کار را در یک کامیت جدید بدون بازنویسی تاریخچه Git انجام می‌دهد. هنگام استفاده از این زیرحالت، گزینه‌های اصلی migrate مانند --include-ref، و همچنین گزینه‌های حالت اصلی import نادیده گرفته خواهند شد. دستور migrate همچنین فهرست متفاوتی از آرگومان‌ها را می‌پذیرد. در نتیجه این تغییرات، --no-rewrite فقط روی شاخه فعلی کار خواهد کرد - هر شاخه دیگری که علاقه‌مند به این تغییرات باشد باید کامیت تولیدشده را با خود ادغام کند.

زیرحالت --no-rewrite از گزینه‌ها و آرگومان‌های زیر پشتیبانی می‌کند:

-m <message>, --message=<message>

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

[file ...]

فهرست فایل‌ها برای وارد کردن. این فایل‌ها باید توسط الگوهای مشخص‌شده در gitattributes ردیابی شوند.

اگر --message داده شود، کامیت جدید با پیام ارائه‌شده ایجاد می‌شود. اگر پیامی ارائه نشود، پیام کامیت بر اساس آرگومان‌های فایل تولید خواهد شد.

حالت export فایل‌های اشاره‌گر Git LFS موجود در تاریخچه Git را از Git LFS خارج کرده و آن‌ها را به فایل‌های شیء متناظرشان تبدیل می‌کند. این حالت از تمام گزینه‌های اصلی migrate و این گزینه‌های اضافی پشتیبانی می‌کند:

--verbose

شناسه oid کامیت و نام فایل‌های مهاجرت‌داده‌شده را در STDOUT چاپ می‌کند.

--object-map=<path>

فایلی با نگاشت هر یک از کامیت‌های بازنویسی‌شده را در path می‌نویسد. قالب فایل CSV با این الگو است: OLD-SHA,NEW-SHA

--remote=<git-remote>

در حین عملیات export اشیاء LFS را از git-remote مشخص‌شده دانلود می‌کند. در صورت عدم ارائه، به صورت پیش‌فرض origin در نظر گرفته می‌شود.

حالت export حداقل به یک الگوی مشخص‌شده با آرگومان --include نیاز دارد تا مشخص شود کدام فایل‌ها باید export شوند. فایل‌هایی که با الگوهای --include مطابقت دارند از Git LFS حذف خواهند شد، در حالی که فایل‌های منطبق با الگوهای --exclude وضعیت Git LFS خود را حفظ می‌کنند. دستور export فایل .gitattributes را برای تنظیم یا لغو تنظیم هرگونه الگوی مسیر فایل طبق آن فلگ‌ها اصلاح خواهد کرد.

می‌توانید مشخص کنید که git lfs migrate فقط فایل‌هایی را تبدیل کند که تطبیق مسیر آن‌ها (pathspec) با الگوهای گلوب (glob) گزینه --include مطابقت دارد و با الگوهای --exclude مطابقت ندارد، تا یا زمان کل مهاجرت کاهش یابد یا فقط بخشی از مخزن شما مهاجرت داده شود. می‌توان چندین الگو را با استفاده از کاما به عنوان جداکننده مشخص کرد.

تطبیق الگو به گونه‌ای انجام می‌شود که از نظر عملکردی معادل قالب تطبیق الگو در .gitattributes باشد. علاوه بر تطبیق ساده پسوند فایل (مثلاً .gif)، الگوها همچنین می‌توانند مسیرهای دایرکتوری را مشخص کنند که در این صورت می‌توان از قالب path/* برای تطبیق بازگشتی استفاده کرد.

توجه داشته باشید که این شیوه تطبیق الگو برای گزینه‌های --include و --exclude مورد استفاده در دستور git lfs migrate، در بین مجموعه‌دستورات git lfs منحصر‌به‌فرد است. سایر دستوراتی که این گزینه‌ها را می‌پذیرند، مانند git lfs ls-files، در عوض از شکل تطبیق الگوی gitignore(5) استفاده می‌کنند.

می‌توانید مشخص کنید که git lfs migrate فقط فایل‌های اضافه‌شده در کامیت‌های در دسترس از ارجاعات خاص را تبدیل کند، یعنی ارجاعاتی که با استفاده از یک یا چند گزینه --include-ref تعریف شده‌اند، و فایل‌های موجود در کامیت‌های در دسترس از ارجاعات تعریف‌شده در گزینه‌های --exclude-ref را نادیده بگیرد.

      D---E---F
     /         \
A---B------C    refs/heads/my-feature
 \          \
  \          refs/heads/main
   \
    refs/remotes/origin/main

در پیکربندی بالا، کامیت‌های زیر توسط هر ارجاع قابل دسترسی هستند:

refs/heads/main:           C, B, A
refs/heads/my-feature:     F, E, D, B, A
refs/remote/origin/main:   A

بنابراین، گزینه‌های زیر در git lfs migrate کامیت‌های F، E، D، C، و B را شامل شده، اما کامیت A را مستثنی می‌کنند:

--include-ref=refs/heads/my-feature
--include-ref=refs/heads/main
--exclude-ref=refs/remotes/origin/main

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

یک کاربرد متداول برای دستور migrate، تبدیل اشیاء بزرگ Git به LFS پیش از ارسال (push) کامیت‌های شما است. به طور پیش‌فرض، تا زمانی که مخزن non-bare باشد، فقط کامیت‌هایی را اسکن می‌کند که در هیچ مخزن دوردستی وجود ندارند.

ابتدا، git lfs migrate info را اجرا کنید تا انواعی از فایل‌ها را که بیشترین فضا را در مخزن شما اشغال کرده‌اند فهرست کند:

$ git lfs migrate info
Fetching remote refs: ..., done
Sorting commits: ..., done
Examining commits: 100% (1/1), done
*.mp3   284 MB    1/1 files(s)  100%
*.pdf   42 MB     8/8 files(s)  100%
*.psd   9.8 MB  15/15 files(s)  100%
*.ipynb 6.9 MB    6/6 files(s)  100%
*.csv   5.8 MB    2/2 files(s)  100%

اکنون، می‌توانید git lfs migrate import را برای تبدیل برخی از انواع فایل به LFS اجرا کنید:

$ git lfs migrate import --include="*.mp3,*.psd"
Fetching remote refs: ..., done
Sorting commits: ..., done
Rewriting commits: 100% (1/1), done
  main  d2b959babd099fe70da1c1512e2475e8a24de163 -> 136e706bf1ae79643915c134e17a6c933fd53c61
Updating refs: ..., done

اگر پس از تبدیل متوجه شدید که برخی از فایل‌ها در دایرکتوری کاری شما با اشاره‌گرهای Git LFS جایگزین شده‌اند، این امری طبیعی است و نسخه‌های کاری این فایل‌ها را می‌توان با استفاده از git lfs checkout مجدداً با محتویات کامل مورد انتظار پر کرد.

همچنین می‌توانید کل تاریخچه مخزن خود را مهاجرت دهید:

# بررسی فایل‌های بزرگ و اشیاء موجود Git LFS در شاخه اصلی محلی
$ git lfs migrate info --include-ref=main
# بررسی فایل‌های بزرگ و اشیاء موجود Git LFS در تمام شاخه‌ها
$ git lfs migrate info --everything
# بررسی فایل‌های بزرگ در تمام شاخه‌ها با نادیده گرفتن اشیاء موجود Git LFS،
# و فهرست کردن ۱۰۰ نتیجه برتر یا کمتر
$ git lfs migrate info --everything --pointers=ignore --top=100

همین فلگ‌ها در حالت import نیز کار خواهند کرد:

# تبدیل تمام فایل‌های zip در شاخه اصلی شما
$ git lfs migrate import --include-ref=main --include="*.zip"
# تبدیل تمام فایل‌های zip در تمام شاخه‌های محلی
$ git lfs migrate import --everything --include="*.zip"
# تبدیل تمام فایل‌های بزرگتر از 100K در تمام شاخه‌های محلی
$ git lfs migrate import --everything --above=100Kb

نکته: این کار نیازمند force-push به تمام مخازن دوردست موجود Git خواهد بود. استفاده از گزینه --all هنگام force-push در صورتی که ارجاعات محلی متعددی به‌روزرسانی شده باشند (مثلاً پس از import به Git LFS با گزینه --everything) می‌تواند راحت باشد.

شما همچنین می‌توانید فایل‌ها را بدون اصلاح تاریخچه موجود مخزن خود مهاجرت دهید.

مهاجرت به Git LFS در یک کامیت منفرد و جدید، بدون مشخص کردن پیام کامیت:

$ git lfs track "*.zip" "*.mp3" "*.psd"
$ git add .gitattributes
$ git commit -m "add Git LFS attributes"
$ git lfs migrate import --no-rewrite --yes test.zip audios/*.mp3 images/*.psd

توجه داشته باشید که الگوهای نام فایل .mp3 و .psd داخل نقل‌قول (کوتیشن) قرار نگرفته‌اند و بنابراین توسط شل (shell) بسط داده می‌شوند، نه توسط دستور git lfs migrate import. برای جزئیات بیشتر به توضیحات پس از مثال بعدی مراجعه کنید.

مهاجرت به Git LFS در یک کامیت منفرد و جدید، با یک پیام کامیت مشخص:

$ git lfs track "*.zip" "*.mp3" "*.psd"
$ git add .gitattributes
$ git commit -m "add Git LFS attributes"
$ git lfs migrate import --no-rewrite --yes \
  -m "Import test.zip, audios/*.mp3, and images/*.psd files" \
  test.zip audios/*.mp3 images/*.psd

توجه داشته باشید که الگوهای نام فایل .mp3 و .psd داخل نقل‌قول قرار نگرفته‌اند و بنابراین توسط شل بسط داده می‌شوند، نه توسط دستور git lfs migrate import. استفاده از علامت نقل‌قول در اطراف چنین الگوهایی با گزینه --no-rewrite پشتیبانی نمی‌شود، زیرا این دستور انتظار فهرستی از فایل‌ها را دارد (احتمالاً بسط داده‌شده توسط شل) و تمام فایل‌های منطبق با یک الگوی نام فایل نقل‌قول‌شده را جستجو نخواهد کرد.

البته می‌توان از دستورات اضافی برای یافتن و فهرست کردن تمام فایل‌های منطبق با مجموعه‌ای از الگوها استفاده کرد. در یک محیط سازگار با POSIX مانند لینوکس، macOS یا Git Bash در ویندوز، مثال بالا را می‌توان با دستورات find(1) و sed(1) به شرح زیر ترکیب کرد، مشروط بر اینکه فهرست فایل‌های حاصل باعث نشود طول خط فرمان بسط‌یافته از حداکثر مجاز توسط شل فراتر رود:

$ git lfs migrate import --no-rewrite --yes \
  $(find . -name "*.zip" -o -name "*.mp3" -o -name "*.psd" | sed "s/^\.\///")

همچنین توجه داشته باشید که دستور git lfs track به طور پیش‌فرض برچسب‌های زمانی اصلاح را روی هر فایل موجود که با الگوهای نام فایل داده‌شده مطابقت دارد تغییر می‌دهد، به طوری که فایل‌ها در نظر Git به عنوان «تغییریافته» (dirty) ظاهر می‌شوند و در نتیجه کاربر را به تبدیل آن‌ها به فایل‌های Git LFS ترغیب می‌کنند. سپس دستور بعدی git lfs migrate import هشدار می‌دهد که درخت کاری حاوی تغییرات است و از کاربر تایید می‌خواهد تا ادامه دهد، مگر اینکه گزینه --yes مشخص شده باشد، همانند مثال‌های بالا.

به عنوان جایگزینی برای استفاده از git lfs migrate import با گزینه --no-rewrite جهت مهاجرت فایل‌ها به Git LFS بدون تغییر تاریخچه موجود مخزن، اگر Git نسخه 2.16.0 یا بالاتر را نصب دارید، می‌توانید از گزینه --renormalize در دستور git add برای دستیابی به همین نتیجه استفاده کنید. به عنوان مثال:

$ git lfs track "*.zip" "*.mp3" "*.psd"
$ git add .gitattributes
$ git add --renormalize .
$ git commit -m "Import all *.zip, *.mp3, and *.psd files to Git LFS"

اگر دیگر تمایلی به استفاده از Git LFS برای برخی یا تمام فایل‌های خود ندارید، می‌توانید از حالت export برای تبدیل مجدد اشیاء Git LFS به blobهای معمولی Git استفاده کنید.

حالت export حداقل به یک pathspec با --include نیاز دارد، و هر شیئی را که به صورت محلی یافت نشود از مخزن دوردست Git با نام origin شما یا از مخزن دوردستی که با گزینه --remote مشخص می‌کنید دانلود خواهد کرد.

# تبدیل تمام اشیاء Git LFS نوع zip به فایل در شاخه اصلی شما
$ git lfs migrate export --include-ref=main --include="*.zip"
# تبدیل تمام اشیاء Git LFS نوع zip به فایل در تمام شاخه‌های محلی،
# و واکشی داده‌های اشیایی که به صورت محلی کش نشده‌اند از مخزن دوردست my-remote
$ git lfs migrate export --everything --include="*.zip" --remote=my-remote
# تبدیل تمام اشیاء Git LFS به فایل در تمام شاخه‌های محلی
$ git lfs migrate export --everything --include="*"

نکته: این کار نیازمند force-push به تمام مخازن دوردست موجود Git خواهد بود. استفاده از گزینه --all هنگام force-push در صورتی که ارجاعات محلی متعددی به‌روزرسانی شده باشند (مثلاً پس از export از Git LFS با گزینه --everything) می‌تواند راحت باشد.

git-lfs-checkout(1), git-lfs-ls-files(1), git-lfs-track(1), git-lfs-untrack(1), gitattributes(5), gitignore(5).

بخشی از مجموعه git-lfs(1).