Как мне настроить git на локальное игнорирование некоторых файлов?

1351

Могу ли я игнорировать файлы локально, не загрязняя глобальные настройки git для всех остальных? У меня есть неотслеживаемые файлы, которые являются спамом, в моем состоянии git, но я не хочу фиксировать изменения конфигурации git для каждого небольшого случайного неотслеживаемого файла, который есть в моих локальных ветках.

Bjorn
источник

Ответы:

1864

Из соответствующей документации Git :

Шаблоны, которые являются специфическими для конкретного репозитория, но которые не должны использоваться совместно с другими связанными репозиториями (например, вспомогательные файлы, которые находятся внутри репозитория, но специфичны для рабочего процесса одного пользователя), должны быть помещены в $GIT_DIR/info/excludeфайл.

.git/info/excludeФайл имеет тот же формат , как и любой .gitignoreфайл. Другой вариант - установить core.excludesFileимя файла, содержащего глобальные шаблоны.

Обратите внимание, что если у вас уже есть нетегированные изменения, вы должны выполнить следующее после редактирования шаблонов игнорирования:

git update-index --assume-unchanged <file-list>

Примечание$GIT_DIR : это обозначение используется во всем руководстве по git просто для указания пути к хранилищу git. Если задана переменная окружения, она будет переопределять местоположение любого репо, в котором вы находитесь, что, вероятно, не то, что вам нужно.


Изменить : Другой способ заключается в использовании:

git update-index --skip-worktree <file-list>

Обратитесь к этому:

git update-index --no-skip-worktree <file-list>
Джош Ли
источник
204
Как примечание, обязательно запустите git update-index --assume-unchanged [<file>...]после внесения дополнения в исключаемый файл. Изменения не будут приняты до тех пор.
Tollmanz
30
Мне не нужно было запускать git update-index ..., чтобы изменения вступили в силу с помощью git 1.7.9.5.
Джеффри Мартинес
39
Вам нужно использовать git update-index только в том случае, если вы уже внесли изменения в файл и теперь хотите, чтобы он игнорировался. Если вы изменили исключить до внесения изменений, это не обязательно.
Брэди Эмерсон
13
Хотя это предотвращает появление файла как измененного во время коммитов, таких как .gitignore, в отличие от игнорируемых файлов, файл (ы) все равно будет сброшен обратно в версию репо, если вы выполните git reset --hard.
Брэди Эмерсон
19
Для stackoverflow.com/questions/23097368/… и stackoverflow.com/questions/13630849/… , skip-worktreeскорее всего, предпочтительнее assume-unchanged.
danShumway
436

Обновление : рассмотрите возможность использования git update-index --skip-worktree [<file>...]вместо этого, спасибо @danShumway! См. Объяснение Бореалида о различии двух вариантов .


Старый ответ:

Если вам нужно игнорировать локальные изменения в отслеживаемых файлах (у нас это происходит с локальными изменениями в конфигурационных файлах), используйте git update-index --assume-unchanged [<file>...].

Флориан Сессер
источник
8
Просто чтобы заметить, я добавил файл в $ GIT_DIR / info / exclude (например, my-file.php) и затем должен был запустить git update-index --assume-unchanged my-file.phpего, чтобы его начали игнорировать. Спасибо за совет!
Tollmanz
78
Чтобы отменить это: git update-index --no-assume-unchanged my-file.php
Рэй
18
Просто для пояснения: предположим, что без изменений это для отслеживаемых файлов (существует в репо) ... ОП запрашивал неотслеживаемые файлы, в этом случае .git/info/excludeвы хотите (чтобы не загрязнять часто используемые и отслеживаемые .gitignore)
dyodji
7
Согласно stackoverflow.com/questions/23097368/… это считается небезопасным, и ваши файлы все еще могут быть зафиксированы, если вы не будете осторожны. Он предназначен для повышения производительности, а не как надежное решение этой проблемы.
danShumway
3
Я поспешил, --assume-unchangedпрежде чем читать ваше обновление . Я расстался с, --no-assume-unchangedа затем сделал --skip-worktree... Я в чистоте?
Николас Миари
162

