українська мова ▾ Topics ▾ Latest version ▾ git-fast-import last updated in 2.51.0

НАЗВА

git-fast-import - Бекенд для швидких імпортерів даних Git

СИНОПСИС

frontend | git fast-import [<options>]

ОПИС

Зазвичай кінцевий користувач не хоче запускати цю програму безпосередньо. Більшість кінцевих користувачів хочуть використовувати одну з існуючих фронтенд-програм, яка аналізує певний тип зовнішнього джерела та передає вміст, що там зберігається, до «git fast-import».

fast-import зчитує змішаний потік команд/даних зі стандартного вводу та записує один або декілька pack-файлів безпосередньо в поточний репозиторій. Коли EOF отримується на стандартний ввод, fast-import записує оновлені посилання на гілки та теги, повністю оновлюючи поточний репозиторій щойно імпортованими даними.

Сам бекенд швидкого імпорту може імпортувати дані в порожній репозиторій (той, який вже був ініціалізований за допомогою git init) або інкрементально оновлювати існуючий заповнений репозиторій. Підтримка інкрементального імпорту з конкретного зовнішнього джерела залежить від використовуваної фронтенд-програми.

ОПЦІЇ

--force

Примусово оновлювати змінені існуючі гілки, навіть якщо це призведе до втрати комітів (оскільки новий коміт не містить старого).

--quiet

Вимкнути вивід, що відображається за допомогою --stats, що зазвичай робить fast-import беззвучним у разі успішного виконання. Однак, якщо потік імпорту містить директиви, призначені для відображення виводу користувача (наприклад, директиви progress), відповідні повідомлення все одно відображатимуться.

--stats

Відображає деяку основну статистику про об’єкти, створені fast-import, пакетні файли, в яких вони були збережені, та пам’ять, використану fast-import під час цього запуску. Відображення цього виводу наразі є типовим, але його можна вимкнути за допомогою --quiet.

--allow-unsafe-features

Багато параметрів командного рядка можна надати як частину самого потоку швидкого імпорту за допомогою команд feature або option. Однак деякі з цих параметрів є небезпечними (наприклад, дозволяючи швидкому імпорту отримувати доступ до файлової системи поза репозиторієм). Ці параметри вимкнено за замовчуванням, але їх можна дозволити, надавши цей параметр у командному рядку. Наразі це впливає лише на команди функцій export-marks, import-marks та import-marks-if-exists.

Увімкніть цю опцію, лише якщо ви довіряєте програмі, яка генерує потік швидкого імпорту! Ця опція вмикається автоматично для віддалених помічників, які використовують можливість `імпорту`, оскільки їм вже довірено виконувати власний код.

Варіанти для фронтендів

--cat-blob-fd=<fd>

Записувати відповіді на запити get-mark, cat-blob та ls у файловий дескриптор <fd> замість stdout. Дозволяє відокремити вивід progress, призначений для кінцевого користувача, від інших виводів.

--date-format=<fmt>

Вкажіть тип дат, які фронтенд надаватиме для швидкого імпорту, в командах author, committer та tagger. Див. розділ “Формати дат” нижче для отримання детальної інформації про підтримувані формати та їхній синтаксис.

--done

Завершити з помилкою, якщо в кінці потоку немає команди done. Ця опція може бути корисною для виявлення помилок, які призводять до завершення роботи фронтенду до початку запису потоку.

Розташування файлів Marks

--export-marks=<file>

Згенерує внутрішню таблицю позначок у <file> після завершення. Позначки записуються по одній на рядок як :markid SHA-1. Фронтенди можуть використовувати цей файл для перевірки імпорту після його завершення або для збереження таблиці позначок під час інкрементальних запуску. Оскільки <file> відкривається та обрізається лише на контрольній точці (або завершенні), той самий шлях також можна безпечно надати --import-marks.

--import-marks=<file>

Перед обробкою будь-яких вхідних даних завантажте позначки, зазначені у <файл>. Вхідний файл має існувати, бути читабельним та використовувати той самий формат, що й створений за допомогою --export-marks. Для імпорту кількох наборів позначок можна вказати кілька параметрів. Якщо позначка визначена з різними значеннями, перевагу має останній файл.

--import-marks-if-exists=<file>

Подібно до --import-marks, але замість виведення помилки, файл не існує, якщо він не існує.

--[no-]relative-marks

Після вказівки --relative-marks шляхи, вказані за допомогою --import-marks= та --export-marks=, будуть відносними до внутрішнього каталогу в поточному репозиторії. У git-fast-import це означає, що шляхи будуть відносними до каталогу .git/info/fast-import. Однак інші імпортери можуть використовувати інше розташування.

Відносні та невідносні позначки можна комбінувати шляхом переплетення — (no-)-relative-marks з опціями — (import|export)-marks=.

Переписування підмодулів

--rewrite-submodules-from=<name>:<file>
--rewrite-submodules-to=<name>:<file>

Перепишіть ідентифікатори об’єктів для підмодуля, вказаного <name>, зі значень, що використовуються у from <file>, на ті, що використовуються у to <file>. Мітки from мали бути створені за допомогою git fast-export, а позначки to мали бути створені за допомогою git fast-import під час імпорту того ж підмодуля.

<name> може бути будь-яким довільним рядком, що не містить символу двокрапки, але однакове значення має використовуватися з обома опціями при визначенні відповідних позначок. Можна вказати кілька підмодулів з різними значеннями для <name>. Не використовувати ці опції у відповідних парах є помилкою.

Ці опції корисні в першу чергу під час конвертації репозиторію з одного алгоритму хешування на інший; без них швидкий імпорт завершиться невдачею, якщо зіткнеться з підмодулем, оскільки не матиме можливості записати ідентифікатор об’єкта в новий алгоритм хешування.

Налаштування продуктивності та стиснення

--active-branches=<n>

Максимальна кількість гілок, які потрібно підтримувати активними одночасно. Див. розділ «Використання пам’яті» нижче для отримання детальної інформації. Значення за замовчуванням — 5.

--big-file-threshold=<n>

Максимальний розмір блобу, для якого швидкий імпорт спробує створити дельту, виражений у байтах. Значення за замовчуванням — 512 м (512 МіБ). Деякі імпортери можуть забажати зменшити це значення на системах з обмеженою пам’яттю.

--depth=<n>

Максимальна глибина дельти для дельтифікації блобів та дерев. Значення за замовчуванням – 50.

--export-pack-edges=<file>

Після створення пакетного файлу виведіть рядок даних до <file>, в якому буде перераховано ім’я пакетного файлу та останній коміт у кожній гілці, який був записаний у цей пакетний файл. Ця інформація може бути корисною після імпорту проектів, загальний набір об’єктів яких перевищує ліміт пакетного файлу в 4 ГіБ, оскільки ці коміти можуть бути використані як граничні точки під час викликів git pack-objects.

--max-pack-size=<n>

Максимальний розмір кожного вихідного пакетного файлу. Значення за замовчуванням — необмежене.

fastimport.unpackLimit

Див. git-config[1]

ПРОДУКТИВНІСТЬ

Конструкція fast-import дозволяє імпортувати великі проекти з мінімальним використанням пам’яті та часом обробки. Якщо припустити, що фронтенд здатний встигати за fast-import та забезпечувати його постійним потоком даних, час імпорту для проектів, що мають понад 10 років історії та містять понад 100 000 окремих змін, зазвичай виконується всього за 1-2 години на досить скромному обладнанні (~2000 доларів США у 2007 році).

Більшість вузьких місць, схоже, пов’язані з доступом до даних зовнішнього джерела (джерело просто не може достатньо швидко витягувати версії) або з операціями вводу-виводу на диск (швидкий імпорт записує так само швидко, як диск приймає дані). Імпорт виконуватиметься швидше, якщо вихідні дані зберігаються на іншому диску, ніж цільовий репозиторій Git (через меншу конкуренцію за операції вводу-виводу).

ВАРТІСТЬ РОЗРОБКИ

