Как восстановить спрятанные незафиксированные изменения

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

Кроме того, с тех пор я сделал некоторые изменения поверх записанных файлов кода.

Есть ли вероятность, что я могу получить спрятанные изменения в новую ветку, если это возможно?

Ответ 1

Легкий ответ на простой вопрос: git stash apply

Просто зайдите в ветку, в которую хотите внести изменения, а затем git stash apply. Затем используйте git diff, чтобы увидеть результат.

После того, как вы все закончите с вашими изменениями, apply выглядит хорошо, и вы уверены, что вам больше не нужен кошелек, а затем используйте git stash drop, чтобы избавиться от него.

Я всегда предлагаю использовать git stash apply, а не git stash pop. Разница заключается в том, что apply оставляет закладок вокруг, чтобы легко повторить попытку apply, или для поиска и т.д. Если pop может извлечь тайник, он немедленно также будет drop и если вы вдруг осознаете, что хотите извлечь его где-нибудь еще (в другой ветке) или с помощью --index или некоторых таких, это не так просто. Если вы apply, вы можете выбрать, когда drop.

Все это довольно незначительно, так или иначе, и для новичка до git он должен быть примерно таким же. (И вы можете пропустить все остальное!)


Что делать, если вы делаете более продвинутые или более сложные вещи?

Существует как минимум три или четыре разных способа использования git stash ". Вышеупомянутый вариант -" путь 1 "," простой способ":

  • Вы начали с чистой ветки, работали над некоторыми изменениями, а затем поняли, что делаете их в неправильной ветке. Вы просто хотите принять изменения, которые у вас есть, и "переместить" их в другую ветку.

    Это простой случай, описанный выше. Запустите git stash save (или обычный git stash, то же самое). Проверьте другую ветку и используйте git stash apply. Это получает git, чтобы объединить ваши предыдущие изменения, используя git довольно мощный механизм слияния. Осмотрите результаты внимательно (с помощью git diff), чтобы увидеть, нравится ли вам их, и если вы это сделаете, используйте git stash drop, чтобы сбросить тайник. Все готово!

  • Вы начали некоторые изменения и спрятали их. Затем вы переключились на другую ветку и начали больше изменений, забыв, что у вас были спрятанные.

    Теперь вы хотите сохранить или даже перенести эти изменения и применить свой тайник тоже.

    На самом деле вы можете git stash save снова, поскольку git stash создает "стек" изменений. Если вы это сделаете, у вас есть два закладок, один из которых называется stash, но вы также можете написать [email protected]{0} и один пишется [email protected]{1}. Используйте git stash list (в любое время), чтобы увидеть их все. Новейший всегда самый низкий. Когда вы git stash drop, он опускает самую новую, а та, которая была [email protected]{1}, перемещается в верхнюю часть стека. Если у вас было еще больше, то [email protected]{2} становится [email protected]{1} и т.д.

    Вы можете apply, а затем drop конкретный штамп: git stash apply [email protected]{2} и т.д. Сбрасывая конкретный кошелек, renumbers только более высокие номера. Опять же, номер без номера также [email protected]{0}.

    Если вы накапливаете множество задержек, это может стать довольно беспорядочным (был ли я был stash, я хотел [email protected]{7} или был он [email protected]{4}? Подождите, я просто нажал другой, теперь им 8 и 5?). Я лично предпочитаю переносить эти изменения на новую ветку, потому что у ветвей есть имена, а cleanup-attempt-in-December для меня намного больше, чем [email protected]{12}. (Команда git stash принимает необязательное сообщение сохранения, и это может помочь, но каким-то образом все мои штампы просто заканчиваются именем WIP on branch.)

  • (Экстра-продвинутый). Вы использовали git stash save -p или тщательно git add -ed и/или git rm -это определенные биты вашего кода перед запуском git stash save. У вас была одна версия в скрытом индексе/промежуточной области и другая (другая) версия в рабочем дереве. Вы хотите сохранить все это. Итак, теперь вы используете git stash apply --index, и это иногда терпит неудачу:

    Conflicts in index.  Try without --index.
    
  • Вы используете git stash save --keep-index, чтобы проверить "что будет сделано". Этот вопрос выходит за рамки этого ответа; см. fooobar.com/questions/5127/....

В сложных случаях рекомендуется сначала начать работу с "чистым" рабочим каталогом, выполнив любые изменения, которые у вас есть (в новой ветке, если хотите). Таким образом, "где-то", что вы их применяете, в нем нет ничего, и вы просто будете пытаться спрятать изменения:

git status               # see if there anything you need to commit
                         # uh oh, there is - let put it on a new temp branch
git checkout -b temp     # create new temp branch to save stuff
git add ...              # add (and/or remove) stuff as needed
git commit               # save first set of changes

