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 "<тут комментарий>"
Однако эта команда считается устаревшей — подробнее можно посмотреть в документации.
vds
Как вернуть изменения?
Итак, возвращаемся к своей изначальной задаче. Теперь необходимо вернуть спрятанные изменения. Используем команду:
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 для резервного копирования локальных изменений
Размещайте свои проекты на VDS/VPS<br>в Timeweb Cloud
Заключение
В данной статье мы глубоко исследовали команду git stash и кейсы ее использования. Git Stash — это мощный инструмент, который может значительно облегчить управление изменениями в вашем репозитории и улучшить рабочий процесс. Мы изучили как базовые, так и продвинутые сценарии использования этого инструмента, включая создание, применение, извлечение и управление записями stash.
