W3docs

git stash

Информация о команде git stash: как сохранять изменения, работать с несколькими тайниками и частичным сохранением.

Что делает git stash

Команда git stash откладывает изменения, внесённые в рабочую копию, чтобы вы могли переключиться на другую задачу и вернуться к ним позже. Она решает распространённую проблему: вы находитесь в середине работы и вам нужно переключить ветку, подтянуть обновления или исправить срочную ошибку — но изменения ещё не готовы к коммиту. Вместо того чтобы делать временный коммит, вы прячете изменения в тайник, получаете чистое рабочее дерево, выполняете другую задачу, а затем восстанавливаете свои изменения.

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

тайник

Эта страница охватывает сохранение и восстановление изменений, включая неотслеживаемые и игнорируемые файлы, работу с несколькими тайниками, просмотр и частичное сохранение изменений, создание веток из тайника и очистку. Для ознакомления с понятиями проиндексированных и непроиндексированных изменений см. git add и git status.

Сохранение изменений в тайник

Команда git stash принимает все незакоммиченные проиндексированные и непроиндексированные изменения в отслеживаемых файлах, сохраняет их для дальнейшего использования и удаляет из рабочей копии. Сначала выполните git status, чтобы увидеть текущее состояние. Затем запустите git stash, чтобы спрятать изменения:

Проверка состояния рабочего дерева

git status
On branch master
Changes to be committed:
  new file:   style.css
Changes not staged for commit:
  modified:   index.html

Сохранение изменений в тайник

git stash
Saved working directory and index state WIP on master: 5002d47 our new homepage
HEAD is now at 5002d47 our new homepage

Подтверждение того, что рабочее дерево теперь чистое

git status
On branch master
nothing to commit, working tree clean

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

Восстановление сохранённых изменений

Существует две команды для восстановления тайника, и разница между ними важна:

  • git stash pop применяет последний тайник к рабочей копии и удаляет его из списка тайников.
  • git stash apply применяет изменения, но оставляет их в списке тайников — это удобно, когда нужно применить один и тот же тайник к нескольким веткам.

Применить последний тайник и удалить его

git stash pop
On 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 list
stash@{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 -p
diff --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 -p
diff --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 clear
Внимание

git 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.

Практика

Практика
Каковы возможности и функции команды 'git stash'?
Каковы возможности и функции команды 'git stash'?
Was this page helpful?