Інструменти робочого простору

Атрибути файлів

.gitattributes — найцінніший файл у git, який майже ніхто не пише. Саме через нього репозиторій розповідає git про власний вміст: які файли бінарні, які треба склеювати замість конфліктувати, які ніколи не потрапляють в архів, які закінчення рядків отримують усі.

Найважливіше: він комітиться. Правило, яке ви додали, розв’язує проблему для кожного, хто зробить клон, на кожній ОС, назавжди — на відміну від налаштування у вашому власному конфізі, яке лагодить проблему вам, а колегам лишає можливість відкрити її для себе важким шляхом.

⌘K → Атрибути файлів.

Правила, які репозиторій уже несе, пресети, перевірка шляху та діф-драйвери

Що роблять правила

Атрибут Що лагодить
text=auto eol=lf Закінчення рядків, які стрибають залежно від того, хто зробив чекаут файлу
binary Спроби git показати діф або зробити тристороннє злиття PSD, DOCX чи скомпільованого ресурсу
merge=union Changelog, до якого всі дописують і на якому всі конфліктують
-merge Файли, де тристороннє злиття дає нісенітницю — lock-файли, згенерований код
export-ignore Конфіги CI та фікстури, що поїхали всередині релізного тарболу
diff=<driver> Нечитабельні діфи для форматів, які насправді читабельні, якщо дати конвертер
filter=lfs Великі файли, що зберігаються через LFS
linguist-vendored Сторонній код, зарахований вам у мовній статистиці

binary — це скорочення для -diff -merge -text, тобто три відповіді на «припини вгадувати щодо цього файлу» одним словом.

Редагування

Пресети підставляють шаблон і його атрибути; відредагуйте шаблон перед додаванням — CHANGELOG.md це пропозиція, а не правило про ваш проєкт.

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

Кожне збереження — звичайна дія Gitcito: вона показує сповіщення, а Скасувати повертає файл рівно таким, яким він був.

Репозиторій може мати кілька файлів атрибутів. Один у корені, один у будь-якому підкаталозі, і приватний .git/info/attributes, який ніколи не комітиться і діє лише на вашій машині — правильне місце для правила, що стосується вас, а не проєкту. Gitcito перелічує їх усі й каже, що є що.

Що застосовується до шляху?

Правила приходять із кількох файлів, перемагає конкретніше, і читати їх, щоб вивести відповідь, — це гадання. Що застосовується до шляху? запускає git check-attr і показує, до чого доходить сам git — єдину відповідь, яка має значення.

Діф-драйвери: як зробити документ Word читабельним

.docx — це zip. .pdf — стиснутий граф об’єктів. Git показує їхні діфи як те, чим вони є — як шум, — тож історія документа нечитабельна, хоч сам документ читабельний.

Діф-драйвер лагодить це через textconv: команду, яка перетворює файл на текст лише для порівняння. Файл у вашому робочому дереві не змінюється; git просто порівнює сконвертований текст.

Дві половини, і потрібні обидві:

  1. diff.<name>.textconv у конфізі git — команда-конвертер.
  2. *.docx diff=<name> у .gitattributes — до яких файлів вона застосовується.

Кнопки тут роблять і те, і те одразу. Для Word, Excel, JSON і .strings Gitcito постачає конвертер сам — той самий розбір документів, яким користуються його попередні перегляди, відкритий як невелика команда gitcito-textconv всередині застосунку, — тож ці чотири працюють без жодних встановлень. Решті все ще потрібен справжній інструмент у вашому PATH: Gitcito перевіряє і притлумлює те, чого бракує, замість писати драйвер, що зламається на першому ж діфі.

Драйвер Потребує Дає вам
word нічого — постачається з Gitcito Діфи прози для .docx
excel нічого — постачається з Gitcito Порядкові діфи (CSV на кожен аркуш) для .xlsx/.xls
json нічого — постачається з Gitcito Стабільні діфи JSON із відсортованими ключами
strings нічого — постачається з Gitcito Порядковий diff .strings у UTF-16, який git називає двійковим
pdf pdftotext (poppler) Текстові діфи для .pdf
exif exiftool Що змінилося в зображенні, коли пікселі непрозорі

Той, що кусає iOS-проєкти

