Если внести файл в .gitignore, то он не будет отслеживаться гитом лишь в том случае, если этого файла нет в удаленном репозитории.

Но если в репозитории уже есть (к примеру конфиги сайта), а мы не хотим, чтобы наши локальные конфиги отслеживались, то можно выполнить команду:
git update-index --assume-unchanged application/config/database.php

либо всю папку
git update-index --assume-unchanged application/config/*

Чтобы перестать игнорировать изменения, нужно использовать параметр --no-assume-unchanged.
git update-index --no-assume-unchanged application/config/*

Update: Если конфиг изменили


Если всё же кто-то изменил структуру файла конфига, то git не даст сделать pull, т.к. все-равно будет считать, что файл конфига с нашими паролями отличается от того, что прийдет с командой pull.

Чтобы все-таки получить новые изменения, но и свои пароли сохранить в конфиге нужно сделать следующее:

1. Сохранить текущие конфиги (с нашими локальными паролями) в отдельную папку например.

2. Отменить игнорирование изменений (параметр --no-assume-unchanged).
git update-index --no-assume-unchanged application/config/database.php

3. На данном шаге команда git status покажет, что файл application/config/database.php был изменен, но еще не проиндексирован. Именно эти изменения и мешают нам забрать командой git pull новые изменения. Учитывая, что на шаге 1 мы сохранили наши конфиги в отдельную папку — мы можем сейчас отменить эти изменения.
git checkout application/config/database.php

4. Сейчас git status покажет, что изменений нет (nothing to commit, working tree clean). Забираем новые изменения:
git pull

5. Опционально: Если мы привыкли работать в отдельной ветке (не в master), то переходим в эту ветку (например: dev-branch) для последующей работы:
git checkout dev-branch

и вливаем в ветку dev-branch новые изменения из ветки master (куда мы их уже получили командой git pull):
git merge master

6. Изменяем теперь наши обновленные конфиги, возвращая туда наши локальные пароли и все то, что мы желаем там видеть, но не хотим это хранить в репозитории (для этого мы сохранили все в шаге 1). После чего команда git status естественно покажет, что конфиги изменены, но не проиндексированы.

7. И только теперь мы можем снова включить игнорирование (--assume-unchanged):
git update-index --assume-unchanged application/config/database.php

После чего git status покажет, что все чисто (nothing to commit, working tree clean) и мы сможем снова работать, делать коммиты и переключаться между ветками.

P.S. Разумеется автор не рекомендует хранить конфиги с паролями в репозитории. Это лишь наглядный пример.

Модератору: Данный 2do list писал ранее для себя в жж (https://pashakiz.livejournal.com/183468.html)
Если для хабра это важно — могу скрыть свою пост в жж под ключ.

Комментарии (5)


  1. datacompboy
    06.01.2023 11:20
    +6

    https://www.baeldung.com/git-assume-unchanged-skip-worktree

    Правильнее использовать skip-worktree а не assume-unchanged


  1. gdt
    06.01.2023 12:08
    +2

    Наверное можно пропустить первый шаг, если складывать измененные файлы в stash, вместо копирования в отдельную папочку


  1. YegorP
    06.01.2023 12:15
    +3

    Если внести файл в .gitignore, то он не будет отслеживаться гитом лишь в том случае, если этого файла нет в удаленном репозитории.

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


  1. amakhrov
    07.01.2023 01:35
    +6

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


  1. Andrey_Solomatin
    07.01.2023 09:50
    +1

    Часто существует путаница между конфигами и секретами. Они похожи и хочется именть доступ к ним единообразно. Например адрес базы это конфиг а пароль от базы это секрет.

    Хранить всё как конфиги просто, но не безопастно. Хранить всё как секреты, приводит к дополнительным сложностям.

    Мне нравится подход со слиянием файлов.
    Все конфигарационные файлы я бы бил на три группы. Конфиги от развёртываний(прод, тест итд.), личные конфиги и секреты.

    Конфиги развёртываний в репозитории.
    Файл с секретами добавляется только в момент депоя. Локально он свой, в .gitignore
    Личные конфиги с переопредениями локально свои, в .gitignore