Поясніть, яке правило gitignore - ігнорування мого файлу


310

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

Уявіть, що у мене є такий (або набагато складніший сценарій, із сотнями папок і десятками .gitignoreфайлів:

/
-.gitignore
-folder/
    -.gitignore
    -subfolder/
              -.gitignore
              -file.txt

Якщо я запускаю git add folder/subfolder/file.txtgit, то можна поскаржитися на його ігнорування:

The following paths are ignored by one of your .gitignore files:
folder/subfolder/file.txt
Use -f if you really want to add them.

Чи є спосіб дізнатися, яке з усіх можливих .gitignoreмає правило ігнорувати цей файл, а також показати це правило? Подібно до:

The following paths are ignored by your folder/.gitignore file (line 12: *.txt)
folder/subfolder/file.txt
Use -f if you really want to add them.

Або просто:

$ git why-is-ignored folder/subfolder/file.txt
folder/.gitignore:12:*.txt

4
Примітка: git check-ignoreнезабаром (git1.8.5 / 1.9) з'явиться --no-indexопція. Дивіться мою відповідь нижче
VonC

Примітка: GIT_TRACE_EXCLUDE=1 git statusнезабаром з'явиться додатковий спосіб налагодження .gitignoreправил. Дивіться мою відредаговану відповідь нижче
VonC

Відповідний запис в блозі: danielcompton.net/2016/04/21 / ... .
krlmlr

Відповіді:


643
git check-ignore -v filename

Детальнішу інформацію див. На сторінці чоловіка .

Оригінальна відповідь наступна:

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

ОНОВЛЕННЯ: Вау, це було набагато важче, ніж я очікував. Внутрішнє gitоброблення виключення є досить виразним. У будь-якому випадку, ось вже майже закінчена серія зобов’язань, що стосуються сьогоднішньої masterгілки. Набір тестів завершено на 99%, але я ще не закінчив обробляти цей --stdinваріант. Сподіваюся, мені вдасться це у вихідні, а потім подати свої патчі до списку розсилки git.

Тим часом я обов'язково вітаю тестування від усіх, хто вміє це робити - просто клонуйте з моєї gitвилки , перевірте check-ignoreгілку та скомпілюйте її як звичайну.

ОНОВЛЕННЯ 2: Зроблено! Остання версія розміщена на github, як зазначено вище, і я подав серію патчів до списку розсилки git для експертного огляду. Давайте подивимось, що вони думають ...

ОНОВЛЕННЯ 3: Після ще декількох місяців злому / патч-оглядів / обговорень / очікування я з задоволенням можу сказати, що ця функція вже дійшла до masterгілки Git і буде доступна в наступному випуску (1.8.2, очікується 8-го Березень 2013 р.). Ось check-ignoreсторінка керівництва . Фу, це було набагато більше роботи, ніж я очікував!

ОНОВЛЕННЯ 4: Якщо вас зацікавив повний розповідь про те, як ця відповідь розвивалася та функція стала реалізовуватися, ознайомтеся з епізодом №32 підкасту GitMinutes .


2
Я використовую 1.8.2 і git check-ignoreнічого не роблю.
zakdances

3
@yourfriendzak Без тіні сумнівів, git check-ignoreприсутній і працює в 1.8.2. Якщо поведінка не така, яку ви очікуєте, я пропоную вам (повторно) прочитати сторінку керівництва, і якщо вона все ще не є, будь ласка, надішліть належний звіт про помилку у списку розсилки git. Просто сказати, що нічого не робить, не дуже корисно. Я очікую , що ви, ймовірно , запустити його на не ігнорувати файл і неправильно очікує деякий висновок (хоча я, ймовірно , додати підтримку --show-unmatchedв--verbose режимі виведення в майбутньому).
Адам Шпіерс

1
@AdamSpiers ти маєш рацію. Я повинен був уточнити, що коли я виконую команду, нічого не друкується. Немає повідомлення про помилку, немає повідомлення про успіх, немає інформації. Просто наступне, пусте підказка, що з’являється. Тож я правильно вважаю, що "жодних результатів" в певних обставинах не очікується?
zakdances

1
@AdamSpiers дуже дякую за це! Після 3-х днів розслідування ви щойно допомогли мені з'ясувати причину розбиття через глобально проігнорований файл у .gitignore_global! Я навіть не знав, що це була річ!
BenBtg

3
Не кожен день, коли бачимо, що розробник програми переповнення стека вносить стільки змін для впровадження функції розробника. Вау і повага.
користувач3613932

18

Оновлення git 2.8 (березень 2016 року):

GIT_TRACE_EXCLUDE=1 git status

Див. " Спосіб перевірки .gitignoreфайлу "

Це доповнює git check-ignore -vописане нижче.


Оригінальна відповідь: вересень 2013 року (git 1.8.2, потім 1.8.5+):

git check-ignoreзнову покращується в git 1.8.5 / 1.9 (Q4 2013) :

" git check-ignore" дотримується того самого правила, що і " git add" і "git status " у тому, що механізм ігнорування / виключення не набуває впливу на шляхи, які вже відстежуються.
За допомогою --no-indexпараметра " " можна використовувати для діагностики, які шляхи, які слід було проігнорувати, були помилково додані до індексу .

Див. Запис 8231fa6 з https://github.com/flashydave :

check-ignore В даний час показує, як .gitignore правила поводжуться з нерозкритими шляхами. Відстежені шляхи не дають корисного результату.
Це запобігає налагодженню того, чому шлях несподівано відстежується, якщо цей шлях спочатку не буде видалено з індексу git rm --cached <path>.

Цей параметр --no-indexвказує команді обійти чек для шляху, що знаходиться в індексі, і, отже, дозволяє перевіряти також відстежені шляхи.

Хоча така поведінка відхиляється від характеристик git add та git statusвипадки його використання навряд чи спричинить заплутаність користувачів.

Тестові сценарії доповнені, щоб перевірити цю опцію щодо стандартних ігнорувань, щоб забезпечити правильну поведінку.


--no-index::

Не дивіться в індекс під час здійснення чеків.
Це можна використовувати:

  • налагоджувати, чому шлях відслідковується, наприклад, git add .і не ігнорується правилами, як очікував користувач або
  • при розробці шаблонів, включаючи заперечення, щоб відповідати шляху, раніше доданому git add -f.

4

Я не можу знайти нічого на сторінці вкладки, але ось швидкий і брудний сценарій, який перевірить ваш файл у кожному батьківському каталозі, щоб побачити, чи може бути додано git-add'ed. Запустіть його в каталозі, що містить проблемний файл, як:

test-add.sh STOP_DIR FILENAME

де STOP_DIRкаталог верхнього рівня проекту Git і FILENAMEім'я файлу проблеми (без шляху). Він створює порожній файл з тим самим іменем на кожному рівні ієрархії (якщо він не існує) і намагається git add -nперевірити, чи можна його додати (очищається після себе). Він видає щось на кшталт:

FAILED:    /dir/1/2/3
SUCCEEDED: /dir/1/2

Сценарій:

#!/usr/bin/env bash
TOP=$1
FILE=$2
DIR=`pwd`
while : ; do
  TMPFILE=1
  F=$DIR/$FILE
  if [ ! -f $F ]; then
    touch $F
    TMPFILE=0
  fi
  git add -n $F >/dev/null 2>&1
  if [ $? = 0 ]; then
    echo "SUCCEEDED: $DIR"
  else
    echo "FAILED:    $DIR"
  fi
  if [ $TMPFILE = 0 ]; then
    rm $F
  fi
  DIR=${DIR%/*}
  if [ "$DIR" \< "$TOP" ]; then
    break
  fi
done 

1

Щоб додати до основної відповіді використання git check-ignore -v filename(спасибі BTW), я виявив, що мій файл .gitignore блокує все, оскільки після підстановки з'явився новий рядок, тому у мене було:

* .sublime-project

як приклад. Я щойно видалив новий рядок, і вуаля! Це було виправлено.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.