Могу ли я git зафиксировать 'файл и игнорировать его изменения в содержимом?

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

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

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

Это возможно? Это, безусловно, будет приятной особенностью...

Ответ 1

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

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

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

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

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

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

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

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

$ 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, и вы можете сделать нормальный сбой и слияние и т.д. в этой точке.

Ответ 2

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

Ответ 3

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

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

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

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

Ответ 4

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

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