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.
Увидеть:
Комментарий Junio (текущий сопровождающий git) относительно намерения
assume-unchanged
,В частности, Хунио отмечает, что изменения в
assume-unchanged
Файлы могут быть случайно зафиксированы: "если Git может определить путь, который помечен какassume-unchanged
был изменен без дополнительных затрат lstat(2), он оставляет за собой право сообщить, что путь был изменен (в результатеgit commit -a
волен совершить это изменение)."разница между
assume-unchanged
а такжеskip-worktree
как обсуждалось в списке рассылки git при добавленииskip-worktree
патч
Он делает вывод:
На самом деле ни один из флагов не является достаточно интуитивным.
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