it-swarm.com.ru

Как остановить отслеживание и игнорировать изменения в файле в Git?

Я клонировал проект, который включает в себя несколько файлов .csproj. Мне не нужно/не нравится, чтобы мои локальные csproj файлы отслеживались Git (или появлялись при создании патча), но они явно нужны в проекте.

Я добавил *.csproj в свой ЛОКАЛЬНЫЙ .gitignore, но файлы уже находятся в репо.

Когда я набираю git status, он показывает мои изменения в csproj, которые я не заинтересован в отслеживании или отправке патчей.

Как убрать «отслеживание» этих файлов из моего личного репозитория (но сохранить их в источнике, чтобы я мог их использовать), чтобы не видеть изменения, когда я делаю статус (или создаю патч)?

Есть ли правильный/канонический способ справиться с этой ситуацией?

1508
Joshua Ball

Просто вызовите git rm --cached для каждого файла, который вы хотите удалить из контроля версий. Пока ваши локальные шаблоны игнорирования верны, вы не увидите эти файлы, включенные в вывод состояния git.

Обратите внимание, что это решение удаляет файлы из репозитория, поэтому всем разработчикам необходимо поддерживать свои собственные локальные (не контролируемые редакцией) копии файла.

Чтобы git не обнаружил изменения в этих файлах, вы также должны использовать эту команду:

git update-index --assume-unchanged [path]

Что вы, вероятно, хотите сделать: (снизу @Ryan Taylor answer )

  1. Это говорит git, что вы хотите свою собственную независимую версию файла или папки. Например, вы не хотите перезаписывать (или удалять) Конфигурационные файлы производства/постановки.

git update-index --skip-worktree <path-name>

Полный ответ здесь в этом URL: http://source.kohlerville.com/2009/02/untrack-files-in-git/

1891
anthony

Если вы выполните git update-index --assume-unchanged file.csproj, git не будет проверять file.csproj на наличие изменений автоматически: это остановит их появление в состоянии git, когда вы их измените. Таким образом, вы можете пометить все ваши файлы .csproj таким образом, хотя вам придется вручную отмечать любые новые файлы, которые отправляет вам репозиторий верхнего уровня. (Если они есть в вашем .gitignore или .git/info/exclude, то созданные вами будут игнорироваться)

Я не совсем уверен, что такое файлы .csproj ... если они совпадают с конфигурациями IDE (аналогично файлам Eclipse .Eclipse и .classpath), то я бы предположил, что они никогда не должны быть управляемый источником вообще. С другой стороны, если они являются частью системы сборки (например, Makefiles), то, очевидно, они должны --- и был бы полезен способ получения необязательных локальных изменений (например, из local.csproj a la config.mk). разделите сборку на глобальные части и локальные переопределения.

232
araqnid

Это двухэтапный процесс:

  1. Удалить отслеживание файла/папки - но сохранить их на диске - используя 

    git rm --cached 
    

    Теперь они не отображаются как «измененные», но все равно отображаются как 

        untracked files in  git status -u  
    
  2. Добавьте их в .gitignore

140
rjha94

Есть 3 варианта, вы, вероятно, хотите # 3

1. Это сохранит локальный файл для вас, но удалит его для всех остальных, когда они извлекут.

git rm --cached <file-name> или git rm -r --cached <folder-name>

2. Это для оптимизации, как папка с большим количеством файлов, например SDK, которые, вероятно, никогда не изменятся. Он говорит git прекратить проверять эту огромную папку каждый раз на предмет изменений, локально, так как у нее их нет. Индекс assume-unchanged будет сброшен и файл (ы) будут перезаписаны, если в файл/папку будут внесены изменения в исходный файл (при извлечении).

git update-index --assume-unchanged <path-name>

3. Это говорит git, что вы хотите иметь свою собственную независимую версию файла или папки. Например, вы не хотите перезаписывать (или удалять) производственные/промежуточные файлы конфигурации.

git update-index --skip-worktree <path-name>

Важно знать, что git update-index не будет распространяться с git, и каждый пользователь должен будет запускать его независимо.

137
Ryan Taylor

