git stash
Информация о команде git stash: как сохранять изменения, работать с несколькими тайниками и частичным сохранением.
Что делает git stash
Команда git stash откладывает изменения, внесённые в рабочую копию, чтобы вы могли переключиться на другую задачу и вернуться к ним позже. Она решает распространённую проблему: вы находитесь в середине работы и вам нужно переключить ветку, подтянуть обновления или исправить срочную ошибку — но изменения ещё не готовы к коммиту. Вместо того чтобы делать временный коммит, вы прячете изменения в тайник, получаете чистое рабочее дерево, выполняете другую задачу, а затем восстанавливаете свои изменения.
Тайник хранится как специальный объект, похожий на коммит, в стеке по принципу «последним пришёл — первым ушёл» (LIFO). Каждая запись содержит снимок изменённых отслеживаемых файлов, и по умолчанию Git оставляет рабочий каталог чистым после создания тайника.

Эта страница охватывает сохранение и восстановление изменений, включая неотслеживаемые и игнорируемые файлы, работу с несколькими тайниками, просмотр и частичное сохранение изменений, создание веток из тайника и очистку. Для ознакомления с понятиями проиндексированных и непроиндексированных изменений см. git add и git status.
Сохранение изменений в тайник
Команда git stash принимает все незакоммиченные проиндексированные и непроиндексированные изменения в отслеживаемых файлах, сохраняет их для дальнейшего использования и удаляет из рабочей копии. Сначала выполните git status, чтобы увидеть текущее состояние. Затем запустите git stash, чтобы спрятать изменения:
Проверка состояния рабочего дерева
git statusOn branch master
Changes to be committed:
new file: style.css
Changes not staged for commit:
modified: index.htmlСохранение изменений в тайник
git stashSaved working directory and index state WIP on master: 5002d47 our new homepage
HEAD is now at 5002d47 our new homepageПодтверждение того, что рабочее дерево теперь чистое
git statusOn branch master
nothing to commit, working tree cleanВаши изменения надёжно сохранены, а рабочий каталог соответствует последнему коммиту — теперь вы можете свободно переключать ветки или подтягивать обновления.
Восстановление сохранённых изменений
Существует две команды для восстановления тайника, и разница между ними важна:
git stash popприменяет последний тайник к рабочей копии и удаляет его из списка тайников.git stash applyприменяет изменения, но оставляет их в списке тайников — это удобно, когда нужно применить один и тот же тайник к нескольким веткам.
Применить последний тайник и удалить его
git stash popOn branch master
Changes to be committed:
new file: style.css
Changes not staged for commit:
modified: index.html
Dropped refs/stash@{0} (32b3aa1d185dfe6d57b3c3cc3b32cbf3e380cc6a)Строка Dropped refs/stash@{0} подтверждает, что запись была удалена после успешного применения.
Если при применении тайника возникают конфликты слияния (из-за того, что базовые файлы были изменены), git stash pop не удалит тайник — он оставит маркеры конфликтов для разрешения и сохранит запись, чтобы вы не потеряли работу. Разрешите конфликты, затем удалите тайник вручную с помощью git stash drop.
Сохранение неотслеживаемых и игнорируемых файлов
По умолчанию git stash сохраняет только те изменения, которые Git уже отслеживает: проиндексированные изменения и модификации отслеживаемых файлов. Новые файлы, которые ни разу не были проиндексированы, а также игнорируемые файлы не попадут в тайник. Чтобы включить неотслеживаемые файлы, используйте опцию -u (или --include-untracked):
Включить неотслеживаемые файлы
git stash -uЧтобы также сохранить игнорируемые файлы, используйте опцию -a (или --all):
Включить неотслеживаемые и игнорируемые файлы
git stash -aФайлы, соответствующие правилам .gitignore, сохраняются в тайник только при передаче -a. Используйте эту опцию с осторожностью — она может захватить артефакты сборки и локальные конфигурации, которые вы, вероятно, не хотели перемещать.
Сохранение проиндексированных изменений с --keep-index
Когда нужно протестировать только проиндексированные изменения в изоляции, git stash --keep-index сохраняет всё в тайник, но оставляет содержимое индекса в рабочем дереве:
Сохранить в тайник всё, кроме проиндексированных изменений
git stash --keep-indexЭто удобно перед коммитом: спрячьте непроиндексированную работу в тайник, запустите тесты именно для того, что собираетесь закоммитить, затем выполните git stash pop, чтобы вернуть остальное.
Несколько тайников
Вы можете выполнять git stash несколько раз, создавая несколько тайников, а затем запустить git stash list для их просмотра. По умолчанию каждый тайник обозначается как «WIP» — работа в процессе — вместе с именем ветки и коммитом, на котором он был создан. Самый последний тайник — stash@{0}; у более старых индекс выше.
Список тайников
git stash liststash@{0}: WIP on master: 5002d47 our new homepage
stash@{1}: WIP on master: 049d078 add navigation
stash@{2}: WIP on master: 38e3b29 initial layoutХорошей практикой является добавление описательного сообщения вместо метки «WIP» по умолчанию, чтобы позже различать тайники:
Сохранить тайник с сообщением
git stash push -m "wip: experimental dark theme"По умолчанию git stash pop применяет последний тайник stash@{0}. Вы можете указать конкретный тайник, передав его ссылку в команду pop или apply:
Применить конкретный тайник
git stash pop stash@{2}On branch master
Changes to be committed:
new file: style.css
Changes not staged for commit:
modified: index.html
Dropped refs/stash@{2} (32b3aa1d185dfe6d57b3c3cc3b32cbf3e380cc6a)Просмотр различий тайника
Используйте git stash show для просмотра сводки файлов, изменённых в тайнике:
Сводка тайника
git stash show index.html | 1 +
style.css | 3 +++
2 files changed, 4 insertions(+)По умолчанию git stash show выводит информацию о последнем тайнике. Передайте ссылку вида git stash show stash@{1}, чтобы просмотреть более старый тайник. Добавьте опцию -p или --patch, чтобы увидеть полный diff:
Полный diff тайника
git stash show -pdiff --git a/style.css b/style.css
new file mode 100644
index 0000000..d92368b
--- /dev/null
+++ b/style.css
@@ -0,0 +1,3 @@
+* {
+ text-decoration: blink;
+}
diff --git a/index.html b/index.html
index 9daeafb..ebdcbd2 100644
--- a/index.html
+++ b/index.html
@@ -1 +1,2 @@
+<link rel="stylesheet" href="style.css"/>Частичное сохранение в тайник
Git позволяет выбрать, что именно сохранять: отдельный файл, группу файлов или отдельные изменения внутри файлов. Команда git stash -p (или --patch) перебирает каждый блок изменений — непрерывный фрагмент изменений — в рабочей копии и спрашивает, нужно ли его сохранить:
Интерактивное сохранение выбранных блоков
git stash -pdiff --git a/style.css b/style.css
new file mode 100644
index 0000000..d92368b
--- /dev/null
+++ b/style.css
@@ -0,0 +1,3 @@
+* {
+ text-decoration: blink;
+}
Stash this hunk [y,n,q,a,d,/,e,?]? y
diff --git a/index.html b/index.html
index 9daeafb..ebdcbd2 100644
--- a/index.html
+++ b/index.html
@@ -1 +1,2 @@
+<link rel="stylesheet" href="style.css"/>
Stash this hunk [y,n,q,a,d,/,e,?]? nКоманды для блоков изменений
| Команда | Описание |
|---|---|
| / | Поиск блока по регулярному выражению. |
| ? | Вывести справку. |
| n | Не сохранять блок. |
| a | Сохранить этот блок и все последующие блоки в файле. |
| d | Не сохранять этот блок и все последующие блоки в файле. |
| e | Вручную отредактировать текущий блок. |
| q | Выйти (выбранные блоки будут сохранены). |
| s | Разделить блок на меньшие блоки. |
| y | Сохранить блок. |
Создание ветки из тайника
Иногда коммит, на котором был создан тайник, ушёл так далеко вперёд, что применение тайника приведёт к конфликтам. Команда git stash branch решает эту проблему, создавая новую ветку из коммита, на котором тайник был первоначально создан, применяя тайник к ней и удаляя его при успешном выполнении:
Создать ветку из тайника
git stash branch add-stylesheet stash@{1}Switched to a new branch 'add-stylesheet'
On branch add-stylesheet
Changes to be committed:
new file: style.css
Changes not staged for commit:
modified: index.html
Dropped refs/stash@{1} (32b3aa1d185dfe6d57b3c3cc3b32cbf3e380cc6a)Очистка тайников
Тайники не удаляются автоматически, поэтому список может разрастаться со временем. Удалите отдельный тайник с помощью git stash drop:
Удалить один тайник
git stash drop stash@{1}Dropped stash@{1} (17e2697fd8251df6163117cb3d58c1f62a5e7cdb)Чтобы удалить все тайники сразу, используйте git stash clear:
Удалить все тайники
git stash cleargit stash clear и git stash drop удаляют сохранённые изменения безвозвратно — они не входят в состав ни одной ветки, поэтому обычный git log их не покажет. Если вы случайно удалили тайник, возможно, объект ещё можно восстановить через git reflog и git stash apply <commit-hash> до того, как сборщик мусора его удалит.
Краткий справочник команд
| Команда | Что делает |
|---|---|
git stash | Сохраняет проиндексированные и непроиндексированные изменения отслеживаемых файлов. |
git stash -u | Также сохраняет неотслеживаемые файлы. |
git stash -a | Также сохраняет неотслеживаемые и игнорируемые файлы. |
git stash --keep-index | Сохраняет в тайник, но оставляет проиндексированные изменения в рабочем дереве. |
git stash push -m "message" | Сохраняет в тайник с описательной меткой. |
git stash list | Выводит список всех тайников (новейший — stash@{0}). |
git stash show -p | Показывает полный diff тайника. |
git stash pop | Применяет последний тайник и удаляет его. |
git stash apply | Применяет последний тайник и сохраняет его. |
git stash branch <name> | Создаёт ветку из тайника и применяет его. |
git stash drop / clear | Удаляет один / все тайники. |
Для изучения связанных способов перемещения и отмены изменений см. git reset, git restore и git checkout.