Простой ответ на простой вопрос 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}
. (Команда git 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
для того, чтобы проверить «что будет совершено». Этот выходит за рамки этого ответа; см. этот другой ответ StackOverflow вместо этого.
В сложных случаях я рекомендую сначала начать с «чистого» рабочего каталога, зафиксировав любые изменения, которые у вас есть сейчас (в новой ветке, если хотите). Таким образом, «где-то», к которому вы их применяете, больше ничего не имеет, и вы просто попробуете спрятанные изменения:
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
.
- Таким образом, когда вы бежали
git stash
, вы могли редактировать оба файла foo
и zorg
, но только поставить один из них.
- Так что, когда вы просите , чтобы получить копить обратно, было бы хорошо , если это
git add
ВЛЯЕТСЯ add
ред вещи и вовсе не git add
в не-добавлены вещи. То есть, если вы add
редактировали, foo
но не zorg
вернулись до того, как сделали это stash
, было бы неплохо иметь точно такую же настройку. То, что было поставлено, должно быть снова поставлено; то, что было изменено, но не организовано, должно быть снова изменено, но не организовано.
--index
Флаг apply
пытается установить вещи таким образом. Если ваше дерево работы чистое, это обычно просто работает. Если add
, однако, в вашем рабочем дереве уже есть материал ed, вы можете увидеть, что здесь могут быть некоторые проблемы. Если вы пропустите --index
, apply
операция не будет пытаться сохранить всю ступенчатую / не постановочную установку. Вместо этого он просто вызывает механизм слияния git, используя коммит рабочего дерева в «шкатулке» . Если вы не заботитесь о сохранении поэтапного / неустановленного сценария, упускать --index
его намного проще git stash apply
.