Принятый ответ все еще не работал для меня

Я использовал 

git rm -r - кешируется.

мерзавец добавить.

git commit -m "исправление .gitignore"

Нашел ответ от здесь

82
Buddhika Hasthanayake

Забыли свой .gitignore?

Если у вас есть весь проект локально, но вы забыли добавить его, git ignore и теперь отслеживаете некоторые ненужные файлы, используйте эту команду, чтобы удалить все

git rm --cached -r .

убедитесь, что вы находитесь в корне проекта.

Тогда вы можете сделать обычное 

Добавлять

git add .

Совершить

git commit -m 'removed all and added with git ignore'

От себя

git Push Origin master

Заключение

Надеюсь, что это поможет людям, которые должны внести изменения в свой .gitignore или забыли все это вместе. 

  • Удаляет весь кеш
  • Смотрит на ваш .gitignore
  • Добавляет файлы, которые вы хотите отслеживать
  • Подталкивает к вашему репо
41
Joe Lloyd

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

ответ на другой вопрос предполагает, что может потребоваться пропустить рабочее дерево.

git update-index --skip-worktree <file>
22
the_new_mr

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

git rm --cached app/**/*.xml

или же

git rm --cached -r app/widgets/yourfolder/

так далее.

21
Peter

Многие люди советуют вам использовать git update-index --assume-unchanged. Действительно, это может быть хорошим решением, но только в краткосрочной перспективе.

Что вы, вероятно, хотите сделать, это: git update-index --skip-worktree.

(Третий вариант, который вам, вероятно, не нужен: git rm --cached. Он сохранит ваш локальный файл, но будет помечен как удаленный из удаленного репозитория.)

Разница между первыми двумя вариантами?

  • assume-unchanged позволяет временно скрыть изменения из файла. Если вы хотите скрыть изменения, внесенные в файл, изменить файл, а затем извлечь другую ветку, вам нужно будет использовать no-assume-unchanged, тогда, вероятно, сохраните сделанные изменения.
  • skip-worktree будет следовать за вами независимо от того, какую ветку вы заказываете, с вашими изменениями!

Вариант использования assume-unchanged

Предполагается, что этот файл не должен быть изменен, и дает более чистый вывод при выполнении git status. Но когда вы переходите в другую ветку, вам необходимо сбросить флаг и зафиксировать или сохранить изменения перед этим. Если вы активируете эту опцию, вам нужно будет разрешать конфликты, а git не будет автоматически объединяться. На самом деле он скрывает только изменения (git status не покажет вам отмеченные файлы).

Мне нравится использовать его, когда я хочу только на некоторое время остановить отслеживание изменений + зафиксировать кучу файлов (git commit -a), связанных с модификацией same.

Вариант использования skip-worktree

У вас есть класс настройки, содержащий параметры (например, включая пароли), которые ваши друзья должны изменить в соответствии с их настройкой.

  • 1. Создайте первую версию этого класса, заполните поля, которые вы можете заполнить, и оставьте другие поля пустыми/пустыми.
  • 2: зафиксируйте и отправьте его на удаленный сервер.
  • 3: git update-index --skip-worktree MySetupClass.Java
  • 4: Обновите свой класс конфигурации с вашими собственными параметрами.
  • 5: вернитесь к работе над другой функциональностью.

Изменения, которые вы делаете, будут следовать за вами независимо от ветки. Предупреждение: если ваши друзья также хотят изменить этот класс, они должны иметь ту же настройку, в противном случае их изменения будут перенесены в удаленный репозиторий. При извлечении удаленная версия файла должна перезаписывать вашу.

PS: делайте одно или другое, но не оба, поскольку у вас будут нежелательные побочные эффекты. Если вы хотите попробовать другой флаг, вы должны сначала отключить его.

7
belka

Чтобы запретить Git отслеживать изменения в вашем локальном файле/папке (т.е. git status не обнаружит изменения в нем), выполните:

git update-index --skip-worktree path/to/file

И чтобы Git снова отслеживал изменения в вашей локальной версии (чтобы вы могли зафиксировать изменения), выполните:

