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


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

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

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

11 128

11 ответов:

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

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

в принципе

  1. создает патч
  2. трубы, которые к команде apply
  3. если есть какие-либо конфликты, они должны быть решены с помощью 3-way merge
  4. если применить (или объединить) удалось, он отбрасывает только что примененный элемент тайника...

интересно, почему нет никакого -f (сил) вариант 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 параметр, который позволяет разрешать конфликты непосредственно через 3-полосное слияние.

Я делаю это таким образом:

git add -A
git stash apply

а потом (опционально):

git reset

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

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

  1. экспорт stash@{0} как патч:

    git stash show - P stash@{0} > Stash0.патч

  2. вручную применить изменения:

    git применить Stash0.патч

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

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

$ git stash save "description of current changes"
$ git stash pop stash@{1}

это будет прятать текущие изменения, а затем поп второй тайник из стека тайника.

решение Матиаса определенно ближе всего к git stash pop-force (и действительно, давайте git devs, давайте уже получим этот вариант!)

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

  1. git commit-a-m "Fixme"
  2. git stash pop
  3. git commit-a -- amend
  4. git reset HEAD~

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

* * EDIT**

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

  1. git commit-a-m "Fixme"
  2. git stash pop
  3. git reset HEAD~

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

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

  1. выяснить хэш тайника использовать git reflog --all
  2. объединить этот хэш с веткой, которую вы интересуете

Я нашел Матиас 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.)

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

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

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

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

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

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