Заставьте.gitignore игнорировать все, кроме нескольких файлов
Я понимаю, что файл.gitignore скрывает указанные файлы из системы контроля версий Git. У меня есть проект (LaTeX), который генерирует много дополнительных файлов (.auth, .dvi, .pdf, журналы и т. Д.) Во время работы, но я не хочу, чтобы они отслеживались.
Я знаю, что могу (возможно, должен) сделать так, чтобы все эти файлы были помещены в отдельную подпапку в проекте, так как тогда я мог бы просто игнорировать эту папку.
Тем не менее, есть ли способ сохранить выходные файлы в корне дерева проекта и использовать.gitignore, чтобы игнорировать все, кроме файлов, которые я отслеживаю с помощью Git? Что-то вроде
# Ignore everything
*
# But not these files...
script.pl
template.latex
# etc...
32 ответа
Необязательный префикс
!
который отрицает образец; любой соответствующий файл, исключенный предыдущим шаблоном, снова будет включен. Если шаблон с отрицанием соответствует, это переопределит источники шаблонов с более низким приоритетом.
# Ignore everything
*
# But not these files...
!.gitignore
!script.pl
!template.latex
# etc...
# ...even if they are in subdirectories
!*/
# if the files to be tracked are in subdirectories
!*/a/b/file1.txt
!*/a/b/c/*
Если вы хотите игнорировать все содержимое каталога, кроме одного файла внутри него, вы можете написать пару правил для каждого каталога в пути к файлу. Например.gitignore, чтобы игнорировать папку pippo, кроме как в pippo / pluto / paperino.xml
.gitignore
pippo/*
!pippo/pluto
pippo/pluto/*
!pippo/pluto/paperino.xml
Вы хотите использовать /*
вместо *
или же */
в большинстве случаев
С помощью *
допустимо, но работает рекурсивно. Это не будет смотреть на каталоги с тех пор. Люди рекомендуют использовать !*/
снова занести в белый список каталоги, но на самом деле лучше поместить в черный список папку с /*
# Blacklist files/folders in same directory as the .gitignore file
/*
# Whitelist some files
!.gitignore
!README.md
# Ignore all files named .DS_Store or ending with .log
**/.DS_Store
**.log
# Whitelist folder/a/b1/ and folder/a/b2/
# trailing "/" is optional for folders, may match file though.
# "/" is NOT optional when followed by a *
!folder/
folder/*
!folder/a/
folder/a/*
!folder/a/b1/
!folder/a/b2/
!folder/a/file.txt
Приведенный выше код будет игнорировать все файлы, кроме .gitignore
, README.md
, folder/a/file.txt
, folder/a/b1/
а также folder/a/b2/
и все, что содержится в этих двух последних папках. (А также .DS_Store
а также *.log
файлы будут игнорироваться в этих папках.)
Очевидно, я мог бы сделать, например, !/folder
или же !/.gitignore
тоже.
Более подробная информация: http://git-scm.com/docs/gitignore
Немного конкретнее:
Пример: игнорировать все в webroot/cache
- но продолжай webroot/cache/.htaccess
,
Обратите внимание на косую черту (/) после cache
папка:
FAILS
webroot/cache*
!webroot/cache/.htaccess
РАБОТАЕТ
webroot/cache/*
!webroot/cache/.htaccess
Я знаю, что опаздываю на вечеринку, но вот мой ответ.
Как сказал @Joakim, чтобы игнорировать файл, вы можете использовать что-то вроде ниже.
# Ignore everything
*
# But not these files...
!.gitignore
!someFile.txt
но если файл находится во вложенных каталогах, то немного сложно вручную написать правила.
Например, если мы хотим пропустить все файлы в git
проект, но не a.txt
который расположен в aDir/anotherDir/someOtherDir/aDir/bDir/cDir
, Тогда наш .gitignore
будет что-то вроде этого
# Skip all files
*
# But not `aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt`
!aDir/
aDir/*
!aDir/anotherDir/
aDir/anotherDir/*
!aDir/anotherDir/someOtherDir/
aDir/anotherDir/someOtherDir/*
!aDir/anotherDir/someOtherDir/aDir/
aDir/anotherDir/someOtherDir/aDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/
aDir/anotherDir/someOtherDir/aDir/bDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/cDir/
aDir/anotherDir/someOtherDir/aDir/bDir/cDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt
Выше дано .gitignore
файл пропустит все каталоги и файлы, кроме !aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt
Как вы могли заметить, эти правила сложно определить.
Чтобы решить эту проблему, я создал простое консольное приложение с именем git-do-not-ignore, которое сгенерирует правила для вас. Я разместил проект в github с подробной инструкцией.
Пример использования
java -jar git-do-not-ignore.jar "aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt"
Выход
!aDir/
aDir/*
!aDir/anotherDir/
aDir/anotherDir/*
!aDir/anotherDir/someOtherDir/
aDir/anotherDir/someOtherDir/*
!aDir/anotherDir/someOtherDir/aDir/
aDir/anotherDir/someOtherDir/aDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/
aDir/anotherDir/someOtherDir/aDir/bDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/cDir/
aDir/anotherDir/someOtherDir/aDir/bDir/cDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt
Здесь также доступна простая веб-версия
Спасибо.
Была проблема, аналогичная OP, но ни один из 10 лучших ответов на самом деле не работал.
Я наконец узнал следующее
Неправильный синтаксис:
*
!bin/script.sh
Правильный синтаксис:
*
!bin
!bin/script.sh
Объяснение со страницы руководства gitignore:
Необязательный префикс "!" который сводит на нет узор; любой соответствующий файл, исключенный предыдущим шаблоном, снова будет включен. Невозможно повторно включить файл, если родительский каталог этого файла исключен. Git не перечисляет исключенные каталоги по соображениям производительности, поэтому любые шаблоны для содержащихся файлов не имеют никакого эффекта, независимо от того, где они определены.
Это означает, что приведенный выше "Неверный синтаксис" неверен, потому что bin/script.sh
не может быть повторно включен как bin/
игнорируется. Вот и все.
Расширенный пример:
$ tree.
.
├── .gitignore
└── bin
├── ignore.txt
└── sub
└── folder
└── path
├── other.sh
└── script.sh
$ cat.gitignore
*
!.gitignore
!bin
!bin/sub
!bin/sub/folder
!bin/sub/folder/path
!bin/sub/folder/path/script.sh
$ git status --untracked-files --ignored
On branch master
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
.gitignore
bin/sub/folder/path/script.sh
Ignored files:
(use "git add -f <file>..." to include in what will be committed)
bin/ignore.txt
bin/sub/folder/path/other.sh
nothing added to commit but untracked files present (use "git add" to track)
Чтобы игнорировать некоторые файлы в каталоге, вы должны сделать это в правильном порядке:
Например, игнорируйте все в папке "application", кроме index.php и папки "config", обратите внимание на порядок.
Вы должны отрицать, что хотите сначала.
FAILS
application/*
!application/config/*
!application/index.php
РАБОТАЕТ
!application/config/*
!application/index.php
application/*
Ты можешь использовать git config status.showUntrackedFiles no
и все неотслеживаемые файлы будут скрыты от вас. Увидеть man git-config
для деталей.
Так я сохраняю структуру папок, игнорируя все остальное. У вас должен быть файл README.md в каждом каталоге (или .gitkeep).
/data/*
!/data/README.md
!/data/input/
/data/input/*
!/data/input/README.md
!/data/output/
/data/output/*
!/data/output/README.md
Чтобы исключить папку из.gitignore, можно сделать следующее.
!app/
app/*
!app/bower_components/
app/bower_components/*
!app/bower_components/highcharts/
Это будет игнорировать все файлы / подпапки внутри bower_components
кроме /highcharts
,
По этому поводу есть куча похожих вопросов, поэтому я выложу то, что написал ранее:
Единственный способ заставить это работать на моей машине - это сделать так:
# Ignore all directories, and all sub-directories, and it's contents:
*/*
#Now ignore all files in the current directory
#(This fails to ignore files without a ".", for example
#'file.txt' works, but
#'file' doesn't):
*.*
#Only Include these specific directories and subdirectories and files if you wish:
!wordpress/somefile.jpg
!wordpress/
!wordpress/*/
!wordpress/*/wp-content/
!wordpress/*/wp-content/themes/
!wordpress/*/wp-content/themes/*
!wordpress/*/wp-content/themes/*/*
!wordpress/*/wp-content/themes/*/*/*
!wordpress/*/wp-content/themes/*/*/*/*
!wordpress/*/wp-content/themes/*/*/*/*/*
Обратите внимание, как вы должны явно разрешить контент для каждого уровня, который вы хотите включить. Так что, если у меня есть подкаталоги 5 глубоко под темами, мне все еще нужно разобрать это.
Это из комментария @ Ярина здесь: /questions/27976168/ispolzovaniegitignore-dlya-ignorirovaniya-vsego-krome-opredelennyih-katalogov/27976178#27976178
Это были полезные темы:
- Как работают шаблоны с отрицанием в.gitignore?
- Как на самом деле работают правила исключения из gitignore?
Я тоже пробовал
*
*/*
**/**
а также **/wp-content/themes/**
или же /wp-content/themes/**/*
Ничто из этого не сработало для меня. Много следов и ошибок!
Вот как я это сделал:
# Ignore everything
*
# Whitelist anything that's a directory
!*/
# Whitelist some files
!.gitignore
# Whitelist this folder and everything inside of it
!wordpress/wp-content/themes/my-theme/**
# Ignore this folder inside that folder
wordpress/wp-content/themes/my-theme/node_modules
# Ignore this file recursively
**/.DS_Store
Использовать gig status -u
для рекурсивного просмотра отдельных файлов в неотслеживаемых каталогах - с git status
вы увидите только папки, которые могут обмануть вас, если вы подумаете, что все внутри них отслеживается
Не уверен, что это уже было указано, но у меня возникли проблемы с игнорированием подпапки внутри игнорируемой папки с помощью!
перед папкой, которую я хочу игнорировать gitignore.
Однако я понял, что папка, которая игнорировалась, не имеет пути. Мой .gitignore выглядел так:
/folder/
!/folder/subfolder
Подпапка по-прежнему игнорировалась, но добавление*
после того, как папка заставила его работать так
/folder/*
!/folder/subfolder
У меня была проблема с подпапкой.
Не работает:
/custom/*
!/custom/config/foo.yml.dist
Работает:
/custom/config/*
!/custom/config/foo.yml.dist
Я перепробовал все ответы, приведенные выше, но у меня не получилось. Прочитав документацию gitignore ( здесь), я обнаружил, что если вы сначала исключите папку, то имена файлов в подпапке не будут проиндексированы. Поэтому, если впоследствии вы используете восклицательный знак для включения файла, он не будет найден в индексе и, следовательно, не будет включен в ваш git-клиент.
Это был способ найти решение. Я начал с добавления исключений для всех подпапок в моем дереве папок, чтобы оно заработало, что является адской работой. После этого я смог сжать подробную конфигурацию до конфигурации ниже, что немного противоречит документации.
Рабочая.gitignore:
# Ignore the 'Pro' folder, except for the '3rdparty' subfolder
/Pro/*
!Pro/3rdparty/
# Ignore the '3rdparty' folder, except for the 'domain' subfolder
/Pro/3rdparty/*
!Pro/3rdparty/domain/
# Ignore the 'domain' folder, except for the 'modulename' subfolder
Pro/3rdparty/domain/*
!Pro/3rdparty/domain/modulename/
В результате я вижу в своем git-клиенте, что только два файла в папке Pro/3rdparty/domain/modulename/ готовятся к следующему коммиту, и это именно то, что я искал.
И если вам нужно внести в белый список несколько подпапок одной и той же папки, сгруппируйте строки восклицательного знака под оператором exclude следующим образом:
# Ignore the 'Pro' folder, except for the '3rdparty' subfolder
/Pro/*
!Pro/3rdparty/
# Ignore the '3rdparty' folder, except for the 'domain' & 'hosting' subfolders
/Pro/3rdparty/*
!Pro/3rdparty/domain/
!Pro/3rdparty/hosting/
# Ignore the 'domain' folder, except for the 'modulename' subfolder
Pro/3rdparty/domain/*
!Pro/3rdparty/domain/modulename/
# Ignore the 'hosting' folder, except for the 'modulename' subfolder
Pro/3rdparty/hosting/*
!Pro/3rdparty/hosting/modulename/
Иначе это не будет работать, как ожидалось.
здесь много сложных ответов ... вот что-то довольно простое, чего я не вижу выше и хорошо работает во многих сценариях:
# ignore all files that have an extension
**/*.*
# except for these extensions
!**/*.extension1
!**/*.extension2
это не игнорирует файлы без расширений, но если у вас есть группа, у которых все имеют одинаковое или похожее имя, вы можете добавить исключения для этих
**/EXTENSIONLESSFILETOIGNORE
Вот что сработало для меня, я хотел добавить в репозиторий только один плагин Cordova:
...
plugins/*
!plugins/cordova-plugin-app-customization
Самый простой способ сделать это - принудительно добавить файл. Он будет учтен в git, даже если он похоронен или вложен в дерево подкаталогов, игнорируемое git.
Например:
Папка x64 исключена в.gitignore:
x64/
Но вы хотите включить файл
myFile.py
находится в
x64/Release/
каталог. Тогда вам необходимо:
git add -f x64/Release/myFile.py
Вы можете сделать это для нескольких файлов файлов, которые соответствуют шаблону, например
git add -f x64/Release/myFile*.py
и так далее.
У меня есть Jquery и Angular от беседки. Бауэр установил их в
/public_html/bower_components/jquery/dist/bunch-of-jquery-files
/public_html/bower_components/jquery/src/bunch-of-jquery-source-files
/public_html/bower_components/angular/angular-files
Минимизированный JQuery находится внутри dist
каталог и угловой внутри angular
каталог. Мне нужно было только свернутые файлы для передачи на github. Некоторое вмешательство в.gitignore, и это то, что мне удалось наколдовать...
/public_html/bower_components/jquery/*
!public_html/bower_components/jquery/dist
/public_html/bower_components/jquery/dist/*
!public_html/bower_components/jquery/dist/jquery.min.js
/public_html/bower_components/angular/*
!public_html/bower_components/angular/angular.min.js
Надеюсь, кто-то может найти это полезным.
Простое решение, если вам нужно игнорировать все, кроме нескольких файлов и нескольких корневых папок:
/*
!.gitignore
!showMe.txt
!my_visible_dir
Магия в /*
(как описано выше) он игнорирует все в папке, но НЕ рекурсивно.
Я получил это работает
# Vendor
/vendor/braintree/braintree_php/*
!/vendor/braintree/braintree_php/lib
Пока у меня ничего не получалось, потому что я пытался добавить одну банку из lib.
Это не сработало:
build/*
!build/libs/*
!build/libs/
!build/libs/myjarfile.jar
Это сработало:
build/*
!build/libs
У меня также были некоторые проблемы с отрицанием отдельных файлов. Я смог их зафиксировать, но моя IDE (IntelliJ) всегда жаловалась на игнорируемые файлы, которые отслеживаются.
git ls-files -i --exclude-from .gitignore
Отображены два файла, которые я исключил таким образом:
public/
!public/typo3conf/LocalConfiguration.php
!public/typo3conf/PackageStates.php
В конце концов, это сработало для меня:
public/*
!public/typo3conf/
public/typo3conf/*
!public/typo3conf/LocalConfiguration.php
!public/typo3conf/PackageStates.php
Ключ был отрицанием папки typo3conf/
первый.
Кроме того, похоже, что порядок утверждений не имеет значения. Вместо этого вам нужно явно отменить все подпапки, прежде чем вы сможете отменить отдельные файлы в нем.
Папка !public/typo3conf/
и содержимое папки public/typo3conf/*
две разные вещи для.gitignore.
Отличная тема! Эта проблема беспокоила меня некоторое время;)
Это катастрофа, что после 16 лет (2005) использования
git
, нет простого и очевидного способа исключить один файл, расположенный глубоко в иерархии каталогов, который в противном случае следует игнорировать. Вместо этого нам нужно прибегать к безумным вещам, таким как многократное копание в структуре и исключение и включение каталогов в правильном порядке. Чего-то чертовски невозможного запомнить те 4 раза в год, которые нужно делать.
Единственная умная, но очень странная альтернатива — использовать
git add --force
. Что-то, что обязательно потерпит неудачу в какой-то момент, когда вы не работаете только с gitted репо.
Поэтому я написал небольшую функцию bash, чтобы исправить это для вас, чтобы упростить копирование и вставку. Позвольте мне сначала объяснить один лайнер:
f=0; y='';for x in $(echo "uploads/rubbish/stuff/KEEP_ME/a.py" | tr '\/' '\n'); do y="$y/$x"; if [ $(($f)) -eq 0 ]; then y="$x"; f=1; fi; echo -e '!'"$y/\n$y/*"; done | sed '$d' |sed -z 's/..$//'; echo;
# output:
!uploads/
uploads/*
!uploads/rubbish/
uploads/rubbish/*
!uploads/rubbish/stuff/
uploads/rubbish/stuff/*
!uploads/rubbish/stuff/KEEP_ME/
uploads/rubbish/stuff/KEEP_ME/*
!uploads/rubbish/stuff/KEEP_ME/a.py
Описание
- Существует оператор для корректировки 1-го элемента, не получающего .
-
tr '\/' '\n'
- перевести/
к\n
в стандартных путях POSIX (чтобы получить список) -
y="$y/$x"
- добавить следующий подкаталог (в списке) после предыдущего каталога . -
echo -e '!'"$y/\n$y/*"
-
напечатать 2 строки элемента подкаталога, 1-я с!
префикс и 2-й с постфиксом . -
sed '$d'
- удалить последнюю строку -
sed -z 's/..$//'
- удалить последние 2 символа/*
с последней строки
Затем мы создаем функцию:
function gitkeep () { f=0; y='';for x in $(echo "$1" | tr '\/' '\n'); do y="$y/$x"; if [[ f -eq 0 ]]; then y="$x"; f=1; fi; echo -e '!'"$y/\n$y/*"; done | sed '$d' |sed -z 's/..$//'; echo; }
# gitkeep "uploads/rubbish/stuff/KEEP_ME/a"
!uploads/
uploads/*
!uploads/rubbish/
uploads/rubbish/*
!uploads/rubbish/stuff/
uploads/rubbish/stuff/*
!uploads/rubbish/stuff/KEEP_ME/
uploads/rubbish/stuff/KEEP_ME/*
!uploads/rubbish/stuff/KEEP_ME/a
Здесь я упростил арифметику
if
заявление
if [[ f -eq 0 ]];
.
Наслаждаться!
Кажется, я нашел что-то, что сработало для меня, о чем больше никто не упоминал.
# Ignore everything
*
# But not these files...
!.gitignore
!script.pl
!template.latex
# etc...
# And if you want to include a sub-directory and all sub-directory and files under it, but not all sub-directories
!subdir/
!subdir/**/*
В принципе, похоже, что подкаталог не игнорируется, у вас должно быть две записи, одна для самого подкаталога !subdir/
а затем еще один, который расширяется до всех файлов и папок под ним !subdir/**/*
Суть
# Ignore everything
*
# But not these files...
!script.pl
!template.latex
И, вероятно, включают:
!.gitignore
Ссылка
С https://git-scm.com/docs/gitignore:
Необязательный префикс "
!
"что исключает шаблон; любой соответствующий файл, исключенный предыдущим шаблоном, будет снова включен. Невозможно повторно включить файл, если родительский каталог этого файла исключен. Git не перечисляет исключенные каталоги по соображениям производительности, поэтому любые шаблоны для содержащихся файлов не действуют, независимо от того, где они определены. Поместите обратную косую черту ("\
") перед первым"!
"для шаблонов, которые начинаются с буквального"!
", например, "\!important!.txt
"....
Пример исключения всего, кроме определенного каталога
foo/bar
(Обратите внимание/*
- без косой черты подстановочный знак также исключает все в пределахfoo/bar
):$ cat .gitignore # exclude everything except directory foo/bar /* !/foo /foo/* !/foo/bar
Через github.com/gitinclude вы можете загрузить инструмент командной строки (для Windows, Linux и OSX) для включения глубоко вложенных наборов файлов.
Определите наборы файлов в
.gitinclude
и запустите инструмент (с помощью двойного щелчка или командной строки). Ваш
.gitignore
теперь обновляется.
Далее в структуре каталогов используйте отдельный .gitignore.
root
|- subdirA
|- subdirA1
|- file1.txt
|- file2.txt
|- README.md
|- .gitignore
Используйте .gitignore в корне, но тогда в root/subdirA/subdirA1 это будет содержимое .gitignore.
*
!README.md
Надеюсь, это поможет!
Содержимое файла должно быть похоже на следующее
*
!app.py
!local.conf
!requirements.txt
!Dockerfile
!selenium_test/
selenium_test/*
!selenium_test/seleniumTest.py
!selenium_test/seleniumTest2.py
!selenium_test/seleniumTest3.py
Здесь с помощью '*' мы все игнорируем.
Но с '!' мы говорим включить что-то. Сюда включены app.py, local.conf, require.txt и Dockerfile.
Теперь включаем папку selenium_test с '!', потому что нам нужно немного файлов из этой папки.
Но в следующей строке мы исключаем все содержимое папки с selenium_test/*, потому что нам не нужны все файлы из этой папки, а нужны только некоторые из них.
Далее мы указываем включение файлов seleniumTest.py, seleniumTest2.py и seleniumTest3.py, которые существуют в папке selenium_test.
Примечание: если бы мы не добавили 6-ю и 7-ю строки, то 8-я, 9-я и 10-я строки не работали бы, поскольку файлы, указанные в этих строках, не получили бы папку «selenium_test», потому что мы ее уже исключили. в первой строке через '*'.