Могу ли я выполнить "git commit" файл и игнорировать изменения его содержимого?

У каждого разработчика в моей команде своя локальная конфигурация. Эта информация о конфигурации хранится в файле с именем devtargets.rb, который используется в наших задачах сборки rake. Однако я не хочу, чтобы разработчики затирали файлы devtargets друг друга.

Моя первая мысль заключалась в том, чтобы поместить этот файл в список .gitignore, чтобы он не передавался в git.

Тогда я начал задаваться вопросом: можно ли зафиксировать файл, но игнорировать изменения в файле? Итак, я бы зафиксировал версию файла по умолчанию, а затем, когда разработчик изменил ее на своем локальном компьютере, git проигнорировал бы изменения, и он не отобразился бы в списке измененных файлов, когда вы выполняете git status или git commit .

Это возможно? Это, безусловно, было бы неплохо ...


person Derick Bailey    schedule 23.07.2010    source источник
comment
См. Также stackoverflow.com/questions/3318043/ по аналогичной теме.   -  person VonC    schedule 23.07.2010
comment
возможный дубликат фиксации файлов конфигурации для конкретного компьютера   -  person Senseful    schedule 03.09.2014
comment
git игнорировать файлы только локально   -  person phuclv    schedule 20.03.2017


Ответы (5)


Конечно, я делаю именно это время от времени, используя

git update-index --assume-unchanged [<file> ...]

Чтобы отменить и снова начать отслеживание (если вы забыли, какие файлы не отслеживались, см. Этот вопрос):

git update-index --no-assume-unchanged [<file> ...]

Соответствующая документация:

- [no-] accept-unchanged
Если установлен этот флаг, имена объектов, записанные для путей, не обновляются. Вместо этого этот параметр устанавливает / отменяет бит предполагаемого неизменного для путей. Когда бит предположения неизменен, пользователь обещает не изменять файл и позволяет Git предполагать, что файл рабочего дерева совпадает с тем, что записано в индексе. Если вы хотите изменить файл рабочего дерева, вам нужно сбросить бит, чтобы сообщить Git. Это иногда полезно при работе с большим проектом в файловой системе, которая имеет очень медленный lstat(2) системный вызов (например, cifs).

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

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

$ git pull
…
From https://github.com/x/y
   72a914a..106a261  master     -> origin/master
Updating 72a914a..106a261
error: Your local changes to the following files would be overwritten by merge:
                filename.ext
 

и откажется сливаться.

На этом этапе вы можете преодолеть это, отменив локальные изменения, вот один из способов:

 $ git checkout filename.ext

затем снова потяните и измените локальный файл, или можно установить –no-assume-unchanged, и в этот момент вы можете выполнить обычное сохранение, слияние и т. д.

person Rob Wilkerson    schedule 23.07.2010
comment
хмммм, это может быть именно то, что я ищу! спасибо, ограбь! Я попробую и вернусь к тебе. :) - person Derick Bailey; 23.07.2010
comment
если вы хотите снова начать отслеживание изменений, выполните следующую команду: git update-index --no-assume-unchanged <file> - person agustibr; 24.11.2014
comment
делает ли эта команда свое дело локально или в папке .git? Я имею в виду, что если я запустил эту команду для файла config.php, распространится ли это на других пользователей, использующих репо? - person Magus; 10.02.2015
comment
@Magus: Нет. Это будет работать только для вас. - person Rob Wilkerson; 10.02.2015
comment
И вскоре вы захотите узнать, как определить, считается ли файл неизменным: stackoverflow.com/questions/2363197/ - person Ciro Santilli 新疆再教育营六四事件ۍ 20.02.2015
comment
@RobWilkerson: все равно заставить git создавать файл после clone, но игнорировать последующие изменения в различиях и commit -a? - person Gauthier; 24.04.2015
comment
Предполагая, что вы в основном спрашиваете, может ли git создать новый файл в процессе клонирования, тогда нет. Насколько мне известно, нет. Процесс клонирования клонирует только то, что находится в репо, насколько я когда-либо знал, но я думаю, у меня никогда не было причин нуждаться / ожидать чего-то еще. - person Rob Wilkerson; 24.04.2015
comment
Если я воспользуюсь этой командой, я все равно увижу изменения в исходном файле и извлечу их? (У меня немного другой вариант использования, чем в исходном вопросе) - person nhgrif; 07.03.2016
comment
Изменения файлов, игнорируемых таким образом, теряются при использовании git stash. Есть ли способ обойти это? - person Alexis; 04.10.2016
comment
git update-index --assume-unchanged не для этого. public-inbox.org/git/ - person jsageryd; 02.08.2018
comment
Похоже, это не работает для других пользователей, поскольку для запуска команды не требуется никаких фиксаций в репозитории. Я предполагаю, что это нужно делать локально для каждого пользователя, проверяющего проект. - person mmm; 04.02.2019
comment
В настоящее время фарфор имеет аналог: git add --intent-to-add. См. здесь - person jpaugh; 12.02.2019
comment
В документации Git прямо сказано не делать этого. - person bk2204; 29.04.2020
comment
Не игнорировал доработки, хотел остаться на месте. Как упоминалось в других плакатах, git не включает в себя какой-либо (надежный) механизм для игнорирования изменений в отслеживаемых файлах, поэтому вы должны предоставить свои собственные альтернативы. - person Suncat2000; 07.07.2020

