Отмена случайного всплывающего окна git stash

Я спрятал некоторые локальные изменения перед сложным слиянием, сделал слияние, а потом по глупости забыл зафиксировать перед запуском git stash pop. Популярность создала некоторые проблемы (плохие вызовы методов в большой кодовой базе), которые трудно отследить. Я запускал git stash show, так что я хотя бы знаю, какие файлы были изменены. По крайней мере, я думаю, это урок, чтобы совершать больше.

Мой вопрос: можно ли отменить всплывающее окно тайника без отмены слияния?


person nren    schedule 01.07.2011    source источник
comment
Вам не должно быть позволено git stash pop без предварительной фиксации. Что вы сделали для этого?   -  person Chris Jester-Young    schedule 01.07.2011
comment
Не уверен, если честно (это было вчера). Слияние не произошло само по себе, потому что были конфликты. После этого я каким-то образом смог запустить stash pop.   -  person nren    schedule 01.07.2011
comment
Я сделал это только что, используя git версии 1.7.9.msysgit.0. У меня были неустановленные файлы, и всплывающее окно тайника просто объединило все.   -  person PandaWood    schedule 20.11.2012
comment
Я смог запустить git stash pop после подготовки изменений (хотя я не делал фиксации) с версией git 2.25.0.windows.1   -  person Artyom Gevorgyan    schedule 07.04.2020
comment
Если вы проиндексировали свои изменения и потеряли их при выполнении stash pop/apply перед фиксацией, вы можете активировать git fsck --lost-found. Эта команда будет перебирать висячие BLOB-объекты (фактические файлы для тех, кто не знаком с терминологией git), которые были подготовлены, но нигде не зафиксированы (поэтому висят), и поместит их в каталог .git/lost-found/ , где вы можете git show просмотреть их и посмотреть, те ли это файлы, которые вы ищете.   -  person Artyom Gevorgyan    schedule 09.04.2020


Ответы (3)


Попробуйте использовать Как восстановить упавший тайник в Git?, чтобы найти тайник, который вы вытащили. Я думаю, что всегда есть два коммита для тайника, так как он сохраняет индекс и рабочую копию (поэтому часто индексный коммит будет пустым). Затем git show их, чтобы увидеть различия, и используйте patch -R, чтобы отменить их.

person Ben Jackson    schedule 01.07.2011
comment
Вау, это сработало. Мне удалось найти коммиты тайника с помощью git fsck --no-reflog | awk '/dangling commit/ {print $3}' (по ссылке), и я просто вручную нашел проблему из этого diff. Спасибо! - person nren; 01.07.2011
comment
fsck выводит огромный список. Утомительно git показывать каждый SHA1. Как ты это делаешь ? - person meson10; 06.10.2013
comment
@ meson10: К сожалению, тайники хранятся в журнале ссылок, что было бы очевидным способом (если бы они были настоящей веткой) посмотреть историю извлеченных тайников. Также позвольте мне предположить, что голосование против + просьба о помощи - не лучшая стратегия. - person Ben Jackson; 06.10.2013
comment
Мне потребовалось немного коверкать, чтобы сделать это правильно. Вот результат моей работы: git diff -p ${STACH_SHA1}~1 ${STASH_SHA1} | patch -R -p1; Я попытался использовать git show, как было предложено, но его вывод не подходил для патча; также мне пришлось указать параметр -p1 для исправления, чтобы удалить элементы a/.. и b/.., которые git diff помещает перед файлами, иначе он не разрешит пути из корня репозитория. ПРЕДЛОЖЕНИЕ: будьте осторожны и зафиксируйте беспорядок в отдельной ветке, прежде чем играть с патчем. - person protoboolean; 14.02.2017
comment
@BenJackson В вашем ответе всегда означает, что и stash pop, и stash push вызовут фиксацию, которая сохранит изменения в индексе и рабочем каталоге, верно? - person Artyom Gevorgyan; 07.04.2020
comment
Я нашел ответ на свой вопрос, заданный здесь, в комментариях. stash save действительно делает снимок (индекс, рабочее дерево, а если активирован флаг -u, то и неотслеживаемые файлы), который можно показать с помощью git log refs/stash. stash pop/apply ничего подобного не делает, по крайней мере, на справочных страницах нет никаких признаков этого. - person Artyom Gevorgyan; 09.04.2020

От 1_

Recovering stashes that were cleared/dropped erroneously
   If you mistakenly drop or clear stashes, they cannot be recovered through the normal safety mechanisms. However, you can try the
   following incantation to get a list of stashes that are still in your repository, but not reachable any more:

       git fsck --unreachable |
       grep commit | cut -d\  -f3 |
       xargs git log --merges --no-walk --grep=WIP

Это помогло мне лучше, чем принятый ответ с тем же сценарием.

person kachar    schedule 28.10.2013
comment
Обратите внимание, что многие решения, включающие поиск WIP, полагаются на сообщения тайника по умолчанию. Если вы дадите своим тайникам явные сообщения, они могут не содержать WIP. - person Ben Jackson; 18.06.2014
comment
Спасибо. Я добавил параметр --oneline в команду журнала, чтобы улучшить читаемость. - person basslo; 01.03.2017
comment
Это только поможет вам найти SHA коммита тайника. Но если он интегрирован с комментарием @basilikode из принятого ответа (git diff SHA~1 SHA | patch -R), он работает нормально. Я рекомендую сначала использовать path --dry-run для проверки. - person Jarek C; 14.05.2020

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

  1. Переместите все изменения, включая изменения слияния, обратно в тайник, используя «git stash».
  2. Запустите слияние еще раз и зафиксируйте свои изменения (без изменений из удаленного тайника)
  3. Запустите «git stash pop», который должен игнорировать все изменения из вашего предыдущего слияния, поскольку теперь файлы идентичны.

После этого у вас останутся только изменения из тайника, который вы сбросили слишком рано.

person markus    schedule 31.01.2018