git-stash
Название
git-stash — сохранение изменений из грязного рабочего каталога в stash
Краткое описание
git stash list [<log-options>]
git stash show [-u | --include-untracked | --only-untracked] [<diff-options>] [<stash>]
git stash drop [-q | --quiet] [<stash>]
git stash pop [--index] [-q | --quiet] [<stash>]
git stash apply [--index] [-q | --quiet] [--label-ours=<label>] [--label-theirs=<label>] [--label-base=<label>] [<stash>]
git stash branch <branchname> [<stash>]
git stash [push] [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet]
[-u | --include-untracked] [-a | --all] [(-m | --message) <message>]
[--pathspec-from-file=<file> [--pathspec-file-nul]]
[--] [<pathspec>…]
git stash save [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet]
[-u | --include-untracked] [-a | --all] [<message>]
git stash clear
git stash create [<message>]
git stash store [(-m | --message) <message>] [-q | --quiet] <commit>
git stash export (--print | --to-ref <ref>) [<stash>…]
git stash import <commit> Описание
Используйте git stash, если хотите записать текущее состояние рабочего каталога и индекса, но при этом вернуться к чистому рабочему каталогу. Команда сохраняет ваши локальные изменения и приводит рабочий каталог в соответствие с коммитом HEAD.
Сохранённые этой командой изменения можно просмотреть с помощью git stash list, проверить с помощью git stash show и восстановить (возможно, поверх другого коммита) с помощью git stash apply. Вызов git stash без аргументов эквивалентен вызову git stash push. По умолчанию запись stash отображается как «WIP on <branchname> …», но при её создании можно указать в командной строке более информативное сообщение.
Последняя созданная вами запись stash хранится в refs/stash; более старые записи находятся в reflog этой ссылки, и на них можно ссылаться с помощью обычного синтаксиса reflog (например, stash@{0} — это самая новая запись stash, stash@{1} — предыдущая, также допустима запись stash@{2.hours.ago}). На записи stash также можно ссылаться, указав только индекс записи (например, целое число <n> эквивалентно stash@{<n>}).
Команды
-
push[-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [(-m|--message) <message>] [--pathspec-from-file=<file> [--pathspec-file-nul]] [--] [<pathspec>...] -
Сохранить локальные изменения в новой записи
stash entryи отменить их, вернув состояние кHEAD(в рабочем дереве и индексе). Часть<message>необязательна и задаёт описание сохранённого состояния.Чтобы быстро создать снимок, можно опустить «push». В этом режиме элементы pathspec разрешены только после двойного дефиса
--, чтобы опечатка в подкоманде не привела к созданию нежелательной записи stash. -
save[-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [<message>] -
Этот параметр устарел; вместо него следует использовать
git stash push. От команды «stash push» он отличается тем, что не принимает pathspec. Вместо этого все аргументы, не являющиеся параметрами, объединяются в сообщение stash. -
list[<log-options>] -
Вывести список имеющихся записей stash. Для каждой записи
stash entryуказывается её имя (например,stash@{0}— это самая новая запись,stash@{1}— предыдущая и т. д.), имя ветки, активной при создании записи, и краткое описание коммита, на основе которого она создана.stash@{0}: WIP on submit: 6ebd0e2... Update git-stash documentation stash@{1}: On master: 9cc0589... Add git-stashКоманда принимает параметры, применимые к команде
git log, чтобы управлять содержимым и форматом вывода. См. git-log[1]. -
show[-u|--include-untracked|--only-untracked] [<diff-options>] [<stash>] -
Показать изменения, записанные в stash, в виде diff между сохранённым содержимым и коммитом, существовавшим при создании записи stash. По умолчанию команда выводит diffstat, но принимает любой формат, известный команде
git diff(например,gitstashshow-pstash@{1}, чтобы просмотреть предпоследнюю запись в формате патча). Если<diff-option>не указан, поведение по умолчанию определяется переменными конфигурацииstash.showStatиstash.showPatch. Также можно использоватьstash.showIncludeUntracked, чтобы задать, включён ли по умолчанию параметр--include-untracked. -
pop[--index] [-q|--quiet] [<stash>] -
Удалить одну запись stash из списка и применить её поверх текущего состояния рабочего дерева, то есть выполнить обратную операцию по отношению к
gitstashpush. Рабочий каталог должен соответствовать индексу.Применение состояния может завершиться конфликтами; в этом случае запись не удаляется из списка stash. Необходимо разрешить конфликты вручную, а затем вызвать
gitstashdrop. -
apply[--index] [-q|--quiet] [<stash>] -
Аналогично
pop, но состояние не удаляется из списка stash. В отличие отpop, <stash> может быть любым коммитом, похожим на коммит, созданный командамиstashpushилиstashcreate. -
branch<branchname> [<stash>] -
Создать и переключиться на новую ветку с именем
<branchname>, начинающуюся с коммита, на котором изначально была создана запись<stash>, и применить изменения, записанные в<stash>, к новому рабочему дереву и индексу. Если это удаётся и<stash>является ссылкой видаstash@{<revision>}, запись<stash>удаляется.Это полезно, если ветка, в которой была выполнена команда
gitstashpush, достаточно изменилась и командаgitstashapplyзавершается неудачей из-за конфликтов. Поскольку запись stash применяется поверх коммита, на который указывал HEAD в момент выполнения командыgitstash, исходное сохранённое состояние восстанавливается без конфликтов. -
clear -
Удалить все записи stash. Обратите внимание: после этого эти записи могут быть удалены при очистке, и восстановить их может быть невозможно (возможный способ восстановления описан ниже, в разделе
EXAMPLES). -
drop[-q|--quiet] [<stash>] -
Удалить одну запись stash из списка записей stash.
-
create -
Создать запись stash (обычный объект-коммит) и вернуть её имя объекта, не сохраняя его в пространстве имён ссылок. Это предназначено для использования в скриптах. Скорее всего, это не та команда, которая вам нужна; см. описание команды «push» выше.
-
store -
Сохранить указанную запись stash, созданную с помощью
git stash create(висячего коммита слияния), в ссылке stash, обновив reflog stash. Это предназначено для использования в скриптах. Скорее всего, это не та команда, которая вам нужна; см. описание команды «push» выше. -
export(--print|--to-ref<ref> ) [<stash>...] -
Экспортировать указанные записи stash или все записи, если ни одна не указана, в цепочку коммитов, которую можно передать с помощью обычных механизмов fetch и push, а затем импортировать с помощью подкоманды
import. -
import<commit> -
Импортировать указанные записи stash из указанного коммита, который должен быть создан командой
export, и добавить их в список stash. Чтобы заменить существующие записи stash, сначала используйтеclear.
Параметры
-
-a -
--all -
Этот параметр допустим только для команд
pushиsave.Все игнорируемые и неотслеживаемые файлы также сохраняются в stash, а затем удаляются с помощью
gitclean. -
-u -
--include-untracked -
--no-include-untracked -
При использовании с командами
pushиsaveвсе неотслеживаемые файлы также сохраняются в stash, а затем удаляются с помощьюgitclean.При использовании с командой
showнеотслеживаемые файлы из записи stash включаются в diff. -
--only-untracked -
Этот параметр допустим только для команды
show.Включить в diff только неотслеживаемые файлы из записи stash.
-
--index -
Этот параметр допустим только для команд
popиapply.Попытаться восстановить не только изменения рабочего дерева, но и изменения индекса. Однако это может не удаться при наличии конфликтов (которые сохраняются в индексе, поэтому применить изменения в исходном виде уже невозможно).
-
--label-ours=<label> -
--label-theirs=<label> -
--label-base=<label> -
Эти параметры допустимы только для команды
apply.Использовать указанные метки в маркерах конфликтов вместо меток по умолчанию "Updated upstream", "Stashed changes" и "Stash base". Параметр
--label-baseдействует только при merge.conflictStyle=diff3. -
-k -
--keep-index -
--no-keep-index -
Этот параметр допустим только для команд
pushиsave.Все изменения, уже добавленные в индекс, остаются без изменений.
-
-p -
--patch -
Этот параметр допустим только для команд
pushиsave.В интерактивном режиме выбрать фрагменты diff между HEAD и рабочим деревом для сохранения в stash. Запись stash формируется так, чтобы состояние её индекса совпадало с состоянием индекса репозитория, а рабочее дерево содержало только изменения, выбранные в интерактивном режиме. Затем выбранные изменения отменяются в рабочем дереве. О том, как работать в режиме
--patch, см. раздел «Интерактивный режим» в документации git-add[1].Параметр
--patchподразумевает параметр--keep-index. Чтобы отменить это поведение, можно использовать--no-keep-index. -
-U<n> -
--unified=<n> -
Создать diff с
<n>строками контекста. Число строк контекста по умолчанию равноdiff.contextили 3, если переменная конфигурации не задана. (-Uбез <n> принимается без предупреждения как синоним-pиз-за исторической особенности.) -
--inter-hunk-context=<n> -
Показать контекст между фрагментами diff длиной до указанного
<number>строк, объединяя таким образом близко расположенные фрагменты. По умолчанию используется значениеdiff.interHunkContextили 0, если параметр конфигурации не задан. -
-S -
--staged -
Этот параметр допустим только для команд
pushиsave.Сохранить в stash только изменения, добавленные в индекс. Это похоже на обычный вызов
gitcommit, за исключением того, что состояние фиксируется в stash, а не в текущей ветке.Параметр
--patchимеет приоритет над этим параметром. -
--pathspec-from-file=<file> -
Этот параметр допустим только для команды
push.Pathspec передаётся в
<file>, а не как аргументы командной строки. Если<file>имеет значение-, используется стандартный ввод. Элементы pathspec разделяются LF или CR/LF. Элементы pathspec можно заключать в кавычки, как описано для переменной конфигурацииcore.quotePath(см. git-config[1]). См. также--pathspec-file-nulи глобальный параметр--literal-pathspecs. -
--pathspec-file-nul -
Этот параметр допустим только для команды
push.Имеет смысл только вместе с
--pathspec-from-file. Элементы pathspec разделяются нулевым символом; все остальные символы воспринимаются буквально (включая символы новой строки и кавычки). -
-q -
--quiet -
Этот параметр допустим только для команд
apply,drop,pop,push,saveиstore.Тихий режим: не выводить сообщения.
-
--print -
Этот параметр допустим только для команды
export.Создать цепочку коммитов, представляющих экспортированные записи stash, не сохраняя её в пространстве имён ссылок, и вывести идентификатор объекта в стандартный вывод. Предназначено для использования в скриптах.
-
--to-ref -
Этот параметр допустим только для команды
export.Создать цепочку коммитов, представляющих экспортированные записи stash, и сохранить её в указанную ссылку.
-
-- -
Этот параметр допустим только для команды
push.Отделяет pathspec от параметров, чтобы устранить неоднозначность.
- <pathspec>...
-
Этот параметр допустим только для команды
push.Новая запись stash сохраняет изменённые состояния только для файлов, соответствующих pathspec. Записи индекса и файлы рабочего дерева также возвращаются к состоянию в HEAD только для этих файлов; остальные файлы остаются без изменений.
Подробнее см. статью
pathspecв gitglossary[7]. - <stash>
-
Этот параметр допустим только для команд
apply,branch,drop,pop,showиexport.Ссылка вида
stash@{<revision>}. Если<stash>не указан, предполагается последняя запись stash (то естьstash@{0}).
Обсуждение
Запись stash представлена коммитом, дерево которого фиксирует состояние рабочего каталога, а его первый родитель — это коммит, на который указывал HEAD при создании записи. Дерево второго родителя фиксирует состояние индекса на момент создания записи; этот родитель является дочерним коммитом HEAD. Граф родословной выглядит так:
.----W
/ /
-----H----I где H — коммит HEAD, I — коммит, фиксирующий состояние индекса, а W — коммит, фиксирующий состояние рабочего дерева.
Примеры
- Выполнение pull в грязном дереве
-
Когда вы заняты какой-либо работой, вы узнаёте, что появились изменения в вышестоящем репозитории, которые могут иметь отношение к вашей работе. Если локальные изменения не конфликтуют с изменениями в вышестоящем репозитории, можно просто выполнить
gitpullи продолжить работу.Однако иногда локальные изменения конфликтуют с изменениями в вышестоящем репозитории, и команда
gitpullотказывается перезаписывать ваши изменения. В таком случае можно временно сохранить изменения в stash, выполнить pull, а затем восстановить их, например так:$ git pull ... file foobar not up to date, cannot merge. $ git stash $ git pull $ git stash pop
- Прерванный рабочий процесс
-
Вы заняты работой, когда приходит начальник и требует немедленно что-нибудь исправить. Обычно для сохранения изменений вы создаёте коммит во временной ветке, а затем возвращаетесь в исходную ветку, чтобы выполнить срочное исправление, например так:
# ... hack hack hack ... $ git switch -c my_wip $ git commit -a -m "WIP" $ git switch master $ edit emergency fix $ git commit -a -m "Fix in a hurry" $ git switch my_wip $ git reset --soft HEAD^ # ... continue hacking ...
Можно упростить описанные выше действия с помощью
git stash, например так:# ... hack hack hack ... $ git stash $ edit emergency fix $ git commit -a -m "Fix in a hurry" $ git stash pop # ... continue hacking ...
- Проверка частичных коммитов
-
Можно использовать
gitstashpush--keep-index, если вы хотите разбить изменения в рабочем дереве на два или более коммита и проверить каждое изменение перед фиксацией:# ... hack hack hack ... $ git add --patch foo # add just first part to the index $ git stash push --keep-index # save all other changes to the stash $ edit/build/test first part $ git commit -m 'First part' # commit fully tested change $ git stash pop # prepare to work on all other changes # ... repeat above five steps until one commit remains ... $ edit/build/test remaining parts $ git commit foo -m 'Remaining parts'
-
Если вы заняты масштабными изменениями и обнаружили несвязанную проблему, о которой не хотите забыть, можно внести соответствующие изменения, добавить их в индекс и выполнить
gitstashpush--staged, чтобы сохранить их в stash для дальнейшего использования. Это похоже на фиксацию добавленных в индекс изменений, только коммит окажется в stash, а не в текущей ветке.# ... hack hack hack ... $ git add --patch foo # add unrelated changes to the index $ git stash push --staged # save these changes to the stash # ... hack hack hack, finish current changes ... $ git commit -m 'Massive' # commit fully tested changes $ git switch fixup-branch # switch to another branch $ git stash pop # to finish work on the saved changes
- Восстановление записей stash, ошибочно очищенных или удалённых
-
Если вы по ошибке удалите записи stash или очистите список, восстановить их с помощью обычных защитных механизмов не удастся. Однако можно попробовать выполнить следующую команду, чтобы получить список записей stash, которые всё ещё есть в репозитории, но больше недоступны:
git fsck --unreachable | grep commit | cut -d\ -f3 | xargs git log --merges --no-walk --grep=WIP
Конфигурация
Всё содержимое этой секции ниже данной строки выборочно включено из документации git-config[1]. Оно совпадает с содержимым соответствующего раздела:
-
stash.index -
Если для этого параметра задано значение true, команды
gitstashapplyиgitstashpopведут себя так, как если бы был указан параметр--index. Значение по умолчанию — false. -
stash.showIncludeUntracked -
Если для этого параметра задано значение true, команда
gitstashshowпоказывает неотслеживаемые файлы записи stash. Значение по умолчанию — false. -
stash.showPatch -
Если для этого параметра задано значение true, команда
gitstashshowбез параметров показывает запись stash в формате патча. Значение по умолчанию — false. -
stash.showStat -
Если для этого параметра задано значение true, команда
gitstashshowбез параметров показывает diffstat записи stash. Значение по умолчанию — true.
См. также
stash
© 2005–2026 Linus Torvalds and others
Licensed under the GNU General Public License version 2.
https://git-scm.com/docs/git-stash