Типовий фронтенд для швидкого імпорту зазвичай важить приблизно 200 рядків коду на Perl/Python/Ruby. Більшість розробників змогли створити робочі імпортери всього за кілька годин, навіть якщо це їхнє перше знайомство з швидким імпортом, а іноді навіть з Git. Це ідеальна ситуація, враховуючи, що більшість інструментів конвертації є одноразовими (використовуйте один раз і ніколи не озирайтеся назад).

ПАРАЛЕЛЬНА РОБОТА

Як і «git push» або «git fetch», імпорт, оброблений fast-import, безпечно запускати разом із паралельними викликами git repack -a -d або git gc, або будь-якою іншою операцією Git (включно з «git prune», оскільки окремі об’єкти ніколи не використовуються fast-import).

Команда fast-import не блокує посилання на гілки чи теги, які активно імпортуються. Після імпорту, під час фази оновлення посилань, функція fast-import перевіряє кожне існуюче посилання на гілку, щоб переконатися, що оновлення буде оновленням у режимі прискореного оновлення (коміт, що зберігається в посиланні, міститься в новій історії коміту, який буде записаний). Якщо оновлення не є оновленням у режимі прискореного оновлення, функція fast-import пропустить оновлення цього посилання та натомість виведе попередження. Функція fast-import завжди намагатиметься оновити всі посилання на гілки та не зупинятиметься після першої невдачі.

Оновлення гілок можна примусово оновити за допомогою --force, але рекомендується використовувати це лише на репозиторії, де все інакше не відбувається змін. Використання --force не є обов’язковим для початкового імпорту в порожній репозиторій.

ТЕХНІЧНЕ ОБГОВОРЕННЯ

Швидкий імпорт відстежує набір гілок у пам’яті. Будь-яку гілку можна створити або змінити в будь-який момент процесу імпорту, надіславши команду commit у вхідний потік. Така конструкція дозволяє фронтенд-програмі обробляти необмежену кількість гілок одночасно, генеруючи коміти в порядку їх доступності з вихідних даних. Це також значно спрощує фронтенд-програми.

fast-import не використовує та не змінює поточний робочий каталог або будь-який файл у ньому. (Однак він оновлює поточний репозиторій Git, на який посилається GIT_DIR.) Таким чином, фронтенд імпорту може використовувати робочий каталог для власних цілей, таких як вилучення версій файлів із зовнішнього джерела. Це незнання робочого каталогу також дозволяє fast-import працювати дуже швидко, оскільки йому не потрібно виконувати жодних дороговартісних операцій оновлення файлів під час перемикання між гілками.

ФОРМАТ ВВЕДЕННЯ

За винятком необроблених файлових даних (які Git не інтерпретує), формат вхідних даних швидкого імпорту базується на тексті (ASCII). Цей текстовий формат спрощує розробку та налагодження фронтенд-програм, особливо коли використовується мова вищого рівня, така як Perl, Python або Ruby.

Функція fast-import дуже суворо ставиться до вхідних даних. Там, де ми кажемо SP нижче, ми маємо на увазі рівно один пробіл. Аналогічно, LF означає один (і тільки один) перехід рядка, а HT одну (і тільки одну) горизонтальну табуляцію. Додавання додаткових пробілів призведе до неочікуваних результатів, таких як назви гілок або файлів з початковими або кінцевими пробілами в їхніх назвах, або до передчасного завершення fast-import, коли він стикається з неочікуваними вхідними даними.

Коментарі до трансляції

Для полегшення налагодження фронтендів, fast-import ігнорує будь-які рядки, що починаються з # (ASCII фунт/хеш) і до рядка, що закінчується LF включно. Рядок коментаря може містити будь-яку послідовність байтів, яка не містить LF, і тому може бути використаний для включення будь-якої детальної інформації про налагодження, яка може бути специфічною для фронтенду та корисною під час перевірки потоку даних fast-import.

Формати дати

Підтримуються такі формати дати. Фронтенд повинен вибрати формат, який використовуватиметься для цього імпорту, передавши назву формату в параметрі командного рядка --date-format=<fmt>.

raw

Це рідний формат Git, <time> SP <offutc>. Він також є форматом за замовчуванням для fast-import, якщо не було вказано --date-format.

Час події визначається як <time> як кількість секунд з епохи UNIX (північ, 1 січня 1970 року, UTC) та записується як десяткове ціле число ASCII.

Локальне зміщення визначається <offutc> як додатне або від’ємне зміщення відносно UTC. Наприклад, EST (що на 5 годин позаду UTC) буде виражено в <tz> як “-0500”, тоді як UTC дорівнює “+0000”. Локальне зміщення не впливає на <time>; воно використовується лише як порада, щоб допомогти процедурам форматування відображати позначку часу.

Якщо локальне зміщення недоступне у вихідному матеріалі, використовуйте “+0000” або найпоширеніше локальне зміщення. Наприклад, багато організацій мають репозиторій CVS, до якого зверталися лише користувачі, що знаходяться в одному місці та часовому поясі. У цьому випадку можна припустити прийнятне зміщення від UTC.

На відміну від формату rfc2822, цей формат дуже суворий. Будь-яка зміна форматування призведе до того, що функція швидкого імпорту відхилить значення, а також можуть бути виконані деякі перевірки справності числових значень.

raw-permissive

Це те саме, що й raw, за винятком того, що перевірки справності числової епохи та локального зміщення не виконуються. Це може бути корисним під час спроби фільтрувати або імпортувати існуючу історію, наприклад, з фальшивими значеннями часового поясу.

rfc2822

Це стандартний формат дати, описаний у RFC 2822.

Приклад значення: “Tue Feb 6 11:22:18 2007 -0500”. Парсер Git точний, але трохи поблажливий. Це той самий парсер, який використовується git am під час застосування патчів, отриманих з електронної пошти.

Деякі рядки з неправильним форматом можуть бути прийняті як дійсні дати. У деяких із цих випадків Git все ще зможе отримати правильну дату з рядка з неправильним форматом. Існують також деякі типи рядків з неправильним форматом, які Git може неправильно розібрати, але вважати дійсними. Рядки з серйозним дефектом будуть відхилені.

На відміну від наведеного вище формату «сирого» («raw»), інформація про часовий пояс/зміщення UTC, що міститься в рядку дати RFC 2822, використовується для коригування значення дати до UTC перед зберіганням. Тому важливо, щоб ця інформація була якомога точнішою.

Якщо вихідний матеріал використовує дати в стилі RFC 2822, інтерфейс має дозволити fast-import виконувати парсинг та конвертацію (а не намагатися робити це самостійно), оскільки парсер Git добре протестований у реальних умовах.

Фронтендам слід надавати перевагу формату «сирий» (raw) якщо вихідний матеріал вже використовує формат UNIX-епохи, його можна переконати надавати дати в цьому форматі, або його формат легко конвертувати в нього, оскільки немає двозначності при розборі.

now

Завжди використовуйте поточний час і часовий пояс. Для <when> завжди потрібно вказувати літерал now.

Це іграшковий формат. Поточний час і часовий пояс цієї системи завжди копіюються в рядок ідентифікації під час його створення за допомогою швидкого імпорту. Немає можливості вказати інший час або часовий пояс.

Цей конкретний формат надається через його короткий термін реалізації та може бути корисним для процесу, який хоче створити новий коміт просто зараз, без необхідності використовувати робочий каталог або git update-index.

Якщо в commit використовуються окремі команди author та committer, позначки часу можуть не збігатися, оскільки системний годинник буде опитуватися двічі (один раз для кожної команди). Єдиний спосіб гарантувати, що інформація про ідентифікацію автора та комітера має однакову позначку часу, – це пропустити author (таким чином копіюючи з committer) або використовувати формат дати, відмінний від now.

Команди

fast-import приймає кілька команд для оновлення поточного репозиторію та керування поточним процесом імпорту. Більш детальне обговорення (з прикладами) кожної команди буде наведено пізніше.

commit

Створює нову гілку або оновлює існуючу гілку, створюючи новий коміт та оновлюючи гілку, щоб вона вказувала на щойно створений коміт.

tag

Створює анотований об’єкт тегу з існуючого коміту або гілки. Легкі теги не підтримуються цією командою, оскільки вони не рекомендуються для запису значущих моментів часу.