Localizable.strings майже всю історію Xcode лежить у UTF-16, а UTF-16 повний байтів NUL — тож git оголошує файл двійковим і не показує нічого:

diff --git a/Localizable.strings b/Localizable.strings
Binary files a/Localizable.strings and b/Localizable.strings differ

Саме тут найважливіше бачити, який рядок хтось зрушив. Драйвер strings декодує файл лише для порівняння — читаючи позначку порядку байтів, а не припускаючи її, тож сучасний .strings у UTF-8 проходить неушкодженим, а не перетворюється на кракозябри.

String Catalog (.xcstrings, Xcode 15 і новіші) — це JSON, і його закриває драйвер json: він сортує ключі, тож переклад, доданий згори, перестає переписувати в дифі весь файл.

Межі вбудованого конвертера, названі прямо: .doc (старий двійковий формат Word) він не розуміє — лише .docx; PDF не покрито — Gitcito показує PDF у переглядачі браузера й не має видобувача тексту, який можна було б ужити повторно; і кожен діф документа платить коротку ціну запуску конвертера. Налаштування git config diff.<name>.cachetextconv true змушує git кешувати вивід для кожного блоба.

Половина з конвертером живе у вашому конфізі, а не в репозиторії — git не запускатиме команди, які вам підсунув клон, і це властивість безпеки, яку варто берегти. До того ж вбудовані драйвери вказують на ваш шлях встановлення Gitcito, тож колега, що зробить клон, отримає правило diff=word і, доки не під'єднає власний конвертер (Gitcito чи будь-який інший), старий нечитабельний діф. Напишіть про це у своєму README.

Фільтри clean/smudge — спершу пробний прогін

Фільтр переписує вміст на вході в репозиторій і на виході з нього: clean запускається під час додавання в індекс (робоче дерево → репозиторій), smudge — на чекауті (репозиторій → робоче дерево). Так працює git-lfs, і так команди вирізають облікові дані чи згенерований шум із того, що потрапляє в коміт.

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

  1. Команда clean запускається на копії кожного відповідного файлу (до п’яти) — ніщо в репозиторії чи його конфізі не зачіпається.
  2. Якщо задано команду smudge, вона запускається на очищеному виводі, і результат порівнюється байт у байт з оригіналом — перевірка оборотності. Фільтр, який її не проходить, означає, що чекаут не поверне того, що у вас було.
  3. Кнопка збереження вмикається лише після пробного прогону рівно на тих значеннях, які ви зберігаєте. Прогін, що не вдався — помилка команди, жоден файл не підійшов або розбіжна оборотність — усе ж можна зберегти, але лише через явне попередження, яке каже, що можна втратити.

Збереження записує filter.<name>.clean/smudge у ваш локальний конфіг git і правило filter=<name> у файл атрибутів, а ще лишає запис скасування, який повертає конфіг до того, що в ньому було раніше. Перемикач required встановлює filter.<name>.required, через що git провалює операцію, замість тихо пропускати файли, коли фільтр зламався.

Межі, названі прямо: пробний прогін бере до п’яти відповідних файлів не більше 5 МБ кожен, із таймаутом 10 секунд на команду — фільтр, що поводиться добре на вибірці, все одно може повестися погано на файлі, якого вибірка не побачила. Команди живуть у вашому конфізі, тож колега, що зробить клон, отримає правило filter=<name>, але не команди; без них (і без required) його файли проходять наскрізь без змін.

Обмеження, про які варто знати

  • text=auto змінює те, що комітиться, нормалізуючи закінчення рядків на вході. У наявному репозиторії додайте його, а потім свідомо виконайте git add --renormalize . окремим комітом.
  • Атрибути не діють заднім числом. Позначивши файл як binary сьогодні, ви не змінюєте того, як зберігалися його минулі діфи; ви змінюєте те, як git ставиться до нього віднині.
  • Правила діють лише там, де файл видно. Правило в design/.gitattributes не каже нічого про src/.
  • Gitcito пише файли цілком, тож файл, відформатований руками, повертається зі своїм форматуванням — але правило, яке Gitcito переписав, форматується до канонічних для git пробілів pattern attr attr.

Дивіться також: LFS і розріджений чекаут · Бандли та архіви · Опції злиття · Хуки

Покращити цей переклад на GitHub