Почему «git stash apply» ставит мои изменения? - PullRequest
17 голосов
/ 06 августа 2009

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

Мой вопрос

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

  2. Есть ли возможность «отменить» мои изменения, поставленные командой git stash apply?

  3. Есть ли какая-нибудь команда git, позволяющая мне «сделать резервную копию моих изменений, сбросить их в HEAD и скопировать мою резервную копию обратно»? Я подумал git stash, а затем git stash apply - это та команда, но как она «устроила» все мои изменения? Есть ли эквивалент, который позволил бы мне git stash apply без постановочной части моих изменений?

Ответы [ 3 ]

13 голосов
/ 06 августа 2009

Если вы обнаружите, что ваши изменения неожиданно подготовлены, выполните:

git reset HEAD

Обычно я вижу это только в случае конфликта при применении сохраненных изменений.Перед выполнением git reset.

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

9 голосов
/ 19 сентября 2016

Почему 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», мы можем столкнуться с конфликтом и добавить новые записи в индекс.
Восстановление в исходное состояние в этот момент затруднено, потому что такие инструменты, как "git reset --keep", сдувают все, что поставлено .
Мы можем сделать это более безопасным, отказавшись от применения при поэтапных изменениях.

3 голосов
/ 06 августа 2009

Я думаю, что что-то может быть не так в вашей конфигурации, так как git stash записывает состояние индекса и рабочего дерева перед сбросом до последней фиксации, git stash apply должен пытаться восстановить состояние индекса, только если вы используйте опцию --index.

Одна возможная путаница состоит в том, что если у вас есть конфликт (то есть, возникают конфликты слияния, потому что тайник применяется к другому коммиту, где файлы, затронутые тайником, были изменены с момента коммита, в котором был сделан тайник ), затем, если вы используете mergetool для разрешения конфликтов, mergetool автоматически внесет изменения в файлы при успешном разрешении.

Как утверждает Грег Хьюгилл, простой сброс приведет к отмене всех поэтапных изменений.

git reset
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...