Почему "git stash apply" ставит мои изменения?

Я делаю изменения, а затем я git stash и затем я git stash apply

Мой вопрос

  1. почему после того как я git stash applyмое изменение становится "постановочным"? то есть я ничего не увижу, если сделаю git diffЯ вижу разницу, только если git diff --cached?

  2. Есть ли в любом случае, чтобы "отменить" мои изменения, поставленные git stash apply команда?

  3. Есть ли какая-нибудь команда 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 и предположительно предназначен для предотвращения случайного изменения изменений в рабочем дереве во время слияния.

Однако эта проверка имеет две проблемы:

  1. Это чрезмерно ограничительно. Если мой тайник меняет только файл "foo", но "bar"грязно в рабочем дереве, это помешает нам применить тайник.

  2. Это избыточно. Мы вообще не касаемся рабочего дерева, пока не вызовем рекурсивный слияние.
    Но он имеет свои собственные (гораздо более точные) проверки, чтобы избежать потери данных рабочего дерева, и прервет слияние с более приятным сообщением, сообщающим нам, какие пути были проблемами.

Таким образом, мы можем просто полностью отказаться от чека.

Использование индекса для управления слиянием, выполненным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
Другие вопросы по тегам