Сохранять git - файлы без изменений между проверками веток
Я использовал git --assume-unchanged yacs/settings/development.py
, чтобы игнорировать мой локальный файл конфигурации базы данных в моей ветке dev. Но когда я хочу переключать ветки (для развертываний), я получаю сообщение об ошибке, что у меня все еще есть изменения:
% git checkout production
error: Your local changes to the following files would be overwritten by checkout:
yacs/settings/development.py
Please, commit your changes or stash them before you can switch branches.
Aborting
Это раздражает. Единственный способ, которым я знаю, как обойти это, - это спрятать его:
% git stash
% git checkout production
% git merge dev
% ./deploy.sh
% git checkout dev
% git stash pop
# On branch dev
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: yacs/settings/development.py
#
Но теперь он снова возвращается в индекс (тьфу)! Есть ли лучшая альтернатива этому документообороту?
[Мне неинтересно, что локальные изменения остаются локально (ака, это нормально, если это производственная ветка), я просто не хочу, чтобы это было перенесено в удаленный репозиторий.]
Ответы
Ответ 1
Вы можете попробовать (справочная страница git update-index):
git update-index --skip-worktree -- path
Бит Skip-worktree может быть определен в одном (длинном) предложении: если при чтении записи он помечается как skip-worktree, то Git делает вид, что версия его рабочего каталога актуальна, и вместо этого читает индексную версию.
Однако, как упоминалось в "git предположить, что оно не изменилось по сравнению с пропуском рабочего дерева":
У обоих вариантов есть проблемы. --assume-unchanged
сбрасывает себя всякий раз, когда индекс сбрасывается (например, git reset
), так что, вероятно, вы рано или поздно сбиваете с толку. То же самое касается --skip-worktree
.
Кроме того, обязательно используйте Git 2.24 (4 квартал 2014 года).
С 2012 года (вопрос OP) git stash был портирован на C (он больше не является сценарием оболочки), но ему пришлось (в его новой реализации) (re-) научиться записывать обновленный индекс обратно на диск.
См. коммит 34933d0 (11 сентября 2019 г.) от Томаса Гаммерера (tgummerer
).
(Merged by Thomas Gummerer -- [TG45] -- in commit 34933d0, 20 Sep 2019)
stash
: убедитесь, что записали обновленный кеш
При преобразовании stash в C вызывает 'git update-index --refresh
'
были заменены функцией 'refresh_cache()
'.
Это нормально, если индекс нужен только для ядра, а не для чтения re- с диска.
Однако во многих случаях нам действительно нужно записать обновленный индекс на диск, например, "merge_recursive_generic()
" сбрасывает внутренний индекс перед чтением re- его с диска, а в случае "apply --quiet
", "refresh_cache()
", который у нас есть в данный момент, бессмысленно без записи индекса на диск.
Всегда пишите индекс после его обновления, чтобы убедиться, что в этом нет регрессий по сравнению со сценарием.
В будущем мы можем по возможности избегать записи, убедившись, что ни один из последующих вызовов на самом деле не нуждается в обновленном кэше, и это не ожидается, что он будет обновлен после выхода из stashа или уже записан где-то еще.
Ответ 2
То, что я начал делать, это создать ветку от мастера, называемую private, которая имеет мои локальные изменения; подумайте об этом как о прокси-ветке между моей рабочей веткой и мастером. Я могу переустановить мою текущую ветку работы на частную, когда мне нужны мои локальные изменения, и у меня есть несколько псевдонимов в моем .gitconfig, которые автоматизируют хранение личных данных с мастером. Когда мне нужно объединиться для освоения, мои псевдонимы обязательно переконфигурируют - сначала откройте мою рабочую ветвь.
Я разместил запись в блоге об этом более подробно здесь http://blog.ericwoodruff.me/2013/02/git-private-branch-pattern.html
Ответ 3
Решение, которое работало для меня, заключалось в использовании --skip-worktree. Однако, как и некоторые выше, я изо всех сил пытался переключиться между билетами и основной ветвью без git, жалуясь даже после того, как я установил флаг -skip-worktree в файле, изменения которого я хотел бы оставаться локальными.
Кажется, что вы столкнетесь с этой проблемой, если вы внесете изменения в файл локального файла перед запуском --skip-worktree, что и случилось со мной.
Один предлагаемый способ обхода выше, это добавить файл в your_repo/.git/info/exclude
. Но я не хотел добавлять файл в список исключений, поэтому я сделал следующее из моего рабочего каталога:
-
cp <local-only_file> ~/
- копировать файл с локальными изменениями в безопасном месте в файловой системе
-
git checkout <local-only_file>
- в рабочем дереве, файл checkout, чтобы он соответствовал файлу master branch
-
git update-index --skip-worktree -- <local-only_file>
-
cp ~/<local-only_file> .
- копировать файл под вопросом из безопасного места обратно в рабочее дерево
-
git diff
- Никакие изменения не должны отображаться; если вы нажмете на основное репо, никакие изменения в
<local-only_file>
не включены в push
Ответ 4
эта проблема возникает, когда пропущенный файл не совпадает с файлом в ветки, которую вы пытаетесь оформить, или файлом, который вы пытаетесь извлечь.