Git — это распределённая система управления версиями, которую разработал Линус Торвальдс. На данный момент она является стандартом в разработке ПО благодаря своей эффективности и гибкости.
В процессе разработки программ бывают ситуации, когда необходимо срочно переключиться на другую ветку с помощью команды checkout
и внести изменения, относящиеся к другой задаче. Однако текущие изменения могут быть еще не готовы к коммиту, а терять их не хотелось бы. В таких ситуациях, на помощь приходит команда git stash
. Этот инструмент становится незаменимым, позволяя безопасно сохранить текущие изменения на некоторое время, чтобы затем вернуться к ним, не нарушая целостность репозитория.
Разберем, как использовать git stash
в процессе разработки.
Вспомним наш стандартный процесс при работе с кодовой базой и гитом. Мы что-то сделали (функцию, небольшой модуль), выполнили add
, затем commit
и push
. Замечательно — задача сделана, переходим к следующей.
Но что делать в ситуации, когда меняется контекст и надо срочно переключиться?
Заканчивать писать модуль ещё долго, а выполнить другую задачу надо уже сейчас. Оставлять коммит недоделанным не хочется Тут на помощь и приходит stash
. Что он делает?
Процесс сохранения временных изменений состоит из двух этапов:
stash
(спрятать). На этом этапе все изменения сохраняются в специальном хранилище. Можно указать комментарий, с которым они будут сохранены.pop
или apply
(извлечь). После того как изменения скрыты, можно вернуть их обратно в вашу рабочую директорию.Изменения для скрытия должны отслеживаться внутри системы контроля версий. Добавлять файлы в список отслеживаемых можно с помощью команды:
git add .
Используется команда:
git stash
Ответ:
Saved working directory and index state WIP on master: 099797d start
По умолчанию в названии стэша содержится аббревиатура «WIP» (Work In Progress) и название ветки. Если нужно указать комментарий, можно выполнить команды git stash push
или save
:
git stash push -m "<тут комментарий>"
Результат выполнения команды:
Saved working directory and index state On master: <тут комментарий>
Аналогичный результат будет для команды:
git stash save "<тут комментарий>"
Однако эта команда считается устаревшей — подробнее можно посмотреть в документации.
Итак, возвращаемся к своей изначальной задаче. Теперь необходимо вернуть спрятанные изменения. Используем команду:
git stash pop
В ответе нам будет сказано, что изменения применены для текущей рабочей области, и они могут использоваться. А ещё, что все данные удалены из специального временного хранилища.
Если необходимо применить изменения без удаления из стэша — нужно использовать команду:
git stash apply
Общий процесс работы со стэшем можно описать на схеме:
Чтобы увидеть список изменений, которые были скрыты в репозитории, можно вызвать команду:
git stash list
Пример вывода:
stash@{0}: On master: User Story #2010
stash@{1}: WIP on master: 099797d start
Для применения конкретного изменения можно использовать команду pop
с указанием индекса изменения:
git stash pop 'stash@{1}'
Пример вывода:
no changes added to commit (use "git add" and/or "git commit -a")
Dropped stash@{1} (563f9c20ab12525795911fbed0c4ebf4a1298b4e)
Если необходимо отложить изменения в стэш, оставив их в рабочей области гита, можно использовать флаг --keep-index
. В таком случае файлы (добавленные в список отслеживаемых командой add
) останутся.
git stash --keep-index
Ответ:
Saved working directory and index state WIP on master: 099797d start
При этом, если вызвать команду git status
, то изменённые файлы останутся:
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: GitStash/Program.cs
modified: GitStash/SomeModule.cs
Если необходимо добавить файлы, которые ещё не отслеживаются гитом, то можно использовать флаг --include-untracked
:
git stash --include-untracked
Когда мы будем возвращать изменения с помощью pop
, появится сообщение о наличии неотслеживаемых файлов:
...
Untracked files:
(use "git add <file>..." to include in what will be committed)
GitStash/NewClass.cs
…
Иногда может быть удобно разделить незакоммиченные части изменений на отдельные стэши. В этом случае поможет команда:
git stash -p
Для каждого изменения скрытие будет выполнено отдельно, с запросом подтверждения. Вот варианты ответа на это подтверждение:
?
— узнать все вариантыy
— скрыть изменениеn
— не скрывать эту часть измененияq
— скрыть все выбранные части и завершить работуКоманда show
выводит информацию об изменениях в конкретном стэше, например:
git stash show
Пример ответа:
GitStash/Program.cs | 3 ++-
GitStash/SomeModule.cs | 7 +++++-
2 files changed, 8 insertions(+), 2 deletions(-)
Можно также указать индекс конкретного стэша:
git stash show 'stash@{1}'
Пример ответа:
GitStash/SomeModule.cs | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
Чтобы удалить конкретный стэш, можно воспользоваться командой drop
. Без указания конкретного индекса она удалит последний набор сохранённых изменений.
git stash drop
Или:
git stash drop 'stash@{1}'
Ответ:
Dropped stash@{1} (bedb3c2add59a3f203e2367602328dca8b33b6e9)
Чтобы полностью очистить хранилище, где находятся скрытые изменения, можно использовать команду:
git stash clear
Для того, чтобы сразу создавать новую ветку на основе скрытых изменений, существует команда:
git stash branch <название ветки> <индекс стэша>
Или просто:
git stash branch <название ветки>
Например:
git stash branch some-feature stash@{2}
Набор изменений, которые мы скрываем в стэш, — это на самом деле коммиты. Выполнение этой команды создаёт два или три коммита:
stash@{0}
содержит файлы, которые скрываются с помощью этой командыHEAD
в текущей рабочей области гита.--keep-untracked
, будет создан отдельный коммит для untracked-файлов.Что происходит при вызове команды pop
?
В папке .git
существует файл .git/refs/stash
— в нём содержится ссылка на последний коммит для стэша.
cat .\.git\refs\stash
Ответ:
07ea0c456356e883610f43c20d9cb298ff2ebb8a
Рассмотрим основные кейсы использования этого механизма на практике
Команды merge
/ rebase
необходимы при работе с множеством веток. Однако часто возникают конфликты, из-за которых можно потерять важные изменения в текущей рабочей области.
git stash push -m "Резервная копия перед слиянием веток"
Выполните merge
или rebase
.
В процессе выполнения этих команд могут возникнуть конфликты между изменениями в текущей ветке и изменениями в другой ветке. Можно решить конфликты, с помощью средств IDE или же гита.
После успешного завершения этих манипуляций можно вернуть изменения в текущую рабочую область с помощью apply
или pop
.
Механизм Stash также может быть полезен для работы с неотладочными изменениями, такими как временные исправления, комментарии или форматирование кода. Вместо того, чтобы вносить эти изменения в текущий коммит, можно использовать git stash
для их временного сохранения. Это поможет создавать чистые коммиты и улучшать структуру истории изменений в гит.
Ещё одним сценарием для git stash
является эффективная работа с конфигурациями проекта. В зависимости от задачи или среды, в которой вы работаете, может потребоваться изменять конфигурационные файлы, однако сохранять их на постоянной основе может быть нецелесообразным.
Предположим, есть конфигурационный файл, который определяет параметры вашего приложения (например config.json
). Вам необходимо иметь несколько разных версий этого файла для разных сценариев использования (например, локальная разработка, тестирование и production). Можно использовать стэш для сохранения этих конфигураций.
# Сохранение конфигурации для локальной разработки
git stash save "Локальная конфигурация"
# Сохранение конфигурации для тестирования
git stash save "Конфигурация для тестирования"
# Сохранение конфигурации для продуктивного окружения
git stash save "Production-конфигурация"
Когда вам нужно переключиться между разными конфигурациями, просто используйте git stash apply
или git stash pop
, чтобы применить соответствующий стэш:
# Применение конфигурации для тестирования
git stash apply stash@{1}
Сообщения, которые создаются для стэшей по умолчанию обычно не передают сути изменений — это просто аббревиатура WIP
, идентификатор коммита и название ветки:
WIP on master: 099797d start
Используйте команды push
или save
для указания сообщений, например:
git stash save "тестовая конфигурация"
Или:
git stash push -m "начал выполнять issue #11 - добавил контракт для модуля"
При длительной разработке проекта у вас может накопиться большое количество изменений, которые уже неактуальны. Используйте команды list
и show
, чтобы посмотреть изменения, а git stash drop
— чтобы удалить неактуальные стэши. Этот механизм не предназначен для долгосрочного хранения данных или изменений
git stash
может быть использован в сочетании с другими командами, например git stash branch
для создания новых веток или совместно с командами rebase или merge для резервного копирования локальных изменений
В данной статье мы глубоко исследовали команду git stash
и кейсы ее использования. Git Stash — это мощный инструмент, который может значительно облегчить управление изменениями в вашем репозитории и улучшить рабочий процесс. Мы изучили как базовые, так и продвинутые сценарии использования этого инструмента, включая создание, применение, извлечение и управление записями stash
.