Добавьте следующие строки в раздел [alias] вашего файла .gitconfig

ignore = update-index --assume-unchanged
unignore = update-index --no-assume-unchanged
ignored = !git ls-files -v | grep "^[[:lower:]]"

Теперь вы можете использовать, git ignore my_fileчтобы игнорировать изменения в локальном файле и git unignore my_fileпрекратить игнорировать изменения. git ignoredсписки игнорируемых файлов.

Этот ответ был получен с http://gitready.com/intermediate/2009/02/18/temporary-ignoring-files.html .

phatmann
источник
1
"! git ls-files -v | grep" ^ [[: lower:]] "- Есть ли шанс, что вы знаете, как это сделать на Windows
CMD
3
Установите настоящую оболочку (например, Babun предоставляет bash или zsh);) Я знаю ваши чувства, но недавно я перешел с Windows на Linux и больше никогда не буду использовать cmd.
Xerus
@Haohmaru, вы всегда можете использовать WSL (подсистема Windows для Linux).
Sz
110

У вас есть несколько вариантов:

  • Оставьте грязный (или незафиксированный) .gitignoreфайл в рабочем каталоге (или примените его автоматически с помощью topgit или другого такого инструмента исправления).
  • Поместите исключения в ваш $GIT_DIR/info/excludeфайл, если это относится только к одному дереву.
  • Запустите git config --global core.excludesfile ~/.gitignoreи добавьте шаблоны к вашему ~/.gitignore. Этот параметр применяется, если вы хотите игнорировать определенные шаблоны для всех деревьев. Я использую это для .pycи .pyoфайлов, например.

Кроме того, убедитесь, что вы используете шаблоны, а не явно перечислите файлы, если это применимо.

Эмиль Сит
источник
10
Я думаю, что вам нужно git config --globalустановить глобальную опцию.
Джош Ли
7
На самом деле, просто добавьте .gitignore к .gitignore;)!
Доминик Георгий
68

Я думаю, что вы ищете:

git update-index --skip-worktree FILENAME

которые игнорируют изменения, сделанные локально

Вот http://devblog.avdi.org/2011/05/20/keep-local-modifications-in-git-tracked-files/ более подробное описание этих решений!

отменить использование:

git update-index --no-skip-worktree FILENAME
Петр Корлага
источник
9
Существует и соответствующая дискуссия между --skip-worktreeи --assume-unchangedна этот вопрос SO
Merwer
1
Как бы я отменил это или увидел список файлов / шаблонов, через которые в данный момент игнорируются --skipworktree, если я потом передумаю и захочу снова начать отслеживать файл?
Аномалия
1
как отменить это?
user1735921
3
Чтобы отменить, пожалуйста, используйтеgit update-index --no-skip-worktree <file>
user1735921
49

Вы можете установить некоторые псевдонимы git, чтобы упростить этот процесс. Это редактирует [alias]узел вашего .gitconfigфайла.

git config --global alias.ignore 'update-index --skip-worktree'
git config --global alias.unignore 'update-index --no-skip-worktree'
git config --global alias.ignored '!git ls-files -v | grep "^S"'

Ярлыки, которые это устанавливает для вас, следующие:

  • git ignore config.xml
    • git будет делать вид, что не видит никаких изменений, что config.xmlне позволяет вам случайно зафиксировать эти изменения.
  • git unignore config.xml
    • git возобновит подтверждение ваших изменений и config.xmlпозволит вам снова зафиксировать эти изменения.
  • git ignored
    • git перечислит все файлы, которые вы «игнорируете», как описано выше.

Я построил их, ссылаясь на ответ phatmann - который представляет --assume-unchangedверсию того же самого.

Версия, которую я представляю, использует --skip-worktreeдля игнорирования локальных изменений. См . Ответ Бореалида для полного объяснения различий, но, по сути --skip-worktree, цель состоит в том, чтобы разработчики могли изменять файлы без риска их изменения .

git ignoredКоманда , представленная здесь использует git ls-files -vи фильтрует список , чтобы показать только те записи , начиная с Sтега. SТег обозначает файл, статус которого является «пропустить worktree». Для полного списка статусов файлов, показанных git ls-files: см. Документацию для -tопции на git ls-files.

