git stash
Команда git stash
позволяет на время «сдать в архив» (или отложить) изменения, сделанные в рабочей копии, чтобы вы могли применить их позже. Откладывание изменений полезно, если вам необходимо переключить контекст и вы пока не готовы к созданию коммита.
- git stash
- Откладывание кода
- Применение отложенных изменений
- Откладывание неотслеживаемых или игнорируемых файлов
- Управление несколькими наборами отложенных изменений
- Просмотр различий между наборами отложенных изменений
- Частичное откладывание изменений
- Создание ветки из отложенных изменений
- Удаление отложенных изменений
- Принцип работы команды git stash
Откладывание кода
Команда git stash
сохраняет неподтвержденные изменения (индексированные и неиндексированные) в отдельном хранилище, чтобы вы могли вернуться к ним позже. Затем происходит откат до исходной рабочей копии. Например:
$ git status
On branch main
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 main: 5002d47 our new homepage
HEAD is now at 5002d47 our new homepage
$ git status
On branch main
nothing to commit, working tree clean
Связанные материалы
git branch
СМ. РЕШЕНИЕ
Изучите Git с помощью Bitbucket Cloud
Теперь вы можете вносить изменения, создавать новые коммиты, переключаться между ветками и выполнять другие операции Git. По необходимости отложенные изменения можно будет применить позже.
Отложенные изменения сохраняются в локальном репозитории Git и не передаются на сервер при выполнении команды push.
Применение отложенных изменений
Чтобы применить ранее отложенные изменения, воспользуйтесь командой git stash pop
:
$ git status
On branch main
nothing to commit, working tree clean
$ git stash pop
On branch main
Changes to be committed:
new file: style.css
Changes not staged for commit:
modified: index.html
Dropped refs/stash@{0} (32b3aa1d185dfe6d57b3c3cc3b32cbf3e380cc6a)
При извлечении отложенных изменений они удаляются из набора и применяются к рабочей копии.
Вы также можете применить изменения к рабочей копии, не удаляя их из набора отложенных изменений. Для этого воспользуйтесь командой git stash apply
:
$ git stash apply
On branch main
Changes to be committed:
new file: style.css
Changes not staged for commit:
modified: index.html
Это полезно, если вам нужно применить одни и те же отложенные изменения к нескольким веткам.
Теперь вы умеете выполнять основные операции с отложенными изменениями. Однако необходимо помнить о следующей особенности командыgit stash
: по умолчанию Git не создает отложенные изменения для неотслеживаемых или игнорируемых файлов.
Откладывание неотслеживаемых или игнорируемых файлов
По умолчанию команда git stash
создает следующие отложенные изменения:
- изменения, добавленные в раздел проиндексированных файлов (индексированные изменения);
- изменения в файлах, отслеживаемых Git в настоящее время (неиндексированные изменения).
При этом следующие файлы отложены не будут:
- новые файлы в рабочей копии, которые еще не были проиндексированы;
- игнорируемые файлы.
Поэтому если в приведенный выше пример добавить третий файл — неиндексированный (т. е. без выполнения команды git add
), при выполнении команды git stash
этот файл не будет отложен.
$ script.js
$ git status
On branch main
Changes to be committed:
new file: style.css
Changes not staged for commit:
modified: index.html
Untracked files:
script.js
$ git stash
Saved working directory and index state WIP on main: 5002d47 our new homepage
HEAD is now at 5002d47 our new homepage
$ git status
On branch main
Untracked files:
script.js
Запуск git stash
с параметром -u
(или --include-untracked
) позволяет отложить неотслеживаемые файлы:
$ git status
On branch main
Changes to be committed:
new file: style.css
Changes not staged for commit:
modified: index.html
Untracked files:
script.js
$ git stash -u
Saved working directory and index state WIP on main: 5002d47 our new homepage
HEAD is now at 5002d47 our new homepage
$ git status
On branch main
nothing to commit, working tree clean
Можно также отложить изменения, внесенные в игнорируемые файлы. Для этого используйте параметр -a
(или --all
) при запуске команды git stash
.
Управление несколькими наборами отложенных изменений
Вы можете создать несколько наборов отложенных изменений. Команду git stash
можно выполнить несколько раз, после чего можно будет просмотреть список созданных наборов с помощью команды git stash list
. По умолчанию отложенные изменения имеют пометку WIP (незавершенная работа) наверху ветки или коммита, в которых они были отложены. Возможно, со временем вам будет трудно вспомнить содержимое каждого набора:
$ git stash list
stash@{0}: WIP on main: 5002d47 our new homepage
stash@{1}: WIP on main: 5002d47 our new homepage
stash@{2}: WIP on main: 5002d47 our new homepage
Рекомендуем добавлять к отложенным изменениям описание в качестве подсказки. Для этого используется команда git stash save "сообщение"
:
$ git stash save "add style to our site"
Saved working directory and index state On main: add style to our site
HEAD is now at 5002d47 our new homepage
$ git stash list
stash@{0}: On main: add style to our site
stash@{1}: WIP on main: 5002d47 our new homepage
stash@{2}: WIP on main: 5002d47 our new homepage
По умолчанию команда git stash pop
применяет последний набор отложенных изменений: stash@{0}
Если вам нужно применить определенный набор ранее отложенных изменений, укажите его идентификатор в качестве последнего аргумента. Это можно сделать так:
$ git stash pop stash@{2}
Просмотр различий между наборами отложенных изменений
Выполните команду git stash show
, чтобы просмотреть сводные данные по набору отложенных изменений:
$ git stash show
index.html | 1 +
style.css | 3 +++
2 files changed, 4 insertions(+)
Или укажите параметр -p
(или --patch
), чтобы просмотреть разницу между наборами изменений:
$ 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 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 | Описание не откладывать участок кода |
q | Описание выйти (все выбранные участки будут отложены) |
s | Описание разделить участок кода на меньшие части |
y | Описание отложить участок кода |
Специальной команды для прерывания не предусмотрено, но прекратить процесс откладывания можно, нажав CTRL-C
(сигнал SIGINT).
Создание ветки из отложенных изменений
Если изменения в ветке отличаются от отложенных изменений, операции извлечения или применения последних могут привести к конфликтам. Вместо этого вы можете создать новую ветку с помощью команды 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
Если вы просто хотели получить информацию о том, как использовать команду git stash
, то дальше читать необязательно. Однако если вам необходимо узнать о принципах работы Git (и git stash
) — продолжайте чтение!
Наборы отложенных изменений шифруются в репозитории в виде коммитов. Специальная ссылка в .git/refs/stash
указывает на последний созданный набор отложенных изменений, а для ранее созданных наборов изменений используются ссылки из журнала ссылок stash
. Именно поэтому для просмотра наборов отложенных изменений используется ссылка stash@{n}
: при этом вы ссылаетесь на n-ю запись в журнале ссылок stash
. Поскольку набор отложенных изменений представляет собой обычный коммит, его можно просмотреть с помощью команды git log
:
В зависимости от отложенных элементов выполнение команды git stash
создает два или три новых коммита. На приведенной выше схеме создаются следующие коммиты:
stash@{0}
— новый коммит для хранения отслеживаемых файлов, которые находились в рабочей копии при запуске командыgit stash
;- первый родитель
stash@{0}
— существующий коммит, который при запуске командыgit stash
находился в ветке, на которую указывал HEAD; - второй родитель
stash@{0}
— новый коммит, выступавший в роли индекса при запуске командыgit stash
; - третий родитель
stash@{0}
— новый коммит, представляющий неотслеживаемые файлы, которые находились в рабочей копии при запуске командыgit stash
. Третий родитель создается, только если:- рабочая копия действительно содержит неотслеживаемые файлы, и
- вы указали параметр
--include-untracked
или--all
при вызове командыgit stash
.
Ниже показано, как команда git stash
шифрует рабочий каталог и раздел проиндексированных файлов в виде коммитов:
- Перед откладыванием изменений в рабочем каталоге могут находиться изменения отслеживаемых, неотслеживаемых и игнорируемых файлов. Часть этих изменений также может быть проиндексирована в разделе проиндексированных файлов.
- При выполнении команды
git stash
все изменения отслеживаемых файлов шифруются в виде двух новых коммитов в ориентированном ациклическом графе. При этом один коммит используется для неиндексированных изменений, а другой — для индексированных изменений, добавленных в раздел проиндексированных файлов. Для указания на них используется специальная ссылкаrefs/stash
.
- Параметр
--include-untracked
позволяет также зашифровать все изменения неотслеживаемых файлов в виде дополнительного коммита.
- Параметр
--all
позволяет включить изменения игнорируемых файлов в один коммит с изменениями неотслеживаемых файлов.
При выполнении команды git stash pop
изменения из описанных выше коммитов применяются к рабочей копии и разделу проиндексированных файлов, извлеченный коммит удаляется из журнала ссылок на отложенные изменения, и ссылки в журнале сдвигаются. Извлеченные коммиты не удаляются сразу, но помечаются к удалению в будущем при сборе мусора.
Поделитесь этой статьей
Следующая тема
Рекомендуемые статьи
Добавьте эти ресурсы в закладки, чтобы изучить типы команд DevOps или получать регулярные обновления по DevOps в Atlassian.