Почему "git stash apply" ставит мои изменения?
Я делаю изменения, а затем я git stash
и затем я git stash apply
Мой вопрос
почему после того как я
git stash apply
мое изменение становится "постановочным"? то есть я ничего не увижу, если сделаюgit diff
Я вижу разницу, только еслиgit diff --cached
?Есть ли в любом случае, чтобы "отменить" мои изменения, поставленные
git stash apply
команда?Есть ли какая-нибудь команда git, позволяющая мне "сделать резервную копию моих изменений, сбросить их в ГОЛОВУ и скопировать мою резервную копию обратно"? я думал
git stash
а потомgit stash apply
Это команда, но как она "устроила" все мои изменения? Есть ли эквивалент, который позволил бы мнеgit stash apply
без постановочной части моих изменений?
3 ответа
Если вы обнаружите, что ваши изменения были неожиданно подготовлены, выполните:
git reset HEAD
Я обычно вижу это только в случае конфликта при применении скрытых изменений. Вы должны проверить, так ли это, прежде чем делать git reset
,
git stash
Команда является наиболее подходящей командой для вашего варианта использования. Я использую это все время именно для этой цели.
Почему git stash применяет мои изменения?
Все, что повлияет на ваше рабочее дерево ( например,git checkout -- afile
) сначала повлияет на ваш индекс.
Индекс является посредником для перемещения вещей из вашего рабочего дерева в хранилище объектов И для перемещения вещей из хранилища объектов в ваше рабочее дерево.
Индекс также используется git stash apply
для записи конфликтов слияния, так как в индексе есть записи stage-n. Увидеть git merge
:
Для конфликтующих путей индексный файл записывает до трех версий:
- на этапе 1 хранится версия от общего предка,
- 2 этап от HEAD, и
- этап 3 от MERGE_HEAD (вы можете проверить этапы с
git ls-files -u
).
В истории эволюцииgit stash --apply
следует отметить два интересных события: в апреле 2011 года (Git 1.7.5.1, commit e0e2a9c), stash
уронил грязную проверку рабочего дерева.
Прежде чем применить тайник, мы проверяем, нет ли изменений в рабочем дереве, которых нет в индексе. Эта проверка восходит к оригиналу
git-stash.sh
и предположительно предназначен для предотвращения случайного изменения изменений в рабочем дереве во время слияния.Однако эта проверка имеет две проблемы:
Это чрезмерно ограничительно. Если мой тайник меняет только файл "
foo
", но "bar
"грязно в рабочем дереве, это помешает нам применить тайник.Это избыточно. Мы вообще не касаемся рабочего дерева, пока не вызовем рекурсивный слияние.
Но он имеет свои собственные (гораздо более точные) проверки, чтобы избежать потери данных рабочего дерева, и прервет слияние с более приятным сообщением, сообщающим нам, какие пути были проблемами.Таким образом, мы можем просто полностью отказаться от чека.
Использование индекса для управления слиянием, выполненнымgit stash apply
привести к другой ошибке, обнаруженной в апреле 2015 года, Git 2.4.2, commit ed178ef:
stash
: требуется чистый индекс для примененияЕсли вы поместили содержимое в свой индекс и запустите "
stash apply
msgstr "мы можем столкнуться с конфликтом и добавить новые записи в индекс.
Восстановление в исходное состояние в этот момент затруднено, потому что инструменты типа "git reset --keep
Сдувает все, что поставлено.
Мы можем сделать это более безопасным, отказавшись от применения при поэтапных изменениях.
Я думаю, что что-то может быть не так в вашей конфигурации, пока git stash
записывает состояние индекса и рабочего дерева перед сбросом до последней фиксации, git stash apply
пытаться восстановить состояние индекса, только если вы используете --index
вариант.
One possible point of confusion is that if you have conflict (ie there are merge conflicts introduced because the stash is being applied to a different commit where the files affected by the stash have been changed since the commit at which the stash was made), then if you use mergetool
to resolve the conflicts, mergetool
will automatically stage changes to the files on a successful resolution.
As Greg Hewgill states a simple reset will unstage all staged changes.
git reset