Храните файл в репозитории 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. Все мои изменения затем перезаписываются.





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

Ответы:


618

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

git update-index --assume-unchanged FILE_NAME

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

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

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


Я сделал то, что вы говорите, но 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.


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частично решить вашу проблему или даже добавить больше проблем? Это решает именно то, что вы пытаетесь сделать. Вы пробовали это?
— Амир Асыраф
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.