Git - Разница между "предположим, без изменений" и "пропустить рабочее дерево"

У меня есть локальные изменения в файле, которые я не хочу фиксировать в своем хранилище. Это файл конфигурации для сборки приложения на сервере, но я хочу собрать локально с другими настройками. Естественно, файл всегда появляется, когда я делаю "git status" как что-то, что нужно поставить. Я хотел бы скрыть это конкретное изменение, а не совершать его. Я не буду вносить другие изменения в файл.

После нескольких копаний я вижу 2 варианта: "предположить, без изменений" и "пропустить рабочее дерево". Предыдущий вопрос здесь говорит о них, но на самом деле не объясняет их различия. У меня такой вопрос: чем отличаются две команды? Зачем кому-то использовать один или другой?

3 ответа

Решение

Ты хочешь 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 это именно то, что вы хотите.

Примечание: fallengamer провел несколько тестов в 2011 году (поэтому они могут быть устаревшими), и вот его выводы:

операции

  • Файл изменен как в локальном репозитории, так и в апстриме
    git pull:
    Git сохраняет локальные изменения в любом случае.
    Таким образом, вы случайно не потеряете данные, помеченные любым из флагов.
    • Файл с assume-unchanged flag: Git не будет перезаписывать локальный файл. Вместо этого он будет выводить конфликты и советы, как их разрешать
    • Файл с skip-worktree flag: Git не будет перезаписывать локальный файл. Вместо этого он будет выводить конфликты и советы, как их разрешать

,

  • Файл меняется как в локальном репозитории, так и в апстриме, все равно пытаясь вытащить
    git stash
    git pull
    С помощью skip-worktree приводит к некоторой дополнительной ручной работе, но, по крайней мере, вы не потеряете данные, если у вас будут локальные изменения.
    • Файл с assume-unchanged flag: Отменяет все локальные изменения без возможности их восстановления. Эффект как git reset --hard". ' git pull вызов будет успешным
    • Файл с skip-worktree flag: Stash не будет работать на skip-worktree файлы. ' git pull 'потерпит неудачу с той же ошибкой, что и выше. Разработчик вынужден сбросить вручную skip-worktree флаг, чтобы иметь возможность скрыть и завершить неудачу pull,

,

  • Нет локальных изменений, изменен файл апстрима
    git pull
    Оба флага не помешают вам получить изменения вверх по течению. Git обнаруживает, что вы сломали assume-unchanged обещают и выбирают, чтобы отразить реальность, сбросив флаг.
    • Файл с assume-unchanged flag: содержимое обновлено, флаг утерян.
      ' git ls-files -v будет показывать, что флаг изменен на H (от h).
    • Файл с skip-worktree flag: содержимое обновляется, флаг сохраняется.
      ' 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 флаг может быть потерян на pull операция и локальные изменения внутри таких файлов не кажутся важными для git.

Увидеть:

Он делает вывод:

На самом деле ни один из флагов не является достаточно интуитивным.

  • assume-unchanged Предполагается, что разработчик не должен изменять файл. Если файл был изменен - ​​то это изменение не важно. Этот флаг предназначен для повышения производительности для неизменяемых папок, таких как SDK.
    Но если обещание нарушено и файл фактически изменен, git возвращает флаг, чтобы отразить реальность. Возможно, все-таки есть несколько несовместимых флагов в папках, которые обычно не подлежат изменению.

  • С другой стороны skip-worktree полезно, когда вы указываете git не трогать определенный файл. Это полезно для уже отслеженного файла конфигурации.
    Основной основной репозиторий содержит несколько готовых конфигураций, но вы бы хотели изменить некоторые параметры в конфигурации, чтобы иметь возможность проводить локальное тестирование. И вы не хотите случайно проверять изменения в таком файле, чтобы повлиять на производственный конфиг. В таком случае skip-worktree делает идеальную сцену

Используйте skip-worktree, как в:

      git update-index --skip-worktree changedfile.txt

подтвердить статус файла:

       git ls-files -v
 S changedfile.txt

Первая буква S означает, что файл помечен параметром skip-worktree.

Причина:

«git-update-index --assume-unchanged никогда не предназначался для игнорирования изменений в отслеживаемых файлах (только для сохранения некоторой статистики). Поэтому не предлагайте его как средство для достижения этого».

ПОСМОТРЕТЬ: https://github.com/git/git/commit/936d2c9301e41a84a374b98f92777e00d321a2ea

--skip-worktree объяснил:

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

Чтобы отключить эту опцию, используйте--no-skip-worktreeкак в:

      git update-index --no-skip-worktree changedfile.txt

--assume-без изменений объяснил:

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

Он используется следующим образом:

      git update-index --assume-unchanged changedfile.txt

подтвердить статус файла:

      git ls-files -v
h changedfile.txt

Первая буква h означает, что файл помечен как неизмененный. Чтобы отключить этот параметр, используйте–no-assume-unchangedкак в:

      git update-index --no-assume-unchanged changedfile.txt
Другие вопросы по тегам