Теперь вы находитесь на "чистой" отправной точке. Или, может быть, это больше похоже на это:

git status               # see if there anything you need to commit
                         # status says "nothing to commit"
git checkout -b temp     # optional: create new branch for "apply"
git stash apply          # apply stashed changes; see below about --index

Главное, чтобы помнить, что "кошелек" - это фиксация, это просто "смешное/странное" совершение, которое не "на ветке". Операция apply смотрит на то, что зафиксировала фиксация, и пытается повторить ее там, где вы сейчас находитесь. Кошелек все еще будет там (apply держит его вокруг), так что вы можете посмотреть на него больше или решить, что это было неправильное место для apply и повторить попытку по-другому или что-то еще.


В любое время, когда у вас есть кошелек, вы можете использовать git stash show -p, чтобы увидеть упрощенную версию того, что в кошельке. (Эта упрощенная версия относится только к изменениям "окончательного рабочего дерева", а не к сохраненным изменениям индекса, которые --index восстанавливается отдельно.) Команда git stash apply, без --index, просто пытается сделать те же самые изменения в вашей работе, в настоящее время.

Это верно, даже если у вас уже есть некоторые изменения. Команда apply с удовольствием применяет прикрытие к модифицированному рабочему каталогу (или, по крайней мере, пытается применить его). Вы можете, например, сделать это:

git stash apply stash      # apply top of stash stack
git stash apply [email protected]{1}  # and mix in next stash stack entry too

Здесь вы можете выбрать "подать заявку", выбрав специальные отметки для применения в определенной последовательности. Обратите внимание, однако, что каждый раз, когда вы в основном выполняете "git merge", и как сообщает документация слияния:

Выполнение слияния git с нетривиальными незафиксированными изменениями        обескуражен: возможно, он может оставить вас в состоянии, которое тяжело        для отказа от конфликта в случае конфликта.

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


Как насчет самого худшего возможного случая?

Скажем, вы делаете Lots Of Advanced git Stuff, и вы сделали кошелек и хотите git stash apply --index, но уже не можете применить сохраненный stash с --index, потому что ветвь слишком сильно расходится со времени, когда вы его сохранили.

Это то, что git stash branch для.

Если вы:

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

попытка воссоздания изменений определенно будет работать. Это то, что делает git stash branch newbranch. (И затем он сбрасывает тайник с момента его успешного применения.)


Некоторые последние слова о --index (что это за черт?)

Что делает --index, просто объяснить, но немного сложно внутренне:

  • Если у вас есть изменения, вы должны git add (или "stage" ) до commit ing.
  • Таким образом, при запуске git stash вы могли бы отредактировать оба файла foo и zorg, но только поставили один из них.
  • Итак, когда вы попросите вернуть тайник, может быть хорошо, если он git add add ed вещи и не git add не добавленные вещи. То есть, если вы add ed foo, но не zorg до того, как вы сделали stash, было бы неплохо иметь такую ​​же настройку. То, что было поставлено, должно снова быть поставлено; то, что было изменено, но не поставлено, должно быть снова изменено, но не поставлено.

Флаг --index в apply пытается настроить ситуацию таким образом. Если ваше дерево дерева чистое, это обычно работает. Если в вашем дереве уже есть материал add ed, вы можете увидеть, как здесь могут быть некоторые проблемы. Если вы не указали --index, операция apply не пытается сохранить всю старую/неустановленную настройку. Вместо этого он просто запускает механизмы git merge, используя фиксацию рабочего дерева в "сумке для хранения" . Если вы не заботитесь о сохранении поэтапного/нестатического, то оставить --index намного проще для git stash apply, чтобы сделать свое дело.

Ответ 2

git stash pop

получит все обратно на место

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

git checkout -b newbranch
git stash pop

Ответ 3

Чтобы сделать это простым, у вас есть два варианта для повторного применения вашего тайника:

  1. git stash pop - восстанавливает обратно в сохраненное состояние, но удаляет тайник из временного хранилища.
  2. git stash apply - восстановить обратно в сохраненное состояние и оставить список тайников для возможного последующего повторного использования.

Вы можете прочитать более подробно о git stashes в этой статье.

Ответ 4

Чтобы проверить ваш тайник: -

git stash list

применить определенный тайник нет из списка тайников: -

git stash применить stash @{2}

или для применения только первого тайника: -

Git Stash поп

Ответ 5

Для новичков: не пытайтесь делать что-то причудливое, сделайте резервную копию вашего кода в другой папке, перейдите по пути к хранилищу,

rm -rf repository_name

git clone "repository url"

повторно скопируйте резервную копию, добавьте и передайте ее снова

немного грубо, но всегда работаю