Git stash: "Нельзя применять к грязному рабочему дереву, пожалуйста, выполните свои изменения"

Я пытаюсь применить изменения, которые я ранее спрятал с помощью git stash pop, и получить сообщение:

Cannot apply to a dirty working tree, please stage your changes

Любое предложение о том, как с этим бороться?

Ответ 1

Когда мне нужно применить спрятанные изменения к грязной рабочей копии, например. поп больше, чем один набор изменений из кошелька, я использую следующее:

$ git stash show -p | git apply -3 && git stash drop

В основном это

  • создает патч
  • что для команды apply
  • если есть какие-либо конфликты, они должны быть разрешены с помощью трехстороннего слияния
  • если применить (или слить) преуспел, он удаляет только что примененный элемент stash...

Интересно, почему нет опции -f (force) для git stash pop, которая должна точно вести себя как однострочный выше.

Тем временем вы можете добавить этот однострочный шрифт в псевдоним git:

$ git config --global --replace-all alias.unstash \
   '!git stash show -p | git apply -3 && git stash drop'
$ git unstash

Благодаря @SamHasler для указания параметра -3, который позволяет разрешать конфликты напрямую с помощью трехмерного слияния.

Ответ 2

Я делаю это следующим образом:

git add -A
git stash apply

а затем (необязательно):

git reset

Ответ 3

Вы можете сделать это, не заставляя свои текущие изменения экспортировать стат, который вы хотите в качестве файла патча, и вручную его применять.

Например, скажем, вы хотите применить stash @{0} к грязному дереву:

  • Экспорт stash @{0} в качестве патча:

    git stash show -p stash @{0} > Stash0.patch

  • Вручную применить изменения:

    git применить Stash0.patch

Если второй шаг не удался, вам нужно будет отредактировать файл Stash0.patch, чтобы исправить любые ошибки, а затем повторите попытку git.

Ответ 4

Либо очистите рабочий каталог с помощью git reset, зафиксируйте изменения, либо, если вы хотите сохранить текущие изменения, попробуйте:

$ git stash save "description of current changes"
$ git stash pop [email protected]{1}

Это закроет текущие изменения, а затем вытащите второй тайник из стека стека.

Ответ 5

Решение Mathias, безусловно, самое близкое к git stash pop -force (и действительно, c'mon git devs, дайте эту возможность уже!)

Однако, если вы хотите сделать то же самое, используя только команды git, вы можете:

  • git commit -a -m "Fixme"
  • git stash pop
  • git commit -a -amend
  • git reset HEAD ~

Другими словами, сделайте фиксацию (которую мы никогда не будем нажимать) ваших текущих изменений. Теперь, когда ваше рабочее пространство чистое, поп ваш трюк. Теперь скопируйте изменения кошелька в качестве поправки к предыдущей фиксации. Сделав это, у вас теперь есть оба набора изменений, объединенных в единую фиксацию ( "Fixme" ); просто reset (-soft NOT --hard, поэтому ничего не потеряно), ваш чек на "один до этого фиксации", и теперь у вас есть оба набора изменений, полностью незафиксированные.

** EDIT **

Я просто понял это на самом деле еще проще; вы можете полностью пропустить шаг 3, поэтому...

  • git commit -a -m "Fixme"
  • git stash pop
  • git reset HEAD ~

(Зафиксировать текущие изменения, вытеснить спрятанные изменения, reset, которые сначала совершают, чтобы получить оба набора изменений, объединенные в незафиксированном состоянии.)

Ответ 6

Ни один из этих ответов не работает, если вы окажетесь в такой ситуации, как я сделал сегодня. Независимо от того, сколько git reset --hard я сделал, это ни к чему. Мой ответ (официально не был каким-либо образом):

  • Извлеките хэш-таблицу с помощью git reflog --all
  • Объедините этот хеш с интересующей вас веткой.

Ответ 7

Я также нашел решение Mathias Leppich, чтобы работать отлично, поэтому я добавил псевдоним для своего глобального .gitconfig

[alias]
        apply-stash-to-dirty-working-tree = !git stash show -p | git apply && git stash drop

Теперь я могу просто набрать

git apply-stash-to-dirty-working-tree

который отлично работает для меня.

(Ваш пробег может отличаться от этого длинного псевдонима. Но мне нравится доза многословия, когда она заканчивается завершением bash.)

Ответ 8

Вы можете применить кошелек к "грязному" дереву, выполнив git add, чтобы выполнить любые сделанные вами изменения, тем самым очистив дерево. Затем вы можете git stash pop и применить спрятанные изменения, без проблем.

Ответ 9

У вас есть файлы, которые были изменены, но не были зафиксированы. Или:

git reset --hard HEAD (to bring everything back to HEAD)

или, если вы хотите сохранить изменения:

git checkout -b new_branch
git add ...
git commit
git checkout -b old_branch
git stash pop

Ответ 10

У меня была та же проблема, но git имел ноль с измененными файлами. Оказывается, у меня был файл index.lock, который лежал. Удаление этого решения проблемы.

Ответ 11

Мне не удалось заставить большинство из них работать; по какой-то причине он всегда думает, что у меня есть локальные изменения в файле. Я не могу применить кошельку, патчи не будут применяться, checkout и reset --hard терпят неудачу. Что в конечном итоге сработало, это сохранение stash как ветки с git stash branch tempbranchname, а затем выполнение обычного слияния ветвей: git checkout master и git merge tempbranchname. Из http://git-scm.com/book/en/Git-Tools-Stashing:

Если вам нужен более простой способ проверить спрятанные изменения снова, вы можете запустите ветвь git, которая создает для вас новую ветку, проверяет фиксация, на которой вы были, когда вы спрятали свою работу, повторно использует вашу работу там, а затем отбрасывает тайник, если он успешно применяется