reset

Скинути існуючу гілку (або нову гілку) до певної ревізії. Цю команду потрібно використовувати для зміни гілки до певної ревізії без створення фіксації змін.

blob

Конвертувати необроблені дані файлу в блоб-об’єкт для подальшого використання в команді commit. Ця команда необов’язкова і не потрібна для виконання імпорту.

alias

Записує, що позначка посилається на заданий об’єкт без попереднього створення нового об’єкта. Використання --import-marks та посилання на відсутні позначки призведе до збою швидкого імпорту, тому псевдоніми можуть забезпечити спосіб встановлення обрізаних комітів на дійсне значення (наприклад, найближчого не обрізаного предка).

checkpoint

Примусово закриває поточний пакет-файл під час швидкого імпорту, генерує його унікальну контрольну суму та індекс SHA-1, а також запускає новий пакет-файл. Ця команда необов’язкова та не потрібна для виконання імпорту.

progress

Примушує fast-import вивести весь рядок у власний стандартний вивід. Ця команда необов’язкова та не потрібна для виконання імпорту.

done

Позначає кінець потоку. Ця команда є необов’язковою, якщо функцію done не було запрошено за допомогою параметра командного рядка --done або команди feature done.

get-mark

Примушує fast-import виводити SHA-1, що відповідає позначці файлового дескриптора, встановленого за допомогою --cat-blob-fd або stdout, якщо не вказано.

cat-blob

Примушує fastimport виводити blob-об’єкт у форматі cat-file --batch до файлового дескриптора, встановленого за допомогою --cat-blob-fd або stdout, якщо не вказано.

ls

Примушує fast-import виводити рядок з описом запису каталогу у форматі ls-tree до файлового дескриптора, встановленого за допомогою --cat-blob-fd або stdout, якщо не вказано.

feature

Увімкнути вказану функцію. Це вимагає, щоб fast-import підтримував вказану функцію, і перериває роботу, якщо цього не відбувається.

option

Вкажіть будь-який із параметрів, перелічених у розділі ОПЦІЇ, який не змінює семантику потоку відповідно до потреб інтерфейсу. Ця команда є необов’язковою та не потрібна для виконання імпорту.

commit

Створіть або оновіть гілку новим комітом, записавши одну логічну зміну до проєкту.

'commit' SP <ref> LF	mark?	original-oid?	('author' (SP <name>)? SP LT <email> GT SP <when> LF)?	'committer' (SP <name>)? SP LT <email> GT SP <when> LF	('gpgsig' SP <algo> SP <format> LF data)?	('encoding' SP <encoding> LF)?	data	('from' SP <commit-ish> LF)?	('merge' SP <commit-ish> LF)*	(filemodify | filedelete | filecopy | filerename | filedeleteall | notemodify)*	LF?

де <ref> — це назва гілки, на якій буде зроблено коміт. Зазвичай назви гілок у Git мають префікс refs/heads/, тому імпорт символу гілки CVS RELENG-1_0 використовуватиме refs/heads/RELENG-1_0 для значення <ref>. Значення <ref> має бути коректним посиланням у Git. Оскільки LF не є коректним у посиланні Git, тут не підтримується синтаксис лапок або екранування.

За потреби може з’явитися команда mark, яка запитує fast-import для збереження посилання на щойно створений коміт для подальшого використання фронтендом (формат див. нижче). Фронтенди дуже часто позначають кожен створений ними коміт, тим самим дозволяючи створювати гілки з будь-якого імпортованого коміту в майбутньому.

Команда data, що йде після committer, повинна містити повідомлення коміту (синтаксис команди data див. нижче). Щоб імпортувати порожнє повідомлення коміту, використовуйте дані довжиною 0. Повідомлення коміту мають довільну форму та не інтерпретуються Git. Наразі вони мають бути закодовані в UTF-8, оскільки fast-import не дозволяє вказувати інші кодування.

Для оновлення вмісту гілки перед створенням коміту можна включити нуль або більше команд filemodify, filedelete, filecopy, filerename, filedeleteall та notemodify. Ці команди можна вводити в будь-якому порядку. Однак рекомендується, щоб команда filedeleteall передувала всім командам filemodify, filecopy, filerename та notemodify в одному коміті, оскільки filedeleteall очищає гілку (див. нижче).

LF після команди є необов’язковим (раніше він був обов’язковим). Зверніть увагу, що з міркувань зворотної сумісності, якщо коміт закінчується командою data (тобто він не має команд from, merge, filemodify, filedelete, filecopy, filerename, filedeleteall або notemodify), то в кінці команди можуть з’явитися дві команди LF замість однієї.

author

Команда author може з’являтися додатково, якщо інформація про автора може відрізнятися від інформації про комітера. Якщо author пропущено, то fast-import автоматично використовуватиме інформацію про комітера для частини автора коміта. Дивіться нижче опис полів у author, оскільки вони ідентичні committer.

committer

Команда committer вказує, хто зробив цей коміт і коли.

Тут <name> – це ім’я особи (наприклад, “Com M Itter”), а <email> – це адреса електронної пошти особи (“cm@example.com”). LT та GT – це символи «менше» (\x3c) та «більше» (\x3e). Вони потрібні для розмежування адреси електронної пошти від інших полів у рядку. Зверніть увагу, що <name> та <email> мають вільну форму та можуть містити будь-яку послідовність байтів, окрім LT, GT та LF. <name> зазвичай кодується в UTF-8.

Час зміни визначається параметром <when>, використовуючи формат дати, вибраний параметром командного рядка --date-format=<fmt>. Див. розділ “Формати дати” вище, щоб ознайомитися з набором підтримуваних форматів та їхнім синтаксисом.

gpgsig

Додаткова команда gpgsig використовується для додавання підпису PGP/GPG або іншого криптографічного підпису, який підписує дані коміту.

'gpgsig' SP <git-hash-algo> SP <signature-format> LF data

Команда gpgsig приймає два аргументи:

  • <git-hash-algo> вказує, до якого формату об’єкта Git застосовується цей підпис, або sha1, або sha256. Це дозволяє дізнатися, яке представлення коміту було підписано (версія SHA-1 або SHA-256), що допомагає як з перевіркою підпису, так і з сумісністю між репозиторіями з різними хеш-функціями.

  • <формат-сигнатури> вказує тип сигнатури, наприклад, openpgp, x509, ssh або unknown. Це зручно для інструментів, які обробляють потік, тому їм не потрібно аналізувати ASCII-шифрування для визначення типу сигнатури.

Коміт може мати щонайбільше один підпис для формату об’єкта SHA-1 (зберігається в заголовку "gpgsig") та один для формату об’єкта SHA-256 (зберігається в заголовку "gpgsig-sha256").

Дивіться нижче детальний опис команди data, яка містить необроблені дані підпису.

Однак у поточній реалізації підписи ще не перевіряються. (Вже налаштований параметр конфігурації extensions.compatObjectFormat може допомогти з перевіркою підписів об’єктів у форматах SHA-1 та SHA-256, коли це буде реалізовано.)

Note
Це дуже експериментальна розробка, і формат команди gpgsig може змінитися в майбутньому без гарантій сумісності.

encoding

Додаткова команда encoding вказує кодування повідомлення коміту. Більшість комітів мають UTF-8, і кодування опускається, але це дозволяє імпортувати повідомлення комітів у git без попереднього перекодування.

from

Команда from використовується для визначення коміту, з якого буде ініціалізована ця гілка. Ця ревізія буде першим предком нового коміту. Стан дерева, побудованого в цьому коміті, почнеться зі стану коміту from та буде змінено модифікаціями вмісту в цьому коміті.

Пропуск команди from у першому коміті нової гілки призведе до того, що fast-import створить цей коміт без предка. Зазвичай це бажано лише для початкового коміту проекту. Якщо фронтенд створює всі файли з нуля під час створення нової гілки, замість from можна використовувати команду merge, щоб розпочати коміт з порожнього дерева. Зазвичай бажано пропускати команду from на існуючих гілках, оскільки поточний коміт на цій гілці автоматично вважається першим предком нового коміту.

