Git - Разница между "предполагать-неизменным" и "skip-worktree"
У меня есть локальные изменения в файле, который я не хочу фиксировать в моем репозитории. Это файл конфигурации для создания приложения на сервере, но я хочу создать локально с различными настройками. Естественно, файл всегда отображается, когда я делаю "git status" как что-то, что нужно поставить. Я хотел бы скрыть это конкретное изменение и не совершить его. Я не буду вносить никаких изменений в файл.
После некоторого копания, я вижу 2 варианта: "предполагать-без изменений" и "skip-worktree". Предыдущий вопрос здесь говорит о них, но на самом деле не объясняет их различия. Мой вопрос таков: как две команды разные? Почему кто-то использует тот или иной?
Ответы
Ответ 1
Вы хотите skip-worktree
.
assume-unchanged
предназначен для случаев, когда стоит проверить, была ли изменена группа файлов; когда вы устанавливаете бит, git
(конечно) предполагает, что файлы, соответствующие этой части индекса, не были изменены в рабочей копии. Таким образом, это позволяет избежать беспорядка вызовов stat
. Этот бит теряется всякий раз, когда изменяется запись файла в индексе (поэтому, когда файл изменяется вверх по потоку).
skip-worktree
больше: даже если git
знает, что файл был изменен (или должен быть изменен с помощью reset --hard
или тому подобного), он будет притворяться, что он не был, используя версию из индекса. Это сохраняется до тех пор, пока индекс не будет отброшен.
Существует хорошая сводка разницы этой разницы и типичных вариантов использования здесь: http://fallengamer.livejournal.com/93321.html.
Из этой статьи:
-
--assume-unchanged
предполагает, что разработчик не должен изменять файл. Этот флаг предназначен для повышения производительности для не изменяющихся папок, таких как SDK.
-
--skip-worktree
полезно, когда вы указываете git не касаться определенного файла, когда разработчики должны изменять его. Например, если в главном репозитории вверх по потоку размещены готовые файлы конфигурации , и вы не хотите случайно вносить изменения в эти файлы, --skip-worktree
- это именно то, что вы хотите.
Ответ 2
Примечание: fallengamer провел несколько тестов в 2011 году (поэтому они могут быть устаревшими), и вот его выводы:
операции
- Файл меняется как в локальном репозитории, так и в апстриме
git pull
:
Git сохраняет локальные изменения в любом случае.
Таким образом, вы случайно не потеряете данные, помеченные любым из флагов. - Файл с
assume-unchanged
флагом: Git не будет перезаписывать локальный файл. Вместо этого он будет выводить конфликты и советы, как их разрешать - Файл с флагом
skip-worktree
: Git не будет перезаписывать локальный файл. Вместо этого он будет выводить конфликты и советы, как их разрешать
- Файл меняется как в локальном репозитории, так и в апстриме, все равно пытаясь вытащить
git stash
git pull
Использование skip-worktree
приводит к некоторой дополнительной ручной работе, но, по крайней мере, вы не потеряете данные, если у вас будут локальные изменения. - Файл с флагом
assume-unchanged
: Отменяет все локальные изменения без возможности их восстановления. Эффект похож на " git reset --hard
. 'вызов git pull
будет успешным - Файл с флагом
skip-worktree
: Stash не будет работать с файлами skip-worktree
. ' git pull
потерпит неудачу с той же ошибкой, что и выше. Разработчик вынужден вручную сбросить skip-worktree
флаг, чтобы иметь возможность копить и завершить неудовлетворительные pull
.
- Нет локальных изменений, изменен файл апстрима
git pull
Оба флага не помешают вам получить изменения в апстриме. Git обнаруживает, что вы нарушили обещание assume-unchanged
и решает отразить реальность, сбросив флаг. - Файл с
assume-unchanged
флагом: содержимое обновлено, флаг потерян.
' git ls-files -v
покажет, что флаг изменен на H
(из h
). - Файл с флагом
skip-worktree
: содержимое обновлено, флаг сохранен.
' git ls-files -v
' будет показывать тот же S
флаг, что и перед pull
.
- С измененным локальным файлом
git reset --hard
Git не трогает файл skip-worktree
и отражает реальность (файл, который обещал быть неизменным, фактически был изменен) для файла assume-unchanged
. - Файл с флагом "
assume-unchanged
: содержимое файла восстанавливается. Флаг сбрасывается в H
(из h
). - Файл с флагом
skip-worktree
: содержимое файла не повреждено. Флаг остается прежним.
Он добавляет следующий анализ:
-
Похоже, что skip-worktree
очень старается сохранить ваши локальные данные. Но это не мешает вам вносить изменения, если это безопасно. Плюс git не сбрасывает флаг при pull
.
Но игнорирование команды " reset --hard
" может стать неприятным сюрпризом для разработчика.
-
Assume-unchanged
флаг Assume-unchanged
может быть потерян при операции pull
и локальные изменения внутри таких файлов, кажется, не важны для git.
Увидеть:
Он делает вывод:
На самом деле ни один из флагов не является достаточно интуитивным.
-
assume-unchanged
предполагается, что разработчик не должен изменять файл. Если файл был изменен - тогда это изменение не важно. Этот флаг предназначен для повышения производительности для неизменяемых папок, таких как SDK.
Но если обещание нарушено и файл фактически изменен, git возвращает флаг, чтобы отразить реальность. Вероятно, хорошо иметь некоторые несовместимые флаги в обычно не предназначенных для изменения папках.
-
С другой стороны, skip-worktree
полезно, когда вы указываете git не трогать определенный файл. Это полезно для уже отслеженного файла конфигурации.
Основной основной репозиторий содержит несколько готовых конфигураций, но вы бы хотели изменить некоторые настройки в конфигурации, чтобы иметь возможность проводить локальное тестирование. И вы не хотите случайно проверять изменения в таком файле, чтобы повлиять на производственный конфиг. В этом случае skip-worktree
создает идеальную сцену.