Лучшие практики по использованию команды git stash
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)
Дополнительные параметры для команды stash
Если необходимо отложить изменения в стэш, оставив их в рабочей области гита, можно использовать флаг --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
Команды 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
— чтобы удалить неактуальные стэши. Этот механизм не предназначен для долгосрочного хранения данных или изменений
Используйте stash вместе с другими командами
git stash
может быть использован в сочетании с другими командами, например git stash branch
для создания новых веток или совместно с командами rebase или merge для резервного копирования локальных изменений
Заключение
В данной статье мы глубоко исследовали команду git stash
и кейсы ее использования. Git Stash — это мощный инструмент, который может значительно облегчить управление изменениями в вашем репозитории и улучшить рабочий процесс. Мы изучили как базовые, так и продвинутые сценарии использования этого инструмента, включая создание, применение, извлечение и управление записями stash
.