Могу ли я 'git commit' файл и игнорировать изменения его содержимого? - PullRequest
304 голосов
/ 23 июля 2010

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

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

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

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

Ответы [ 4 ]

402 голосов
/ 23 июля 2010

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

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

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

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

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

- [нет-] предполагают, без изменений
Когда указан этот флаг, имена объектов, записанные для путей, не обновляются. Вместо этого, эта опция устанавливает / отменяет бит «предположить неизменным» для путей. Когда бит «предположить, что без изменений» включен, пользователь обещает не изменять файл и позволяет 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, и вы сможете в этот момент выполнять обычное копирование, слияние и т. Д.

71 голосов
/ 21 апреля 2017

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

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

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

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

36 голосов
/ 23 июля 2010

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

0 голосов
/ 29 октября 2015

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

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