Как игнорировать отслеживаемый файл в git, не удаляя его?
Моя команда использует sourcetree в качестве нашего git-клиента. В нашем проекте есть сторонний плагин. Требуется несколько файлов конфигурации. Эти файлы не могут быть созданы автоматически. Они хранят имя учетной записи, токены входа в систему и некоторые временные параметры, которые не должны быть разделены. Но этот файл все еще нужен, иначе он сообщит об ошибке. Так что теперь они всегда остаются в нашем разделе "незафиксированные изменения", что раздражает.
У меня есть 2 варианта:
Удалите эти файлы из репозитория git. Добавьте их в.gitignore. Попросите всех членов моей команды добавить эти файлы обратно в свой локальный проект со своими настройками.
Посмотрите, есть ли такие хитрости, как "игнорирование отслеживаемого файла без его удаления".
(По сути, я чувствую, что если возможен вариант 2, в git должна быть логика типа "Если у local нет этого файла, используйте удаленную версию. Если у local есть этот файл, игнорируйте". Логика кажется плохой, легко генерировать ошибки.)
6 ответов
Это то, что вы хотите сделать:
- Добавьте все файлы, по отдельности или в папке, которые вы хотите удалить из репозитория, но локально сохраните их в .gitignore.
- Выполните git rm --cached put/here/your/file.ext для каждого файла или git rm --cached folder/\*, если они находятся в папке. (Это / \ *, потому что вам нужно убежать *)
- Передайте ваши изменения.
- Нажмите на пульт.
Сделав это, вы эффективно "проигнорируете отслеженные файлы, не удаляя их", удалив их из репозитория и оставив все их нетронутыми в вашей системе. Затем, когда ваша команда извлекает изменения, они извлекают файл .gitignore, и их отдельные файлы конфигурации не будут перезаписаны файлами в репозитории, потому что вы их проигнорировали и удалили из него. Кроме того, поскольку теперь новый .gitignore игнорирует эти файлы, у каждого будет своя собственная версия, которая не отображается в "незафиксированных изменениях".
Кажется, здесь найдено простое решение . Добавления файла/каталога только в .gitignore недостаточно, но git позволит вам вручную «игнорировать» изменения в файле/каталоге:
git update-index --assume-unchanged <file>
А если вы хотите снова начать отслеживать изменения, вы можете отменить предыдущую команду, используя:
git update-index --no-assume-unchanged <file>
Чтобы просмотреть файлы, для которых отключено отслеживание изменений, вы можете использовать (linux/unix):
git ls-files -v | grep ^[h]
или (окна):
git ls-files -v | find "h "
Предыстория: мне это нужно было, чтобы добавить в репозиторий файл конфигурации с пользовательскими данными. Пользователь должен извлечь файл и отредактировать его для своей системы, но впоследствии файл должен игнорироваться git и никогда не фиксироваться.
- Удалите эти файлы из репозитория git. Добавьте их в.gitignore. Попросите всех членов моей команды добавить эти файлы обратно в свой локальный проект со своими настройками.
Если я правильно читаю ваш вопрос, и файлы, о которых идет речь, содержат такие вещи, как учетные данные для проверки подлинности и параметры конфигурации, специфичные для сайта или разработчика, то это путь.
Если есть вероятность того, что ваше git-репо когда-либо будет доступно для внешних или недоверенных лиц, то ваши данные аутентификации не должны быть в нем, потому что они будут раскрыты любому, кто клонирует проект. Даже если учетные данные были удалены в будущем, они все равно будут доступны в истории.
Параметры, специфичные для сайтов / разработчиков, не вызывают проблем безопасности, связанных с информацией об аутентификации, но они все равно будут вызывать проблемы, если задействованы несколько сайтов или разработчиков, потому что, даже если у вас есть политика против принятия / отправки изменений в эти файлы, это Это всего лишь вопрос времени, когда кто-то фиксирует их и приводит к изменению настроек других пользователей (или к созданию ложных конфликтов) при следующем запуске. У меня есть личный опыт с этим, и с этим постоянно приходится сталкиваться. В нашем случае некоторые различия были связаны с настройками разработки и производства, а также с настройками, специфичными для конкретной площадки, и это вызывало неоднократные негативные последствия для наших производственных систем.
Один хакерский обходной путь, который я видел в нескольких проектах, - это сделать очищенную копию foo.cfg
названный foo.cfg.default
, трек foo.cfg.default
в мерзавце, гитиньоре foo.cfg
и полагаться на пользователя для копирования foo.cfg.default
в foo.cfg
после клонирования и настройки (добавление учетных данных для аутентификации, персонализированных настроек и т. д.). В вашем случае, поскольку файлы конфигурации предназначены для стороннего плагина, это может сработать, поскольку они, вероятно, довольно стабильны. Это менее эффективно в сценариях, где foo.cfg.default
будет часто меняться, так как затем пользователь должен будет заметить какие-либо изменения и вручную объединить их с локальными foo.cfg
,
Нет простого решения для этого. Но вы можете попробовать следующее:
А) поставить foo.cfg
в .gitignore
и нажмите. Попросите всех сохранить резервную копию foo.cfg
вне их локального хранилища. Позвольте им нажать и скопировать этот удаленный файл foo.cfg
обратно на место.
Б) переименовать foo.cfg
в foo.default.cfg
положил foo.cfg
в gitignore нажмите и попросите каждого члена вашей команды потянуть, а затем переименовать локально foo.default.cfg
в foo.cfg
, После этого нужно удалить foo.default.cfg
, толкни, и все должны тянуть снова.
В) поставить foo.cfg
в .gitignore
и нажмите. Попроси всех потянуть. Теперь для всех foo.cfg
удален Они могут восстановить это путем git checkout HEAD^ foo.cfg
, Теперь файл все еще в стадии постановки, поэтому им нужно позвонить git reset HEAD
, Теперь это работает.
ТЛ; др
Технически ваше требование противоречиво.
На более философском уровне это (кажется) столкновение между открытым исходным кодом и корпоративной философией.
Во всяком случае... я предложу некоторые вещи, которые приходят мне в голову
технически
git
либо отслеживает, либо игнорирует файл.
- Отслеживание легче (есть). Просто ничего не делайте... кроме использования мерзавца! И любой файл отслеживается.
- Игнорировать это почти так же просто - просто убедитесь, что оно соответствует чему-то в вашем файле gitignore.
- Но вы не можете сделать оба!
- Главное предостережение: перемещение файла из отслеживаемого в игнорируемое несколько нетривиально - простое добавление подходящего шаблона в gitignore не обрезает его после отслеживания. Подходящий
Лучшая практика
Не запускайте git-проект без создания правильного
- gitignore
Также связано - gitattributes
Итак, первое (и несколько нереальное)
Предложение 1
- Начать новый проект git
- Сделайте правильные файлы gitignore и gitattribute
- Отладка при необходимости с помощью git-check-ignore
- Скопируйте, добавьте, зафиксируйте ваши обычные файлы
- Скопируйте, добавьте, укажите статус файлов, которые не будут отслеживаться. Статус должен быть чистым
Но, как я сказал, это, кажется, не совсем то, что вы хотите, потому что вам нужны какие-то общие, но не отслеживаемые файлы. Так что вам нужно
Отследить отслеженные файлы
- Чистый совет (простое, но, вероятно, неадекватное решение
- ветвь фильтра
- Фильтр-отделение
- Лучшая альтернатива фильтрующему ответвлению
Вы на самом деле хотите мерзавца
Пост-клон крюк
Это попытка здесь
Но это плохая идея, как объясняется здесь
Что подводит меня к
Философская разница
- Корпоративный работодатель обоснованно хочет контролировать, что / как функционируют его сотрудники-программисты. Что влечет за собой различные виды управления машиной
- Случайное программное обеспечение с открытым исходным кодом, находящееся на github, которое берет на себя управление машиной другого случайного человека, является неэтичным и незаконным.
Поэтому, если бы вы были большим игроком с Fortune-500, естественным вариантом было бы раскошелиться на git и добавить функцию пост-клонового хука в ваш форк.
Более разумный и только немного более неудобный
Решение 2
- Напишите свой собственный пост-клон, но вручную вызываемый скрипт
- ... что делает требование копии, если отсутствует, оставить в покое, если присутствует
- И добавьте (ручной) шаг в вашу команду: (1) clone (2) скрипт вызова
- И не забывайте, Gitignore!
Если это решение имеет смысл, вы можете предпочесть
Решение 3
Инвертировать скрипт-внутри-git в скрипт-внутри-git
т.е. попросите вашу команду только скачать / скопировать и запустить скрипт, который
- Запускается
git clone
- Проверяет наличие / соответствие этих других файлов
- Создает / загружает их при необходимости (возможно, из источника, независимого от вашего основного репо)
Что вы могли сделать, так это
stash
файлы, изменение которых вы не хотите отслеживать:
git stash push <path/to/file> <path/to/other/file>
Они не будут добавлены, если вы используете
git add .
или же
git add -a
пока они не изменяются. Если изменения происходят часто, вы можете создать псевдоним для этой команды.