Оскільки LF недійсний у Git refname або SHA-1 виразі, синтаксис лапок або екранування не підтримується в <commit-ish>.

Тут <commit-ish> може бути будь-яким із наступного:

  • Назва існуючої гілки, яка вже є у внутрішній таблиці гілок fast-import. Якщо fast-import не знає назви, вона обробляється як вираз SHA-1.

  • Посилання на позначку, :<idnum>, де <idnum> – це номер позначки.

    Причина, чому fast-import використовує : для позначення посилання на позначку, полягає в тому, що цей символ не є допустимим у назві гілки Git. Початковий : дозволяє легко розрізнити позначку 42 (:42) та гілку 42 (42 або refs/heads/42), або скорочений SHA-1, який складався лише з цифр десяткової системи.

    Марки мають бути оголошені (через mark), перш ніж їх можна буде використовувати.

  • Повний 40-байтовий або скорочений коміт SHA-1 у шістнадцятковому форматі.

  • Будь-який дійсний вираз Git SHA-1, який перетворюється на коміт. Див. “ВИЗНАЧЕННЯ РЕВІЗІЙ” у gitrevisions[7] для отримання детальної інформації.

  • Спеціальний нульовий SHA-1 (40 нулів) вказує, що гілку потрібно видалити.

Окремий випадок перезапуску інкрементального імпорту з поточного значення гілки слід записати так:

from refs/heads/branch^0

Суфікс ^0 необхідний, оскільки fast-import не дозволяє гілці починатися з самої себе, а гілка створюється в пам’яті ще до того, як команда from буде прочитана з вхідних даних. Додавання ^0 змусить fast-import виконувати коміт через бібліотеку парсингу версій Git, а не через внутрішню таблицю гілок, тим самим завантажуючи існуюче значення гілки.

merge

Включає один додатковий коміт-предок. Додаткове посилання на предка не змінює спосіб побудови стану дерева в цьому коміті. Якщо команда from пропущена під час створення нової гілки, перший коміт merge буде першим предком поточного коміту, і гілка розпочнеться без файлів. Швидкий імпорт дозволяє необмежену кількість команд merge на коміт, тим самим створюючи n-стороннє злиття.

Тут <commit-ish> — це будь-який із виразів специфікації комітів, який також приймається from (див. вище).

filemodify

Включено до команди commit для додавання нового файлу або зміни вмісту існуючого файлу. Ця команда має два різні способи визначення вмісту файлу.

Формат зовнішніх даних

Дані для файлу вже були надані попередньою командою blob. Фронтенд просто має його підключити.

'M' SP <mode> SP <dataref> SP <path> LF

Тут зазвичай <dataref> має бути або посиланням на позначку (:<idnum>), встановленим попередньою командою blob, або повним 40-байтовим SHA-1 існуючого об’єкта Git blob. Якщо <mode> дорівнює 040000, тоді <dataref> має бути повним 40-байтовим SHA-1 існуючого об’єкта дерева Git або посиланням на позначку, встановленим за допомогою --import-marks.

Вбудований формат даних

Дані для файлу ще не надано. Фронтенд хоче надати їх як частину цієї команди зміни.

'M' SP <mode> SP 'inline' SP <path> LF	data

Дивіться нижче детальний опис команди data.

В обох форматах <mode> – це тип запису файлу, вказаний у вісімковому форматі. Git підтримує лише наступне:

  • 100644 або 644: Звичайний (невиконуваний) файл. Більшість файлів у більшості проектів використовують цей режим. Якщо сумніваєтеся, це саме те, що вам потрібно.

  • 100755 або 755: Звичайний, але виконуваний файл.

  • 120000: Символічне посилання, вміст файлу буде цільовим посиланням.

  • 160000: Посилання git, SHA-1 об’єкта, посилається на коміт в іншому репозиторії. Посилання git можна вказати лише за допомогою SHA або через позначку коміту. Вони використовуються для реалізації підмодулів.

  • 040000: Підкаталог. Підкаталоги можна вказати лише за допомогою SHA або через мітку дерева, встановлену за допомогою --import-marks.

В обох форматах <шлях> – це повний шлях до файлу, який потрібно додати (якщо він ще не існує) або змінити (якщо він вже існує).

<шлях> може бути записано як байти без лапок або як рядок у лапках у стилі C.

