Как восстановить спрятанные незафиксированные изменения
У меня были некоторые незафиксированные изменения в моей ветке разработки, и я спрятал их, используя git stash
, но были некоторые изменения, которые были очень важны среди тех, кто спрятан. Есть ли способ вернуть эти изменения?
Кроме того, с тех пор я внес некоторые изменения в файлы с сохраненным кодом.
Есть ли шанс, что я смогу получить спрятанные изменения в новую ветку, если это возможно?
8 ответов
Простой ответ на простой вопрос 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 stash". Выше для "способ 1", "легкий путь":
Вы начали с чистой ветки, работали над некоторыми изменениями, а затем поняли, что делаете их не в той ветке. Вы просто хотите принять изменения, которые у вас есть, и "переместить" их в другую ветку.
Это простой случай, описанный выше. Бежать
git stash save
(или простоgit stash
, то же самое). Проверьте другую ветку и используйтеgit stash apply
, Это позволяет git слиться с вашими более ранними изменениями, используя довольно мощный механизм слияния git. Внимательно изучите результаты (сgit diff
), чтобы увидеть, если они вам нравятся, и если вы делаете, используйтеgit stash drop
бросить заначку. Вы сделали!Вы начали некоторые изменения и спрятали их. Затем вы переключились на другую ветку и начали больше изменений, забыв, что у вас есть спрятанные.
Теперь вы хотите сохранить или даже перенести эти изменения, а также применить свой тайник.
Вы можете на самом деле
git stash save
опять же, какgit stash
делает "стек" изменений. Если вы сделаете это, у вас есть два тайника, один только что называетсяstash
- но вы также можете написатьstash@{0}
- и один пишетсяstash@{1}
, использованиеgit stash list
(в любое время), чтобы увидеть их всех. Новейший всегда с самым низким номером. Когда тыgit stash drop
, он падает самый новый, и тот, который былstash@{1}
перемещается на вершину стека. Если бы у вас было еще больше, тот, который былstash@{2}
становитсяstash@{1}
, и так далее.Вы можете
apply
а потомdrop
конкретный тайник тоже:git stash apply stash@{2}
, и так далее. Отбрасывая определенный тайник, перенумеровывает только номера с более высокими номерами. Опять же, тот, без номера тожеstash@{0}
,Если вы накапливаете много тайников, это может стать довольно грязным (был тайник, который я хотел
stash@{7}
или это былоstash@{4}
? Подожди, я просто толкнул другого, теперь им по 8 и 5?). Я лично предпочитаю перенести эти изменения в новую ветку, потому что у ветвей есть имена, иcleanup-attempt-in-December
значит намного больше для меня, чемstash@{12}
, (Thegit stash
команда принимает необязательное сообщение сохранения, и они могут помочь, но каким-то образом все мои тайники просто называютсяWIP on branch
.)(Дополнительно) Вы использовали
git stash save -p
или осторожноgit add
и / илиgit rm
конкретные биты вашего кода перед запускомgit stash save
, У вас была одна версия в области сохраненного индекса / промежуточной области, а другая (другая) версия в рабочем дереве. Вы хотите сохранить все это. Так что теперь вы используетеgit stash apply --index
, и это иногда не удается с:Conflicts in index. Try without --index.
Вы используете
git stash save --keep-index
для того, чтобы проверить "что будет совершено". Этот выходит за рамки этого ответа; см. этот другой ответ Stackru вместо этого.
В сложных случаях я рекомендую сначала начать с "чистого" рабочего каталога, зафиксировав любые изменения, которые у вас есть сейчас (в новой ветке, если хотите). Таким образом, "где-то", к которому вы их применяете, больше ничего не имеет, и вы просто попробуете спрятанные изменения:
git status # see if there's anything you need to commit
# uh oh, there is - let's 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's 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
Главное, что нужно помнить, это то, что "stash" - это коммит, это просто "смешной / странный" коммит, который не "на ветке". 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 stash@{1} # and mix in next stash stack entry too
Вы можете выбрать "применить" порядок здесь, выбирая определенные тайники для применения в определенной последовательности. Однако обратите внимание, что каждый раз, когда вы в основном выполняете "git merge", и, как предупреждает документация по слиянию:
Запуск git merge с нетривиальными незафиксированными изменениями не рекомендуется: хотя это возможно, он может оставить вас в состоянии, от которого трудно отказаться в случае конфликта.
Если вы начинаете с чистого каталога и просто делаете несколько git apply
операции, легко отступить: использовать git reset --hard
чтобы вернуться в чистое состояние, и изменить свой apply
операции. (Вот почему я рекомендую начинать сначала с чистого рабочего каталога, для этих сложных случаев.)
Как насчет самого худшего возможного случая?
Допустим, вы делаете много нового Git Stuff, у вас есть тайник, и вы хотите git stash apply --index
, но больше нельзя применить сохраненный тайник с --index
потому что ветка слишком сильно разошлась со времени, когда вы ее сохранили.
Это то, что git stash branch
для.
Если ты:
- проверьте точный коммит, на котором вы были, когда делали оригинал
stash
, затем - создать новую ветку и, наконец,
git stash apply --index
попытка воссоздать изменения определенно сработает. Это то, что git stash branch newbranch
делает. (И тогда он сбрасывает тайник, так как он был успешно применен.)
Несколько заключительных слов о --index
(какого черта это?)
Что за --index
делает это легко объяснить, но немного сложнее внутри:
- Когда у вас есть изменения, вы должны
git add
(или "этап") их доcommit
ING. - Таким образом, когда вы бежали
git stash
, вы могли редактировать оба файлаfoo
а такжеzorg
, но только поставил один из тех. - Поэтому, когда вы просите вернуть тайник, было бы неплохо, если бы
git add
сadd
Эд вещи и неgit add
не добавленные вещи. Это если выadd
изданиеfoo
но нетzorg
назад, прежде чем вы сделалиstash
было бы неплохо иметь точно такую же настройку. То, что было поставлено, должно быть снова поставлено; то, что было изменено, но не организовано, должно быть снова изменено, но не организовано.
--index
флаг для apply
пытается настроить вещи таким образом. Если ваше дерево работы чистое, это обычно просто работает. Если на вашем рабочем дереве уже есть материал add
Эд, однако, вы можете увидеть, как могут быть некоторые проблемы здесь. Если вы пропустите --index
, apply
операция не пытается сохранить всю ступенчатую / не ступенчатую настройку. Вместо этого он просто вызывает механизм слияния git, используя коммит рабочего дерева в "шкатулке". Если вы не заботитесь о сохранении поэтапного / неустановленного, оставляя вне --index
делает это намного проще для git stash apply
делать свое дело.
git stash pop
вернет все на место
как предлагается в комментариях, вы можете использовать git stash branch newbranch
применить тайник к новой ветке, которая аналогична выполнению:
git checkout -b newbranch
git stash pop
Чтобы проверить содержимое вашего тайника: -
git список тайников
применить конкретный номер тайника из списка тайников: -
git stash применить stash@{2}
или для применения только первого тайника: -
git stash pop
Примечание: git stash pop удалит тайник из вашего списка тайников, тогда как git stash apply не будет. Так что используйте их соответственно.
Чтобы сделать это простым, у вас есть два варианта для повторного применения вашего тайника:
git stash pop
- Восстановить обратно в сохраненное состояние, но он удаляет тайник из временного хранилища.git stash apply
- Восстановить обратно в сохраненное состояние и оставить список тайников для возможного последующего использования.
Вы можете прочитать более подробно о git stashes в этой статье.
Вы можете использовать одну команду в git bash
git stash pop
Чтобы просмотреть список спрятанных изменений
git stash list
Чтобы удалить изменения тайника
git stash clear
На Mac это сработало для меня:
git список тайников (посмотреть все ваши тайники)
git stash list
git stash apply (просто номер, который вы хотите из своего списка)
как это:
git stash apply 1
Вы можете спрятать незафиксированные изменения с помощью "git stash", затем оформить заказ в новую ветку с помощью "git checkout -b ", затем применить сохраненные коммиты "git stash apply"
как говорят многие делаютgit stash apply stash@{1}
получит изменения в текущей ветке, я не знаю, почему это не работает для меня.
для меня делаюgit stash apply stashNumber
работает все время.
например, если я хочу получить тайник номер 1, вот как это сделать:git stash apply 1
PS: вы можете использовать вместо .. с той лишь разницей, чтоapply
не удаляет тайник, но делаетpop
удалит stashnumber вы выскакиваете.