цель / против / цель / в .gitignore - PullRequest
1 голос
/ 14 июня 2019

Я использую Eclipse (это, вероятно, не имеет значения), и я хочу исключить целевую папку Maven из коммита.

Есть лотов нотаций

  1. /target/**
  2. */target/*
  3. /target/**
  4. target/
  5. /target/

Что такоеразница?

А какой точный смысл у каждого из них?

1 Ответ

3 голосов
/ 15 июня 2019

TL; DR: вы, вероятно, хотите /target/.

Long

Давайте начнем с четкого определения рабочего дерева (из gitglossary , где оно написано рабочее дерево ) :

Дерево актуальных извлеченных файлов. Рабочее дерево обычно содержит содержимое дерева фиксации HEAD , а также любые локальные изменения, которые вы внесли, но еще не зафиксировали.

Мы должны помнить, что то, что Git хранит и обменивается с другими репозиториями Git, это коммиты . Каждый коммит на все время замораживает некоторый набор файлов, так что в любой момент в будущем вы можете сказать Git get me commit a123456... и вернуть все ваши файлы обратно на момент совершения коммита a123456.... (У каждого коммита есть уникальный большой и ужасный хеш-идентификатор, подобный этому, который вы увидите в выходных данных git log и других местах.)

фиксирует в сравнении с рабочим деревом

Файлы внутри коммитов хранятся в специальной, только для Git, сжатой, дедуплицированной и доступной только для чтения форме. Мне нравится называть эти файлы сублимированным . Они буквально не могут быть изменены. Так что они хороши для архивирования, но совершенно бесполезны для выполнения любой реальной работы . Следовательно, Git должен иметь возможность извлекать любой заданный коммит, "повторно увлажняя" высушенные сублимацией файлы и превращая их обратно в обычные повседневные файлы, которые вы можете просматривать, использовать и использовать. Место, куда вы помещаете эти файлы, - рабочее дерево или рабочее дерево .

В рабочем дереве, конечно, есть каталог верхнего уровня (или папка, если вы предпочитаете этот термин), в котором вы храните различные файлы, включая ваш основной файл .gitignore. Этот каталог верхнего уровня может иметь подкаталоги (подпапки), и у каждой подпапки также может быть свой собственный файл .gitignore. Это важно, когда вы спрашиваете о /target против target, например.

Gitignore записи

Запись в файле .gitignore может быть в любой из следующих форм:

  • name (без специальных символов, таких как *)
  • name.* или *.txt или даже name*txt
  • folder/
  • folder/*
  • folder/name
  • folder/name*txt или любой из этих вариантов
  • folder/subfolder/
  • folder/subfolder/*
  • любой из вышеперечисленных префиксов с косой чертой, например, /name или /folder/ или /folder/name
  • любой из вышеперечисленных, включая префикс с косой чертой, к которому затем также добавляется !, например, !/folder/name

Это не полный список (вы перечислили несколько других форм), а скорее, чтобы проиллюстрировать несколько основных принципов:

  1. Простое имя файла означает любой файл или каталог с этим именем .
  2. Имя с суффиксом с косой чертой означает любой каталог (папку) с этим именем . Объекты, которые являются файлами, не соответствуют этому виду записи.
  3. Записи могут иметь встроенные косые черты - косые черты, которые находятся не спереди и не сзади, например folder/name.
  4. Записи могут иметь начальные косые черты , например /name или /folder/, или обе начальные косые черты и встроенные косые черты, такие как /folder/name .
  5. Записи могут содержать glob символов, * и ** в разных местах.
  6. Записи могут начинаться с префикса !.

Правила для записей gitignore становятся довольно сложными, но начинаются достаточно просто. Помните, что .gitignore может находиться в папке верхнего уровня вашего рабочего дерева или в некоторой подпапке!

  • Простое имя без встроенных или начальных слешей соответствует любому файлу или папке в любом месте этой папки или любой из ее подпапок.
  • Имя с суффиксом косой черты, без встроенных или начальных косых черт, соответствует любой папке (но не файлу) из этой папки или любой из ее подпапок.
  • Если у записи есть префикс косой черты или и встроенный слеш - достаточно одного - запись соответствует только файлам и / или папкам в этой папке . Следовательно, folder/name и /folder/name означают то же самое: соответствует файлу (или папке) с именем folder/name в этой папке , то есть месте, содержащем файл .gitignore , Не сопоставлять файл sub/folder/name, например.
  • Если запись заканчивается косой чертой, она соответствует только папкам (независимо от чего-либо еще).

Вы сказали:

Я хочу исключить целевую папку Maven

Для этого требуется ответить на подвопрос: Где существует эта целевая папка Maven? Есть ли только одна такая папка, или в подпапках могут быть target/ сущности? (Есть также отдельная проблема, заключающаяся в том, что директивы .gitignore не совсем понимают, что люди думают, и что вам нужно обратить внимание на то, что находится в вашем index , но мы оставим это для другого раздела.)

Если это означает: Не включайте ничего в target на верхнем уровне моего рабочего дерева, но продолжайте и включите, например, файлы с именем sub/target/file, тогда вам следует использовать :

/target/

как полное правило в .gitignore на верхнем уровне вашего рабочего дерева. Это немного избыточно, так как вы уже знаете, что /target - это папка, но ясно показывает, что вы хотите игнорировать папку с именем target на верхнем уровне вашей работы. дерево.

Если это означает: Не включать ничего в build-artifacts/target/, тогда вы можете поставить:

build-artifacts/target/

или: * * 1 201

/build-artifacts/target/

на верхний уровень .gitignore; или Вы можете поставить:

/target/

в build-artifacts/.gitignore. В build-artifacts/.gitignore требуется начальная косая черта, потому что /target/ не имеет встроенной косой черты, в то время как в верхнем уровне .gitignore не требуется начальная косая черта, поскольку в ней есть встроенная косая черта.

Если, с третьей стороны (первый шаг?), Необходимо игнорировать все файлы в любой папке, путь к папке которой содержит a target компонент - например, вы хотите не только игнорировать target/file, но также sub/target/file2 и sub/target/sub2/file3 - тогда вы должны использовать:

target/

как ваша запись .gitignore, вероятно, на верхнем уровне вашего рабочего дерева.

Роль указателя / staging-area

Файлы .gitignore содержат информацию о вашем рабочем дереве 1238 *, но Git не создает новые коммиты из вашего рабочего дерева. Вместо этого Git создает новые коммиты из промежуточной вещи, которую он вызывает, по-разному, index или область подготовки . (Эти два термина относятся к одной и той же сущности.)

Хотя у индекса есть и другие роли, его главная роль, особенно для наших целей, заключается в том, что он содержит копию каждого файла из оригинального извлеченного вами коммита, или обновленную копию или полностью новый файл. То есть, если вы извлекли коммит, в котором было просто из двух файлов file1 и folder/file2, в вашем индексе теперь будут копии file1 и folder/file2.

Копии внутри индекса находятся в том же самом лиофилизированном формате, что и копии внутри фиксации. Разница в том, что вы можете заменить копии в индексе - или добавить к ним, или даже вычесть их. Таким образом, вы можете запустить git add file1, чтобы взять полезную версию file1 в вашем рабочем дереве, заморозить его и вставить в индекс. Вы можете сделать то же самое с folder/file2, и вы можете поместить новые файлы, такие как folder2/file3 или ./file4. Короче говоря, git add делает замораживание версии файла рабочего дерева и помещает ее в индекс.

Когда уВы запускаете git commit, Git просто упаковывает все, что есть в индексе , прямо тогда и делает из него новый коммит. Вот почему вы должны git add файлы постоянно: каждый раз, когда вы меняете копию рабочего дерева, вам нужно обновить индексную копию, иначе Git не сохранит новую версию: Git просто сохранит старую копию версия снова. (Чтобы сэкономить место, коммиты, которые сохраняют ту же версию старого файла, на самом деле просто повторно используют старый высушенный замораживанием файл. Они могут сделать это , поскольку эти файлы доступны только для чтения . Всегда безопасно найти старую копию и использовать ее повторно, потому что по определению все внутри Git заморожено на все времена. Изменять можно только копии индекса и рабочего дерева!)

Другими словами, вы можете думать об индексе как о предложенном следующем коммите . Вы копируете в него файлы для обновления предложенного следующего коммита . Чтобы полностью удалить файл из предложенного следующего коммита, вы используете git rm --cached или git rm (без --cached): Git удалит файл из индекса, а может и из рабочего дерева тоже и теперь у предложенного вами следующего коммита просто нет файла.

Файл может находиться в области индекса / размещения и в рабочем дереве. Это случается все время. Такой файл называется tracked . Содержимое не обязательно должно совпадать: только тот факт, что файл находится в индексе прямо сейчас , а также в рабочем дереве, делает файл рабочего дерева отслеживаемым.

Если файл отслеживается - если он находится в индексе прямо сейчас - тогда ничто из того, что вы делаете с .gitignore, никак не повлияет на него. Чтобы не отслеживалось, вы должны удалить его из индекса.

Если вы удалите файл из индекса - или если он уже не находится в индексе, потому что его не было в коммите, который вы извлекли ранее - тогда копия рабочего дерева будет неотслеживаемой . Теперь имеет значение .gitignore. Запись .gitignore сообщает Git:

  • Не жалуйтесь на этот файл. Обычно git status будет скулить на вас, сообщая, что файл не прослежен и, черт возьми, господи, не правда ли, git add Это? .gitignore заставляет Git замолчать об этом файле.

  • Не добавляйте этот файл автоматически. Если вы используете git add . или git add * или что-то в этом роде, вы говорите Git: add all. .gitignore изменяет это так: добавить все - кроме эти неотслеживаемые файлы, которые также игнорируются, не добавляйте их!

  • Он имеет третий эффект, который заключается в предоставлении разрешения Git для clobber файла рабочего дерева в некоторых (редких) случаях и для изменения способа работы git clean с -x и -X.

Действительно, файл должен называться не .gitignore, а скорее как .git-dont-whine-about-these-files-and-do-not-auto-add-them-either-and-maybe-occasionally-do-clobber-or-clean-them. Но кто хочет печатать это все время? Итак, .gitignore.

Заключение

Существует еще больше информации о .gitignore записях, но это уже достаточно долго (может быть, слишком долго). Итоговая версия:

  • .gitignore влияет только на неотслеживаемых файлов;
  • это в основном о том, чтобы прекратить нытье и избегать автоматического добавления; и
  • используйте косую черту для обозначения directory / folder (какое бы слово вы ни выбрали) и начальную косую черту для обозначения , как в this directory . Когда у вас есть сложные записи (со встроенными слешами), начальный слеш избыточен, но передает ваше намерение.

Если вы не хотите использовать эффект начального слеша, но do нуждаются во встроенных слешах, вы должны либо распределить записи игнорирования в подкаталоги / подпапки, или используйте обозначение ** (в качестве ведущего компонента), чтобы сопоставить любое количество компонентов пути. В противном случае редко возникает необходимость в **.

Нездесь: когда Git понимает, что ему не нужно читать каталог рабочего дерева, он не беспокоится о его чтении. В результате игнорирование подкаталога обычно делает невозможным игнорирование (с ! правилами) чего-либо в подкаталоге.

...