git update-index --no-skip-worktree path/to/file
5
Ruto Collins

Чтобы предотвратить мониторинг файла с помощью git

git update-index --assume-unchanged [file-path]

И чтобы вернуть его обратно используйте 

git update-index --no-assume-unchanged [file-path]

Репозиторий для ссылок на похожие варианты использования https://github.com/awslabs/git-secrets

4
shijin

Я предполагаю, что вы спрашиваете, как удалить ВСЕ файлы в определенной папке или папке bin, а не выбирать каждый файл отдельно. 

Вы можете использовать эту команду:

git rm -r -f /<floder-name>\*

Убедитесь, что вы находитесь в родительском каталоге этого каталога.
Эта команда рекурсивно «удалит» все файлы, которые находятся в папках bin/или build /. Под словом «удалить» я подразумеваю, что git сделает вид, что эти файлы «удалены», и эти файлы не будут отслеживаться. Git действительно отмечает эти файлы как находящиеся в режиме удаления.

Убедитесь, что ваш .gitignore готов к предстоящим коммитам.
Документация: git rm

0
Vraj Pandya

Проблема может быть вызвана порядком работы . Если вы сначала изменили .gitignore, а затем git rm --cached xxx, возможно, вам придется продолжать сталкиваться с этой проблемой.

Правильное решение :

  1. мерзавец - кэшированный ххх
  2. изменил .gitignore

Заказ инварианта!

.Gitignore перезагрузить после модификации!

0
thearyong

Я предполагаю, что вы пытаетесь удалить один файл из git tacking . Для этого я бы порекомендовал следующую команду.

git update-index --assume-неизменный

Ex - git update-index --assume-неизмененный .gitignore .idea/compiler.xml

0
Pankaj Sonani

Почти git безкомандный подход был дан в этом answer :

Чтобы игнорировать определенные файлы для каждого локального репо:

  1. Создайте файл ~/.gitignore_global, например, по touch ~/.gitignore_global в вашем терминале. 
  2. Запустите git config --global core.excludesfile ~/.gitignore_global один раз.
  3. Запишите пути к файлам/каталогам, которые вы хотите игнорировать, в ~/.gitignore_global. например modules/*.H, который, как предполагается, будет находиться в вашем рабочем каталоге, т.е. $WORK_DIR/modules/*.H.

Чтобы игнорировать определенные файлы для одного локального репо:

  1. Выполните описанный выше третий шаг для файла .git/info/exclude в репозитории, то есть запишите пути к файлам/каталогам, которые вы хотите игнорировать, в .git/info/exclude. например modules/*.C, который, как предполагается, будет находиться в вашем рабочем каталоге, т.е. $WORK_DIR/modules/*.C.
0
KutalmisB

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

В приведенном ниже тексте «excirir» - это имя каталога, в который я не хочу смотреть изменения.

Сначала удалите все существующие новые файлы из кэша отслеживания изменений (без удаления из файловой системы).

git status | grep "new file:" | cut  --complement -d " " -f1-4 | grep "^excludedir" | xargs git rm --cache

Вы можете сделать то же самое с modified:. renamed: немного сложнее, так как вам нужно посмотреть бит -> для нового имени файла и выполнить предварительный бит ->, как описано для deleted: ниже.

Файлы deleted: оказываются немного сложнее, так как вы не можете обновить индекс для файла, который не существует в локальной системе

echo .deletedfiles >> .gitignore
git status | grep "deleted:" | cut  --complement -d " " -f1-4 | grep "^excludedir" > .deletedfiles
cat .deletedfiles | xargs -d '\n' touch
cat .deletedfiles | xargs -d '\n' git add -f
cat .deletedfiles | xargs -d '\n' git update-index --assume-unchanged
cat .deletedfiles | xargs -d '\n' rm

Последняя команда в списке выше снова удалит файлы из вашей файловой системы, поэтому не стесняйтесь опускать это.

Затем заблокируйте отслеживание изменений из этого каталога

git ls-files excludedir/ | xargs git update-index --skip-worktree
git update index --skip-worktree excludedir/
0
mpag