Предпочтительный способ сделать это - использовать git update-index --skip-worktree <file>, как объяснено в этом ответе:

assume-unchanged разработан для случаев, когда дорого проверять, была ли изменена группа файлов; когда вы устанавливаете бит, git (конечно) предполагает, что файлы, соответствующие этой части индекса, не были изменены в рабочей копии. Таким образом, это позволяет избежать множества вызовов статистики. Этот бит теряется при изменении записи файла в индексе (например, при изменении файла в восходящем направлении).

skip-worktree - это нечто большее: даже если git знает, что файл был изменен (или его нужно изменить с помощью reset --hard или т.п.), он будет делать вид, что этого не было, используя вместо этого версию из индекса. Это сохраняется до тех пор, пока индекс не будет отброшен.

Чтобы отменить это, используйте git update-index --no-skip-worktree <file>

Начиная с версии git 2.25.1, этот способ больше не рекомендуется, цитируя:

Пользователи часто пытаются использовать биты accept-unchanged и skip-worktree, чтобы указать Git игнорировать изменения в отслеживаемых файлах. Это не работает должным образом, поскольку Git может по-прежнему проверять файлы рабочих деревьев по индексу при выполнении определенных операций. Как правило, Git не позволяет игнорировать изменения в отслеживаемых файлах, поэтому рекомендуются альтернативные решения.

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

person 1615903    schedule 21.04.2017
comment
Работает ли это для всех пользователей, проверяющих репозиторий? Получат ли они определенные файлы, но больше не смогут добавлять изменения по ошибке, если об этом явно не сказано? - person mmm; 04.02.2019
comment
@momomo флаг хранится в индексе, поэтому нет, он предназначен только для одного пользователя. См. ответ erjiang, чтобы узнать о том, что работает для всех пользователей. - person 1615903; 05.02.2019
comment
Я пытаюсь понять, каким должно быть содержимое файла. Я прокомментировал упомянутый вами ответ, но не получил ответа. Где он должен находиться и что в нем содержится? Вы знаете? - person mmm; 11.02.2019
comment
Я не слежу. Команда используется для игнорирования одного конкретного файла, указанного в команде. Содержание этого файла не имеет значения. - person 1615903; 11.02.2019
comment
В документации Git прямо говорится, что не следует использовать git update-index --skip-worktree для этой цели. - person bk2204; 29.04.2020

Обычной практикой, кажется, является создание devtargets.default.rb и его фиксация, а затем указание каждому пользователю скопировать этот файл в devtargets.rb (который находится в списке .gitignore). Например, CakePHP делает то же самое для своего файла конфигурации базы данных, который естественно меняется от машины к машине.

person erjiang    schedule 23.07.2010
comment
Вы не можете .gitignore файл, который отслеживается. .gitignore действует только для файлов, которых нет в индексе. - person CB Bailey; 23.07.2010
comment
Я пытался избежать этого, хотя на самом деле у меня нет веской причины. мы делаем это сейчас, и мне больно помнить, что мне нужно создать свою собственную версию без .default в имени. - person Derick Bailey; 23.07.2010
comment
@DerickBailey Но, честно говоря, проще не забыть скопировать файл, чем запомнить использование опции --assume-unchanged для всех, кто клонирует репозиторий. - person Dan; 15.01.2016
comment
@DerickBailey, вы также можете настроить сборку рейка по умолчанию на devtargets.default.rb, если devtargets.rb не существует. - person Luke; 30.09.2016
comment
@erjang, что находится в этом файле devtargets.default.rb? Пример? - person mmm; 05.02.2019
comment
@momomo да, из вопроса изначально - person rogerdpack; 16.01.2020

Для пользователей IntelliJ IDEA: если вы хотите игнорировать изменения для файла (или файлов), вы можете переместить его в другой Change Set.

  • Перейдите на Local Changes (Cmd + 9)
  • Выберите файл (ы), которые хотите игнорировать
  • F6, чтобы переместить их в другой Change Set
person Eugene    schedule 29.10.2015

Невозможно игнорировать изменения в отслеживаемом файле с помощью Git. Git FAQ объясняет это:

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

Заманчиво попытаться использовать определенные функции git update-index, а именно биты accept-unchanged и skip-worktree, но они не работают должным образом для этой цели и не должны использоваться таким образом.

Если ваша цель - работать с файлом конфигурации, то лучше всего добавить файл примера или шаблона, а затем либо попросить пользователя скопировать его на место, либо сценарий создаст соответствующий файл. Затем вы должны игнорировать расположение фактического файла конфигурации и проверять только пример или шаблон.

person bk2204    schedule 09.06.2021