использование gitignore для игнорирования (но не удаления) файлов

98

У меня есть каталог tmp в моем репозитории git, который я хотел бы по-прежнему существовать, но игнорировать. Я добавил его .gitignore, но git statusвсе еще сообщает мне об изменениях в файлах в этом каталоге. Я пробовал git rm -r --cached, но это удаляет его из удаленного репо. Как я могу перестать отслеживать изменения в этом каталоге, но при этом позволить ему существовать? Мне также нужно сделать это для 1 файла, но изменения в нем также появляются git statusпосле .gitignoreних. Что я должен делать?

21312312
источник
1
напишите, пожалуйста, как именно выглядит ваш файл .gitignore?
kdehairy

Ответы:

183

Вместо этого .gitignoreвы можете обновить локальный репозиторий git, выполнив следующую команду:

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

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

Ducin
источник
22
Моя любовь к мерзавцу, возможно, только удвоилась.
Марк Фокс
2
Это должен быть принятый ответ. Спасибо за ссылку на это.
Gowiem
4
Есть ли способ отправить это в удаленное репо?
Брайан Ортис
2
хм, я бы предпочел пометить файл как «это не файл git, никогда не синхронизируйте его с git, даже в
чьих-
11
Вы можете вернуть его с помощью git update-index --no-assume-unchanged <file>. Если хотите их перечислить git ls-files -v | grep '^h'.
Sanghyun Lee
12

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

Но ваша проблема в том, что git уже отслеживает файлы, которые вы хотите игнорировать, и .gitignoreне применяется к отслеживаемым файлам. Единственный способ остановить это отслеживание - приказать git удалить их. Используя git rm --cached, вы запрещаете git удалять ваши локальные файлы, но любой другой репозиторий, получающий ваши изменения, применит удаление. Я не думаю, что есть способ избежать этого из вашего собственного репозитория. Вы должны сделать что-то в других репозиториях, иначе файлы будут удалены.

Чтобы предотвратить удаление друг от друга репозиториев, вы можете:

  • (очевидно) резервное копирование файлов где-нибудь, извлечение изменений и восстановление файлов,
  • или также git rm --cachedфайлы и зафиксируйте перед тем, как вытащить свои изменения. Git красиво объединит два удаления, не затрагивая уже неотслеживаемые файлы.
Михаэль Витрант
источник
6
Это не обязательно должно быть правдой («прекратить отслеживание = удалить файл»). Вы все еще можете иметь файл отслеживаются в репо и не видеть изменения , сделанные с помощью: git update-index --assume-unchanged <file>. Взгляните на: blog.pagebakers.nl/2009/01/29/…
ducin
это решило мою проблему, потому что мне нужно удалить файл из репозитория в git, git rm --cached <filename> -r и после этого push снова изменит репозиторий, чтобы файл был удален
Винисиус Кардосо,
7

Поместите /в конец имени каталога в вашем .gitignoreфайле, т.е.

tmp/

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

git rm -rf ./tmp/
git commit -m "untrack tmp dir"
mkdir tmp
echo tmp/ >> .gitignore
git add .gitignore ; git commit -m "add tmp/ to ignore list"

Новые файлы в этом каталоге не будут отслеживаться.

--cachedВариант git rmработает только по индексу ( в ожидании изменения более или менее). Это не влияет на рабочее дерево или статус того, что отслеживалось или нет.

Мат
источник
У меня есть это. Оба the/dir/иthe/dir/*
21312312
Привет, Мэт, если у меня в разных папках есть что-то вроде / Media, которое я бы не хотел игнорировать, возможно ли это? Так что вроде / 1 / Media, / 2 / Media, вплоть до 99?
Nic
3

.gitignore не влияет на отслеживаемые файлы.

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

Кроме того, однострочные параметры для установки без изменений для всех файлов в каталоге - git update-index --assume-unchanged для каталога .

Гейб Копли
источник
1

Похоже, вы пытаетесь отследить файл (например index.php), добавить его в удаленный репозиторий, а затем перестать следить за ним, сохраняя при этом файл на удаленном компьютере (т.е. оставлять index.phpнеизменным на удаленном репозитории, изменяя его локально).

Насколько я понимаю, git не может этого сделать. Вы можете либо отслеживать файл, либо нет. Если вы отслеживаете файл, он существует в удаленном репо и изменяется при фиксации изменений в нем. Если вы не отслеживаете файл, он не существует в удаленном репо.

Поскольку с помощью git невозможно сделать именно то, что вы хотите, потенциально существуют другие решения, в зависимости от конкретной ситуации. Например, почему вы не хотите index.phpизменять удаленно, когда вы меняете его локально? Есть ли в файле настройки для конкретного пользователя? В этом случае вы можете:

cp index.php index_template.php
git rm --cached index.php

Теперь отредактируйте index_template.php так, чтобы он отображался в удаленном репо. Добавьте что-нибудь в свой README, чтобы сообщить людям, использующим ваш репозиторий, что после клонирования они должны скопировать index_template.php в index.php и отредактировать его в соответствии со своими потребностями.

git add index_template.php
git add README
git commit -m 'added template index.php file'
git push

Когда кто-то клонирует ваше репо, он должен создать свое собственное index.php. Вы сделали это легко для них: просто скопировать index_template.phpв index.phpи пересмотреть его с настройками компьютера специфическими.

Кипарис Франкенфельд
источник