Коли <шлях> не починається з подвійних лапок ("), це рядок без лапок і розбирається як літеральний байт без будь-яких escape-послідовностей. Однак, якщо ім’я файлу містить LF або починається з подвійних лапок, його не можна представити як рядок без лапок і потрібно взяти в лапки. Крім того, джерело <шлях> у копії файлу або ім'я файлу має бути взяте в лапки, якщо воно містить SP.

Коли <шлях> починається з подвійних лапок ("), це рядок у стилі C, взятий у лапки, де повне ім’я файлу укладено в пару подвійних лапок, а також використовуються escape-послідовності. Деякі символи необхідно екранувати, додаючи перед ними зворотну скісну риску: LF записується як \n, зворотна скісну риску як \\, а подвійні лапки як \". Деякі символи можна додатково записувати з escape-послідовностями: \a для дзвінка, \b для повернення назад, \f для переведення сторінки, \n для переведення рядка, \r для повернення каретки, \t для горизонтальної табуляції та \v для вертикальної табуляції. Будь-який байт можна записати 3-значними вісімковими кодами (наприклад, \033). Усі імена файлів можна представити у вигляді рядків у лапках.

<шлях> повинен використовувати роздільники каталогів у стилі UNIX (коса риска /), а його значення має бути в канонічній формі. Тобто він не повинен:

  • містити порожній компонент каталогу (наприклад, foo//bar є недійсним),

  • закінчувати роздільником каталогів (наприклад, foo/ недійсний),

  • починати з роздільника каталогів (наприклад, /foo недійсний)

  • містити спеціальний компонент . або .. (наприклад, foo/./bar та foo/../bar є недійсними).

Корінь дерева може бути представлений порожнім рядком як <шлях>.

<шлях> не може містити NUL, ні буквально, ні екрановано як \000. Рекомендується, щоб <шлях> завжди кодувався за допомогою UTF-8.

filedelete

Включено до команди commit для видалення файлу або рекурсивного видалення всього каталогу з гілки. Якщо видалення файлу або каталогу робить його батьківський каталог порожнім, батьківський каталог також буде автоматично видалено. Це каскадно піднімається по дереву, доки не буде досягнуто першого непорожнього каталогу або кореня.

'D' SP <path> LF

тут <шлях> — це повний шлях до файлу або підкаталогу, який потрібно видалити з гілки. Див. filemodify вище для детального опису <шлях>.

filecopy

Рекурсивно копіює існуючий файл або підкаталог в інше місце в межах гілки. Існуючий файл або каталог має існувати. Якщо місце призначення існує, воно буде повністю замінено вмістом, скопійованим з джерела.

'C' SP <path> SP <path> LF

тут перший <шлях> – це місце розташування джерела, а другий <шлях> – місце призначення. Див. filemodify вище для отримання детального опису того, як може виглядати <шлях>. Щоб використовувати шлях джерела, що містить SP, шлях потрібно взяти в лапки.

Команда filecopy набуває чинності негайно. Після копіювання вихідного розташування до місця призначення будь-які майбутні команди, застосовані до вихідного розташування, не вплинуть на місце призначення копії.

filerename

Перейменовує існуючий файл або підкаталог в інше місце в межах гілки. Існуючий файл або каталог має існувати. Якщо цільовий каталог існує, його буде замінено вихідним каталогом.

'R' SP <path> SP <path> LF

тут перший <шлях> – це місце розташування джерела, а другий <шлях> – місце призначення. Див. filemodify вище для отримання детального опису того, як може виглядати <шлях>. Щоб використовувати шлях джерела, що містить SP, шлях потрібно взяти в лапки.

Команда filerename набуває чинності негайно. Після того, як вихідне розташування буде перейменовано на місце призначення, будь-які майбутні команди, застосовані до вихідного розташування, створюватимуть там нові файли та не впливатимуть на місце призначення перейменування.

Зверніть увагу, що filerename — це те саме, що й filecopy, за яким слід filedelete вихідного розташування. Використання filerename дає невелику перевагу в продуктивності, але ця перевага настільки мала, що ніколи не варто намагатися перетворити пару видалення/додавання у вихідному матеріалі на перейменування для швидкого імпорту. Ця команда filerename надається лише для спрощення інтерфейсів, які вже мають інформацію про перейменування та не хочуть турбуватися про її розкладання на filecopy, за яким слідує filedelete.

filedeleteall

Включено до команди commit для видалення всіх файлів (а також усіх каталогів) з гілки. Ця команда скидає внутрішню структуру гілки, щоб у ній не було файлів, дозволяючи фронтенду згодом додавати всі цікаві файли з нуля.

'deleteall' LF

Ця команда надзвичайно корисна, якщо фронтенд не знає (або не хоче знати), які файли зараз знаходяться в гілці, і тому не може згенерувати відповідні команди filedelete для оновлення вмісту.

Виконання команди filedeleteall, а потім необхідних команд filemodify для встановлення правильного вмісту, призведе до тих самих результатів, що й надсилання лише необхідних команд filemodify та filedelete. Однак підхід filedeleteall може вимагати швидкого імпорту для використання трохи більше пам’яті на активну гілку (менше 1 МіБ навіть для більшості великих проектів); тому фронтендам, які можуть легко отримати лише відповідні шляхи для коміту, рекомендується робити це.

notemodify

Включено до команди commit <notes-ref> для додавання нової нотатки з анотацією <commit-ish> або зміни вмісту цієї анотації. Внутрішньо це схоже на filemodify 100644 для шляху <commit-ish> (можливо, розділено на підкаталоги). Не рекомендується використовувати будь-які інші команди для запису в дерево <notes-ref>, окрім filedeleteall для видалення всіх існуючих нотаток у цьому дереві. Ця команда має два різні способи визначення вмісту нотатки.

Формат зовнішніх даних

Вміст даних для нотатки вже було надано попередньою командою blob. Фронтенд просто має підключити його до коміту, який потрібно анотувати.

'N' SP <dataref> SP <commit-ish> LF

Тут <dataref> може бути або посиланням на позначку (:<idnum>), встановленим попередньою командою blob, або повним 40-байтовим SHA-1 існуючого об’єкта Git blob.

Вбудований формат даних

Дані для нотатки ще не надано. Фронтенд хоче надати їх як частину цієї команди зміни.

'N' SP 'inline' SP <commit-ish> LF	data

Дивіться нижче детальний опис команди data.

В обох форматах <commit-ish> — це будь-який із виразів специфікації коміту, який також приймається from (див. вище).

mark

Організовує швидкий імпорт для збереження посилання на поточний об’єкт, дозволяючи фронтенду викликати цей об’єкт у майбутньому, не знаючи його SHA-1. Тут поточний об’єкт – це команда створення об’єкта, в якій знаходиться команда mark. Це може бути commit, tag та blob, але commit є найпоширенішим використанням.

'mark' SP ':' <idnum> LF

де <idnum> – це число, призначене фронтендом цій позначці. Значення <idnum> виражається як десяткове ціле число ASCII. Значення 0 зарезервовано і не може використовуватися як позначка. Як позначки можна використовувати лише значення, більші або рівні 1.

Нові позначки створюються автоматично. Існуючі позначки можна перемістити на інший об’єкт, просто повторно використовуючи той самий <idnum> в іншій команді mark.

original-oid

Надає ім’я об’єкта в оригінальній системі керування версіями. fast-import просто ігноруватиме цю директиву, але процеси фільтрації, які працюють з потоком та змінюють його перед передачею до fast-import, можуть використовувати цю інформацію

'original-oid' SP <object-identifier> LF

де <ідентифікатор-об'єкта> — це будь-який рядок, що не містить LF.

tag

Створює анотований тег, що посилається на певний коміт. Щоб створити легкі (неанотовані) теги, див. команду reset нижче.

'tag' SP <name> LF	mark?	'from' SP <commit-ish> LF	original-oid?	'tagger' (SP <name>)? SP LT <email> GT SP <when> LF	data

де <назва> – це назва тегу, який потрібно створити.

Назви тегів автоматично мають префікс refs/tags/ під час зберігання в Git, тому імпорт символу гілки CVS RELENG-1_0-FINAL використовуватиме лише RELENG-1_0-FINAL для <назва>, а fast-import запише відповідне посилання як refs/tags/RELENG-1_0-FINAL.

Значення <name> має бути коректним посиланням у Git і тому може містити скісну риску. Оскільки LF не є коректним у посиланнях Git, тут не підтримується синтаксис лапок або екранування.

Команда from така ж, як і в команді commit; див. деталі вище.

Команда tagger використовує той самий формат, що й committer у commit; знову ж таки, див. деталі вище.

Команда data, що йде після tagger, повинна містити анотоване повідомлення тегу (синтаксис команди data див. нижче). Щоб імпортувати порожнє повідомлення тегу, використовуйте дані довжиною 0. Повідомлення тегів мають довільну форму та не інтерпретуються Git. Наразі вони мають бути закодовані в UTF-8, оскільки швидкий імпорт не дозволяє вказувати інші кодування.

Підписання анотованих тегів під час імпорту з fast-import не підтримується. Не рекомендується намагатися включити власний підпис PGP/GPG, оскільки фронтенд не має (легкого) доступу до повного набору байтів, які зазвичай входять до такого підпису. Якщо потрібне підписання, створіть легкі теги з fast-import за допомогою reset, а потім створіть анотовані версії цих тегів офлайн за допомогою стандартного процесу git tag.

reset

Створює (або відтворює) іменовану гілку, за бажанням починаючи з певної ревізії. Команда reset дозволяє фронтенду видавати нову команду from для існуючої гілки або створювати нову гілку з існуючого коміту без створення нового коміту.

'reset' SP <ref> LF	('from' SP <commit-ish> LF)?	LF?

Детальний опис <ref> та <commit-ish> див. вище у розділах commit та from.

Літера LF після команди є необов’язковою (раніше вона була обов’язковою).

Команду reset також можна використовувати для створення легких (неанотованих) тегів. Наприклад:

reset refs/tags/938 from :938

створить легкий тег refs/tags/938, що посилатиметься на будь-який коміт-маркер :938.

blob

Запитує запис однієї ревізії файлу до packfile. Ревізія не пов’язана з жодним комітом; це з’єднання має бути сформоване в наступній команді commit шляхом посилання на блоб через призначену позначку.

'blob' LF	mark?	original-oid?	data

Команда mark тут необов’язкова, оскільки деякі фронтенди вирішили самостійно генерувати Git SHA-1 для блобу та передавати його безпосередньо до commit. Однак це зазвичай більше роботи, ніж того варте, оскільки мітки недорого зберігати та легко використовувати.

data

Надає необроблені дані (для використання як вміст блобів/файлів, повідомлення комітів або анотовані повідомлення тегів) для швидкого імпорту. Дані можна надати з використанням точної кількості байтів або розділити кінцевою лінією. Реальні фронтенди, призначені для перетворень виробничої якості, завжди повинні використовувати формат точної кількості байтів, оскільки він є більш надійним та працює краще. Формат з роздільниками призначений переважно для тестування швидкого імпорту.

Рядки коментарів, що з’являються в частині <raw> команд data, завжди вважаються частиною тіла даних і тому ніколи не ігноруються при швидкому імпорті. Це робить безпечним імпорт будь-якого вмісту файлів/повідомлень, рядки яких можуть починатися з #.

Точний формат підрахунку байтів

Фронтенд повинен вказувати кількість байтів даних.

'data' SP <count> LF	<raw> LF?

де <count> – це точна кількість байтів, що з’являються в <raw>. Значення <count> виражається як десяткове ціле число ASCII. LF з обох боків <raw> не включається до <count> і не буде включено до імпортованих даних.

LF після <raw> є необов’язковим (раніше він був обов’язковим), але рекомендується. Його постійне включення спрощує налагодження потоку швидкого імпорту, оскільки наступна команда завжди починається у стовпці 0 наступного рядка, навіть якщо <raw> не закінчується на LF.

Формат з роздільниками

Для позначення кінця даних використовується рядок-роздільник. fast-import обчислить довжину, шукаючи роздільник. Цей формат корисний переважно для тестування та не рекомендується для реальних даних.

'data' SP '<<' <delim> LF	<raw> LF	<delim> LF	LF?

де <delim> – це вибраний рядок-роздільник. Рядок <delim> не повинен стояти окремо всередині <raw>, оскільки інакше fast-import вважатиме, що дані закінчуються раніше, ніж це є насправді. LF, що безпосередньо йде після <raw>, є частиною <raw>. Це одне з обмежень формату з роздільниками: неможливо надати фрагмент даних, який не має LF як останній байт.

LF після <delim> LF є необов’язковим (раніше він був обов’язковим).

alias

Зафіксуйте, що знак стосується заданого об’єкта без попереднього створення будь-якого нового об’єкта.

'alias' LF	mark	'to' SP <commit-ish> LF	LF?

Детальний опис <commit-ish> див. вище у розділі from.

checkpoint

Примусово закриває поточний пакет-файл під час швидкого імпорту, запускає новий та зберігає всі поточні посилання на гілки, теги та позначки.

'checkpoint' LF	LF?

Зверніть увагу, що fast-import автоматично перемикає пакетні файли, коли поточний пакетний файл досягає --max-pack-size або 4 ГіБ, залежно від того, яка межа менша. Під час автоматичного перемикання пакетного файлу fast-import не оновлює посилання на гілки, теги чи позначки.

Оскільки «контрольна точка» може вимагати значної кількості процесорного часу та дискового вводу-виводу (для обчислення загальної контрольної суми SHA-1 пакета, генерації відповідного індексного файлу та оновлення посилань), виконання однієї команди «контрольна точка» може легко зайняти кілька хвилин.

Фронтенди можуть вирішувати виставляти контрольні точки під час надзвичайно великих та тривалих імпортів або коли їм потрібно дозволити іншому процесу Git доступ до гілки. Однак, враховуючи, що репозиторій Subversion розміром 30 ГіБ можна завантажити в Git за допомогою швидкого імпорту приблизно за 3 години, явне встановлення контрольних точок може не бути необхідним.

Літера LF після команди є необов’язковою (раніше вона була обов’язковою).

progress

Змушує fast-import виводити весь рядок progress без змін у стандартний вихідний канал (файловий дескриптор 1) під час обробки команди з вхідного потоку. В іншому випадку команда не впливає на поточний імпорт або на будь-який внутрішній стан fast-import.

'progress' SP <any> LF	LF?

Частина команди <any> може містити будь-яку послідовність байтів, яка не містить LF. LF після команди є необов’язковим. Викликаючі сторони можуть обробити вивід за допомогою інструменту, такого як sed, щоб видалити початкову частину рядка, наприклад:

frontend | git fast-import | sed 's/^progress //'

Розміщення команди progress одразу після checkpoint повідомить читача про завершення checkpoint, і він зможе безпечно отримати доступ до посилань, які було оновлено за допомогою швидкого імпорту.

get-mark

Примушує fast-import вивести SHA-1, що відповідає позначці, на stdout або на файловий дескриптор, попередньо впорядкований за допомогою аргументу --cat-blob-fd. В іншому випадку команда не впливає на поточний імпорт; її метою є отримання SHA-1, на які наступні коміти можуть посилатися у своїх повідомленнях комітів.

'get-mark' SP ':' <idnum> LF

Дивіться розділ «Відповіді на команди» нижче для отримання детальної інформації про те, як безпечно читати цей вивід.

cat-blob

Примушує fast-import вивести блоб-об’єкт до файлового дескриптора, попередньо впорядкованого за допомогою аргументу --cat-blob-fd. В іншому випадку команда не впливає на поточний імпорт; її головне призначення — отримати блоби, які можуть бути в пам’яті fast-import, але недоступні з цільового репозиторію.

'cat-blob' SP <dataref> LF

<dataref> може бути або посиланням на позначку (:<idnum>), встановленим раніше, або повним 40-байтовим SHA-1 блобу Git, що вже існує або готовий до запису.

Вивід використовує той самий формат, що й git cat-file --batch:

<sha1> SP 'blob' SP <size> LF <contents> LF

Цю команду можна використовувати там, де може з’явитися директива filemodify, що дозволяє використовувати її посеред коміту. Для filemodify, що використовує вбудовану директиву, вона також може з’являтися безпосередньо перед директивою data.

Дивіться розділ «Відповіді на команди» нижче для отримання детальної інформації про те, як безпечно читати цей вивід.

ls

Виводить інформацію про об’єкт за шляхом до файлового дескриптора, попередньо впорядкованого за допомогою аргументу --cat-blob-fd. Це дозволяє виводити блоб з активного коміту (за допомогою cat-blob) або копіювати блоб чи дерево з попереднього коміту для використання в поточному (за допомогою filemodify).

Команду ls також можна використовувати там, де може з’явитися директива filemodify, що дозволяє використовувати її посеред коміту.

Читання з активного коміту

Цю форму можна використовувати лише в середині коміту. Шлях вказує на запис каталогу в активному коміті fast-import. У цьому випадку шлях має бути взято в лапки.

'ls' SP <path> LF
Читання з іменованого дерева

<dataref> може бути посиланням на позначку (:<idnum>) або повним 40-байтовим SHA-1 тегу Git, коміту або об’єкта дерева, що існує вже або очікує на запис. Шлях залежить від верхнього рівня дерева з назвою <dataref>.

'ls' SP <dataref> SP <path> LF

Дивіться filemodify вище для отримання детального опису <шлях>.

Вивід використовує той самий формат, що й `git ls-tree <дерево>:

<mode> SP ('blob' | 'tree' | 'commit') SP <dataref> HT <path> LF

<dataref> представляє об’єкт blob, дерево або commit за адресою <path> і може бути використаний у наступних командах get-mark, cat-blob, filemodify або ls.

Якщо за цим шляхом немає файлу або піддерева, git fast-import натомість видасть повідомлення

missing SP <path> LF

Дивіться розділ «Відповіді на команди» нижче для отримання детальної інформації про те, як безпечно читати цей вивід.

feature

Вимагати, щоб швидкий імпорт підтримував зазначену функцію, або перервати, якщо ні.

'feature' SP <feature> ('=' <argument>)? LF

Частина команди <feature> може бути будь-якою з наступних:

date-format
export-marks
relative-marks
no-relative-marks
сила

Дійте так, ніби відповідний параметр командного рядка з початковим символом -- було передано в командному рядку (див. ПАРАМЕТРИ вище).

import-marks
import-marks-if-exists

Подібно до --import-marks, за винятком двох аспектів: по-перше, для кожного потоку дозволена лише одна команда "feature import-marks" або "feature import-marks-if-exists"; по-друге, параметр командного рядка --import-marks= або --import-marks-if-exists перевизначає будь-яку з цих команд "feature" у потоці; по-третє, "feature import-marks-if-exists", як і відповідний параметр командного рядка, непомітно пропускає неіснуючий файл.

get-mark
cat-blob
лс

Вимагати, щоб серверна частина підтримувала команди get-mark, cat-blob або ls відповідно. Версії fast-import, які не підтримують зазначену команду, завершаться з повідомленням про це. Це дозволяє помилці імпорту вивести її на ранній стадії з чітким повідомленням, замість того, щоб витрачати час на ранню частину імпорту, перш ніж буде виявлено непідтримувану команду.

нотатки

Вимагати, щоб серверна частина підтримувала підкоманду notemodify (N) для команди commit. Версії швидкого імпорту, які не підтримують нотатки, завершаться з повідомленням про це.

зроблено

Виводиться помилка, якщо потік завершується без команди «done». Без цієї функції помилки, що призводять до раптового завершення фронтенду в зручній точці потоку, можуть залишитися непоміченими. Це може статися, наприклад, якщо фронтенд імпорту завершує роботу посеред операції без генерації SIGTERM або SIGKILL у підпорядкованому екземплярі git fast-import.

option

Обробляє вказаний параметр таким чином, щоб git fast-import працював відповідно до потреб фронтенду. Зверніть увагу, що параметри, вказані фронтендом, перевизначаються будь-якими параметрами, які може вказати користувач.

 'option' SP <option> LF

Частина команди <option> може містити будь-які опції, перелічені в розділі OPTIONS, які не змінюють семантику імпорту, без початкового символу --, і обробляється таким самим чином.

Команди з параметрами мають бути першими командами на вхідних даних (не враховуючи команди функцій), щоб команда з параметрами видавалася після помилки будь-якої команди, яка не є параметрами.

Наведені нижче параметри командного рядка змінюють семантику імпорту, тому їх не можна передати як параметри:

  • date-format

  • import-marks

  • export-marks

  • cat-blob-fd

  • сила

done

Якщо функція done не використовується, обробляється так, ніби EOF було прочитано. Це можна використовувати, щоб вказати fast-import завершитися раніше.

Якщо використовується параметр командного рядка --done або команда feature done, команда done є обов’язковою та позначає кінець потоку.

ВІДПОВІДІ НА КОМАНДИ

Нові об’єкти, написані за допомогою fast-import, недоступні одразу. Більшість команд fast-import не мають видимого ефекту до наступної контрольної точки (або завершення). Фронтенд може надсилати команди для заповнення вхідного каналу fast-import, не турбуючись про те, як швидко вони набудуть чинності, що покращує продуктивність, спрощуючи планування.

Однак для деяких фронтендів корисно мати можливість зчитувати дані з поточного репозиторію під час його оновлення (наприклад, коли вихідний матеріал описує об’єкти з точки зору патчів, які потрібно застосувати до раніше імпортованих об’єктів). Цього можна досягти, підключивши фронтенд та функцію швидкого імпорту через двонаправлені канали:

mkfifo fast-import-output frontend <fast-import-output | git fast-import >fast-import-output

Фронтенд, налаштований таким чином, може використовувати команди progress, get-mark, ls та cat-blob для зчитування інформації з поточного імпорту.

Щоб уникнути взаємоблокування, такі фронтенди повинні повністю спожити будь-який очікуваний вивід від progress, ls, get-mark та cat-blob, перш ніж виконувати запис у fast-import, який може призвести до блокування.

ЗВІТИ ПРО АВАРІЇ

Якщо для fast-import надано недійсні вхідні дані, робота завершиться з ненульовим статусом виходу та створиться звіт про збій на верхньому рівні репозиторію Git, в який імпортувався файл. Звіти про збої містять знімок внутрішнього стану fast-import, а також останні команди, що призвели до збою.

Усі нещодавні команди (включно з коментарями до потоку, змінами файлів та командами виконання) відображаються в історії команд у звіті про збій, але необроблені дані файлів та повідомлення про фіксацію виключаються зі звіту про збій. Це виключення економить місце у файлі звіту та зменшує обсяг буферизації, який має виконувати швидкий імпорт під час виконання.

Після написання звіту про збій, швидкий імпорт закриє поточний пакетний файл та експортує таблицю позначок. Це дозволяє розробнику фронтенду перевірити стан репозиторію та відновити імпорт з точки, де стався збій. Змінені гілки та теги не оновлюються під час збою, оскільки імпорт не завершився успішно. Інформацію про гілки та теги можна знайти у звіті про збій, і її необхідно застосувати вручну, якщо потрібне оновлення.

Приклад аварії:

$ cat >in <<END_OF_INPUT # my very first test commit commit refs/heads/master committer Shawn O. Pearce <spearce> 19283 -0400 # who is that guy anyway? data <<EOF this is my commit EOF M 644 inline .gitignore data <<EOF .gitignore EOF M 777 inline bob END_OF_INPUT
$ git fast-import <in fatal: Corrupt mode: M 777 inline bob fast-import: dumping crash report to .git/fast_import_crash_8434
$ cat .git/fast_import_crash_8434 fast-import crash report: fast-import process: 8434 parent process : 1391 at Sat Sep 1 00:58:12 2007
fatal: Corrupt mode: M 777 inline bob
Most Recent Commands Before Crash --------------------------------- # my very first test commit commit refs/heads/master committer Shawn O. Pearce <spearce> 19283 -0400 # who is that guy anyway? data <<EOF M 644 inline .gitignore data <<EOF * M 777 інлайн-боб

Active Branch LRU

active_branches = 1 cur, 5 max назва годинника POS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1) 0 refs/heads/master Inactive Branches

refs/heads/master: status : active loaded dirty tip commit : 0000000000000000000000000000000000000000 old tree : 0000000000000000000000000000000000000000 cur tree : 0000000000000000000000000000000000000000 commit clock: 0 last pack :

------------------- КІНЕЦЬ ЗВІТУ ПРО АВАРІЮ

ПОРАДИ ТА ХИТРОСТІ

Наведені нижче поради та рекомендації були зібрані від різних користувачів швидкого імпорту та пропонуються тут як пропозиції.

Використовуйте одну позначку на коміт

Під час конвертації репозиторію використовуйте унікальну позначку для кожного коміту (mark :<n>) та вкажіть опцію --export-marks у командному рядку. fast-import створить дамп файлу, який містить список усіх позначок та SHA-1 об’єкта Git, що їм відповідає. Якщо фронтенд може пов’язати позначки з вихідним репозиторієм, легко перевірити точність та повноту імпорту, порівнявши кожен коміт Git з відповідною вихідною ревізією.

Виходячи з такої системи, як Perforce або Subversion, це має бути досить просто, оскільки позначкою швидкого імпорту також може бути номер набору змін Perforce або номер ревізії Subversion.

Вільно стрибайте по гілках

Не намагайтеся оптимізувати фронтенд, щоб під час імпорту залишалася лише одна гілка за раз. Хоча це може бути трохи швидшим для швидкого імпорту, це, як правило, значно збільшує складність коду фронтенду.

Вбудований LRU гілок для швидкого імпорту, як правило, поводиться дуже добре, а вартість активації неактивної гілки настільки низька, що перемикання між гілками практично не впливає на продуктивність імпорту.

Обробка перейменувань

Під час імпорту перейменованого файлу або каталогу просто видаліть стару(і) назву(і) та змініть нову(і) назву(і) під час відповідного коміту. Git виконує виявлення перейменування постфактум, а не явно під час коміту.

Використовуйте гілки виправлення тегів

Деякі інші SCM-системи дозволяють користувачеві створювати теги з кількох файлів, які не належать до одного коміту/набору змін. Або створювати теги, які є підмножиною файлів, доступних у репозиторії.

Імпорт цих тегів «як є» в Git неможливий без створення хоча б одного коміту, який «виправляє» файли відповідно до вмісту тегу. Використовуйте команду reset з fast-import, щоб скинути фіктивну гілку за межами вашого звичайного простору гілок до базового коміту для тегу, потім закомітуйте один або кілька комітів виправлення файлів і, нарешті, позначте фіктивну гілку тегом.

Наприклад, оскільки всі звичайні гілки зберігаються в refs/heads/, назвіть гілку fixup з тегом TAG_FIXUP. Таким чином, гілка fixup, що використовується імпортером, не може мати конфліктів простору імен зі справжніми гілками, імпортованими з джерела (ім’я TAG_FIXUP не є refs/heads/TAG_FIXUP).

Під час коміту виправлень розгляньте можливість використання merge для підключення коміту(ів), який(і) надає(ють) ревізії файлів, до гілки fixup. Це дозволить таким інструментам, як git blame, відстежувати реальну історію комітів та правильно анотувати вихідні файли.

Після завершення швидкого імпорту фронтенд-у потрібно буде виконати rm .git/TAG_FIXUP, щоб видалити фіктивну гілку.

Імпортуйте зараз, перепакуйте пізніше

Щойно завершиться швидкий імпорт, репозиторій Git буде повністю валідним та готовим до використання. Зазвичай це займає дуже короткий час, навіть для досить великих проектів (понад 100 000 комітів).

Однак перепакування репозиторію необхідне для покращення локальності даних та продуктивності доступу. Це також може тривати годинами на надзвичайно великих проектах (особливо якщо використовується параметр -f та великий --window). Оскільки перепакування безпечно виконувати разом із програмами читання та запису, запустіть перепакування у фоновому режимі та дайте йому завершитися, коли воно завершиться. Немає причин чекати, щоб дослідити свій новий проект Git!

Якщо ви вирішите почекати на перепакування, не намагайтеся запускати бенчмарки чи тести продуктивності, доки перепакування не буде завершено. fast-import видає неоптимальні файли пакетів, які просто ніколи не зустрічаються в реальних ситуаціях використання.

Перепакування історичних даних

Якщо ви перепаковуєте дуже старі імпортовані дані (наприклад, старіші за минулий рік), подумайте про те, щоб витратити трохи додаткового процесорного часу та вказати параметр --window=50 (або вище) під час запуску git repack. Це займе більше часу, але також призведе до меншого пакетного файлу. Вам потрібно витратити зусилля лише один раз, і всі, хто використовує ваш проект, отримають користь від меншого репозиторію.

Додайте деякі повідомлення про прогрес

Час від часу ваш фронтенд має надсилати повідомлення про хід виконання швидкого імпорту. Вміст повідомлень має повністю вільну форму, тому однією з пропозицій було б виводити поточний місяць і рік щоразу, коли поточна дата фіксації переходить на наступний місяць. Вашим користувачам буде легше знати, яка частина потоку даних була оброблена.

ОПТИМІЗАЦІЯ ПАКЕТНИХ ФАЙЛІВ

Під час пакування блобу fast-import завжди намагається виконати дельта-версію з останнім записаним блобом. Якщо це спеціально не передбачено фронтендом, це, ймовірно, не буде попередньою версією того ж файлу, тому згенерована дельта не буде найменшою можливою. Результуючий пакет-файл буде стиснутий, але не оптимальним.

Фронтенди, які мають ефективний доступ до всіх версій одного файлу (наприклад, читають файл RCS/CVS .v), можуть надавати всі версії цього файлу як послідовність послідовних команд blob. Це дозволяє швидкому імпорту порівнювати різні версії файлів одну з одною, заощаджуючи місце в кінцевому пакетному файлі. Позначки можна використовувати для подальшої ідентифікації окремих версій файлів під час виконання послідовності команд commit.

Пакетні файли, створені за допомогою fast-import, не сприяють належним шаблонам доступу до диска. Це спричинено тим, що fast-import записує дані в порядку їх отримання на стандартний ввід, тоді як Git зазвичай організовує дані в пакетних файлах так, щоб найновіші (поточні дані з підказкою) відображалися перед історичними даними. Git також кластеризує коміти, пришвидшуючи проходження версій завдяки кращій локальності кешу.

З цієї причини наполегливо рекомендується, щоб користувачі перепакували репозиторій за допомогою git repack -a -d після завершення швидкого імпорту, що дозволить Git реорганізувати пакетні файли для швидшого доступу до даних. Якщо дельти блобів неоптимальні (див. вище), то додавання опції -f для примусового перерахунку всіх дельт може значно зменшити кінцевий розмір пакетного файлу (на 30-50% менше може бути досить типовим).

Замість запуску git repack ви також можете виконати git gc --aggressive, що також оптимізує інші речі після імпорту (наприклад, пакує вільні посилання). Як зазначено в розділі "AGGRESSIVE" у git-gc[1], опція --aggressive знайде нові дельти з опцією -f для git-repack[1]. З причин, описаних вище, використання --aggressive після швидкого імпорту є одним з небагатьох випадків, коли це відомо як доцільне.

ВИКОРИСТАННЯ ПАМ’ЯТІ

Існує ряд факторів, які впливають на обсяг пам’яті, який потрібен fast-import для виконання імпорту. Як і критичні розділи ядра Git, fast-import використовує власні розподільники пам’яті для амортизації будь-яких накладних витрат, пов’язаних з malloc. На практиці fast-import, як правило, амортизує будь-які накладні витрати malloc до 0 через використання великих блоків розподілу.

per object

Команда fast-import підтримує структуру в пам’яті для кожного об’єкта, записаного в цьому виконанні. У 32-бітній системі структура має розмір 32 байти, у 64-бітній системі — 40 байт (через більший розмір вказівника). Об’єкти в таблиці не звільняються, доки fast-import не завершиться. Імпорт 2 мільйонів об’єктів у 32-бітній системі потребуватиме приблизно 64 МБ пам’яті.

Таблиця об’єктів насправді є хеш-таблицею, ключ якої пов’язаний з назвою об’єкта (унікальний SHA-1). Така конфігурація сховища дозволяє швидкому імпорту повторно використовувати існуючий або вже записаний об’єкт та уникати запису дублікатів у вихідний пакет-файл. Дублікати блобів напрочуд часто зустрічаються під час імпорту, зазвичай через злиття гілок у вихідному коді.

per mark

Позначки зберігаються в розрідженому масиві, використовуючи 1 вказівник (4 байти або 8 байтів, залежно від розміру вказівника) на позначку. Хоча масив розріджений, фронтендам все одно наполегливо рекомендується використовувати позначки від 1 до n, де n – загальна кількість позначок, необхідних для цього імпорту.

per branch

Гілки класифікуються на активні та неактивні. Використання пам’яті цими двома класами суттєво відрізняється.

Неактивні гілки зберігаються в структурі, яка використовує 96 або 120 байт (відповідно 32-бітні або 64-бітні системи) плюс довжина назви гілки (зазвичай менше 200 байт) на гілку. fast-import легко обробить до 10 000 неактивних гілок у менш ніж 2 МБ пам’яті.

Активні гілки мають такі ж накладні витрати, як і неактивні гілки, але також містять копії кожного дерева, яке нещодавно було змінено на цій гілці. Якщо піддерево include не було змінено з моменту, коли гілка стала активною, його вміст не буде завантажено в пам’ять, але якщо піддерево src було змінено комітом з моменту, коли гілка стала активною, тоді його вміст буде завантажено в пам’ять.

Оскільки активні гілки зберігають метадані про файли, що містяться в цій гілці, розмір їхнього сховища в оперативній пам’яті може значно зрости (див. нижче).

fast-import автоматично переміщує активні гілки в неактивний стан на основі простого алгоритму, що визначає найменш використовувані гілки. Ланцюг LRU оновлюється з кожною командою commit. Максимальну кількість активних гілок можна збільшити або зменшити в командному рядку за допомогою --active-branches=.

на одне активне дерево

Дерева (або каталоги) використовують лише 12 байт пам’яті понад пам’ять, необхідну для їхніх записів (див. «на кожен активний файл»). Вартість дерева практично дорівнює 0, оскільки його накладні витрати амортизуються на окремі записи файлів.

за кожен активний запис файлу

Файли (та вказівники на піддерева) в активних деревах потребують 52 або 64 байти (32/64-бітні платформи) на кожен запис. Для економії місця імена файлів і дерев об’єднуються в загальну таблицю рядків, що дозволяє імені файлу “Makefile” використовувати лише 16 байт (після врахування заголовка рядка) незалежно від того, скільки разів воно зустрічається в проекті.

Активна гілка LRU, у поєднанні з пулом рядків імен файлів та лінивим завантаженням піддерев, дозволяє швидко імпортувати проекти з понад 2000 гілками та понад 45 114 файлами з дуже обмеженим обсягом пам’яті (менше 2,7 МіБ на активну гілку).

СИГНАЛИ

Надсилання SIGUSR1 до процесу git fast-import передчасно завершує поточний пакетний файл, імітуючи команду checkpoint. Нетерплячий оператор може використовувати цю можливість для попереднього перегляду об’єктів та посилань з поточного імпорту, але це призведе до збільшення часу виконання та гіршого стиснення.

КОНФІГУРАЦІЯ

Все, що знаходиться нижче цього рядка в цьому розділі, вибірково включено з документації git-config[1]. Вміст такий самий, як і там:

Warning

Missing uk/config/fastimport.adoc

See original version for this content.

ДИВ. ТАКОЖ

GIT

Частина набору git[1]