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 создает идеальную сцену.