Birchlabs
источник
1
Это не работает для неотслеживаемых файлов: <(git 2.13.5 на osx)
Terra Ashley,
Это '!' должен быть в '!git ls-files -v | grep "^S"'? Команда не работает для меня с этим там .. и, кажется, работает нормально с ее удалением.
Тирис
восклицательный знак в псевдониме git указывает git запускать внешнюю команду , а не подкоманду git . Я вставил его, потому что мне нужен конвейер оболочки, поэтому мне нужно вызывать git извне. Я только что попытался удалить восклицательный знак (согласно вашей рекомендации), но это не работает для меня. Я получаю Expansion of alias 'ignored' failed; 'git' is not a git command. Это имеет смысл; без восклицательного знака: git псевдоним вашей команды git git ls-files ….
Birchlabs
Спасибо за объяснение. Я не знаком с псевдонимом git и просто выполнял тестирование в оболочке перед созданием псевдонима.
Тирис
Это блестящее решение. Поскольку git отслеживает каждый каталог, при запуске указанного выше псевдонима git ignore <filename>он применяется только к этому каталогу. И когда вы, наконец, захотите внести свои изменения в этот файл, зафиксировать и передать на удаленный компьютер, просто используйте удобный инструмент, git unignore <filename>чтобы временно начать отслеживать его снова! Спасибо!
Nickang
42

Вы можете просто добавить файл .gitignore в свой домашний каталог, то есть $HOME/.gitignoreили ~/.gitignore. Затем скажите git использовать этот файл с командой:

git config --global core.excludesfile ~/.gitignore

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

Я использовал этот подход в течение многих лет с отличными результатами.

JESii
источник
Спасибо, @EricChen. Я обновил ответ; попробуйте, а затем используйте git check-ignore <file-name>для проверки. ЛМК, если у тебя это работает
JESii
Это работало только для меня без =:git config --global core.excludesfile ~/.gitignore
Е. Сундин
Я поместил .gitignoreфайл в домашний каталог и сказал git использовать его вместо этого, затем удалил файлы, которые я хотел бы отследить локально. Однако после того, как я отправил изменения, удаленный репозиторий также удалил эти файлы. Я сделал что-то неправильно?
Зы
Вау, @xyz; .gitignoreо игнорировании файлов, которые существуют в вашем локальном каталоге. То, что вы должны были сделать, это git rm --cachedудалить их из репозитория, но оставить их в вашем локальном хранилище. Вы должны иметь возможность вернуться к своему предыдущему коммиту с помощью чего-то вроде git reset --soft HEAD^отмены этого коммита и восстановления ваших файлов. В этом прелесть мерзавца: все это есть в твоей истории.
JESii
2

Чтобы игнорировать неотслеживаемые файлы, особенно если они находятся в (нескольких) папках, которые не отслеживаются, простое решение заключается в добавлении .gitignoreфайла в каждую неотслеживаемую папку и вводе в одну строку, содержащую, *за которой следует новая строка. Это действительно простое и понятное решение, если неотслеживаемые файлы находятся в нескольких папках. Для меня все файлы были из единственной неотслеживаемой папки, vendorи вышеприведенное просто сработало.

aak318
источник
1
Большой! К вашему сведению: это работает только потому, что git отслеживает (и позволяет фиксировать) файлы, а не папки.
jmiserez
-2

Если в вашем репозитории еще нет файла .gitignore, то простое решение - создать файл .gitignore и добавить .gitignoreв него список файлов, которые следует игнорировать.

Гэвин С. Янси
источник
4
А что, если команда затем захочет добавить gitignore позже? Это вообще работает? Звучит как ужасная идея и как то, что не должно даже работать.
Бьорн
Ответ этого парня привел меня в замешательство. Никто так не делает.
Мартын Чемберлин
Это быстрое и простое решение, если есть место для его размещения. Наше репо имеет общий .gitignoreфайл в верхней части. Но мои грязные файлы находятся в глубокой папке, поэтому я просто добавил свои собственные .gitignoreрядом с ними. +1
joeytwiddle