Храните файл в репозитории Git, но не отслеживайте изменения

305

У меня есть несколько файлов на сайте CodeIgniter, которые я хочу иметь в репозитории, но не отслеживаю их изменения.

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

// the production config files i want the files but they need to be updated to specific client needs
application/config/production/config.php
application/config/production/database.php
application/config/production/tank_auth.php
// index page, defines the environment (production|development)
/index.php
// all of the css/js cache (keep the folder but not the contents)
/assets/cache/*
// production user based styling (color, fonts etc) needs to be updated specific to client needs
/assets/frontend/css/user/frontend-user.css

В настоящее время, если я бегу

git clone git@github.com:user123/myRepo.git httpdocs

а затем отредактируйте файлы выше, все отлично. Пока я не выпустил исправление или патч и не запустился git pull. Все мои изменения затем перезаписываются.

gorelative
источник
Вы могли бы просто проигнорировать учетные данные / файлы конфигурации клиента и сделать так, чтобы программа строила файлы по умолчанию, если они отсутствуют при установке репозитория?
От Матфея

Ответы:

618

У git есть другое решение для этого. Сначала измените файл, который вы не хотите отслеживать, и используйте следующую команду:

git update-index --assume-unchanged FILE_NAME

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

git update-index --no-assume-unchanged FILE_NAME

git-update-index документация

nasirkhan
источник
Я сделал то, что вы говорите, но git status продолжает сообщать, что файл изменен
rraallvv
7
Да, это должен быть «Принятый ответ». Работал на меня.
Joshmcode
34
Согласно Джунио Хамано (сопровождающему Git): «Предполагается, что неизменным нельзя злоупотреблять механизмом игнорирования. [...] Git не обещает, что Git всегда будет считать, что эти пути не изменены - если Git может определить путь, помеченный как предположительно неизмененный, без дополнительных затрат lstat (2), он оставляет за собой право сообщить, что путь был изменен (в результате, «git commit -a» может принять изменение)." Другими словами, предположим, что без изменений это только для локальных проблем производительности. Если Git может определить, что эти файлы были изменены легче, это произойдет.
Алехандро Гарсия Иглесиас
41
Читая информацию для него, я думаю, что --skip-worktreeвариант лучше подходит для этой работы, чем --assume-unchanged.
ПАОПеленд
26
--skip-worktree действительно лучший вариант. Дополнительная информация: stackoverflow.com/questions/13630849/…
Настройщик
80

Чтобы извлечь ответ из комментариев другого ответа:

$ git update-index --skip-worktree FILENAME

Кажется лучшим вариантом, чем --assume-unchanged

Подробнее об этом можно прочитать здесь: Git - Разница между «предположим, без изменений» и «skip-worktree»

Энтони
источник
Когда я делаю это и затем пытаюсь изменить ветви, я получаю «Следующие неотслеживаемые файлы рабочего дерева будут перезаписаны при оформлении заказа ... Пожалуйста, переместите или удалите их, прежде чем переключать ветви». Есть идеи как избежать?
Патрик Салапски
Статья, на которую ссылается @aexl, переместилась на compiledsuccessfully.dev/git-skip-worktree
Эндрю Китон,
1
В документах говорят , что это плохая идея. «Пользователи часто пытаются использовать биты предположения без изменений и пропуска рабочего дерева, чтобы Git игнорировал изменения в отслеживаемых файлах. Это не работает должным образом, поскольку Git может по-прежнему проверять файлы рабочего дерева по индексу при выполнении определенных операций. В общем, Git не предоставляет способ игнорировать изменения в отслеживаемых файлах, поэтому рекомендуются альтернативные решения ».
Кертис Блэквелл
58

Для моих проектов Code Igniter я храню database.php.example и config.php.example в репозитории.

Затем я добавляю config.php и apps / config / database.php в файл .gitignore .

Итак, наконец, при развертывании я могу скопировать файлы .example (в config.php и database.php), настроить их, и они не будут отслеживаться GIT.

superiggy
источник
12
Хорошее решение, но я думаю, что ответ Насирхана самый лучший.
26.07.15
Это не хорошее решение. Если вы очистите свой индекс git, вы начнете отслеживать изменения, когда вы этого не хотите. Смотрите @nasirkhans ответ для правильного способа сделать это.
Брайан Мелтон-Грейс - MSFT
3
Я не согласен с обоими предыдущими комментариями. Таким образом, гораздо проще обновить значения «по умолчанию» без необходимости извлекать их и копировать вашу локальную конфигурацию в другое место, чтобы потом вернуть ее обратно. Кроме того, это относится ко всем репозиториям, поэтому вам не нужно делать никаких повторных изменений репо.
OskarD90
1
если он находится в gitignore, почему он снова начинает отслеживать изменения
Shapeshifter
Решает проблему ОП, но на самом деле не отвечает на вопрос.
Трэвис Уилсон,
1

Я бы поместил их в ваш .gitignoreфайл и просто скопировал их вручную, если это необходимо.

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

Майкл Даррант
источник
1
нет способа сначала добавить их в репозиторий, а затем добавить их в .gitignore? Было бы замечательно, если бы было решение для включения файлов, но не каких-либо изменений после определенного коммита или чего-то еще.
Относительно
1
@mklauber Я хочу хранить их до тех пор, пока я не побегу git rm <file>. Цель IE: файл config.php. Я хочу сохранить файл конфигурации, но я, очевидно, не хочу отслеживать учетные данные базы данных от клиента к клиенту, поскольку они различны.
Относительно
1
Да, у меня проблема с нашим файлом rails database.yml. Мы сохраняем скелет, а затем копируем и меняем его.
Майкл Даррант
если бы я создал эти файлы конфигурации "Скелет", вы бы добавили их в начальный коммит. а затем изменив .gitignore, чтобы игнорировать файл? В сущности, хранить файл в репо, но как скелет?
Относительно
10
У вас есть два варианта: добавить файл, git add file1а затем отредактировать .gitignoreфайл. Переданный файл останется там и не будет обновлен. Или: Вы можете добавить файл, .gitignoreа затем добавить его, git add --force file1чтобы принудительно вставить файл. Вы можете использовать 2-й вариант, когда вам нужно перезаписать файл
klaustopher
1

Полученные ответы лишь частично решают проблему, но создают еще больше проблем.

Мне нужно было сохранить файл "Web.Local.config". Единственное решение, которое сработало для меня, было:

1. Исключить файл из проекта

2. Создайте отдельную копию файла как Web.LocalTemplate.config

Теперь, когда Git отслеживает «Web.LocalTemplate.config», все разработчики могут использовать его в качестве отправной точки. Тем не менее, «Web.Local.config», не являющийся частью проекта, будет автоматически игнорироваться.

Хрвое Матич
источник
Как git update-index --skip-worktree FILENAMEчастично решить вашу проблему или даже добавить больше проблем? Это решает именно то, что вы пытаетесь сделать. Вы пробовали это?
Амир Асыраф