Материал подготовлен командой Simple-Server для администраторов VPS и выделенных серверов. Команды и пути проверяйте на тестовой машине перед production.
Кратко о задаче
Вспомним наш стандартный процесс при работе с кодовой базой и гитом. Мы что-то сделали (функцию, небольшой модуль), выполнили add, затем commit и push. Замечательно — задача сделана, переходим к следующей.
Но что делать в ситуации, когда меняется контекст и надо срочно переключиться?
Заканчивать писать модуль ещё долго, а выполнить другую задачу надо уже сейчас. Оставлять коммит недоделанным не хочется Тут на помощь и приходит stash. Что он делает?
Процесс сохранения временных изменений состоит из двух этапов:
stash(спрятать). На этом этапе все изменения сохраняются в специальном хранилище. Можно указать комментарий, с которым они будут сохранены.popилиapply(извлечь). После того как изменения скрыты, можно вернуть их обратно в вашу рабочую директорию.
Изменения для скрытия должны отслеживаться внутри системы контроля версий. Добавлять файлы в список отслеживаемых можно с помощью команды:
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 "<тут комментарий>"Однако эта команда считается устаревшей — подробнее можно посмотреть в документации.
Итак, возвращаемся к своей изначальной задаче. Теперь необходимо вернуть спрятанные изменения. Используем команду:
В ответе нам будет сказано, что изменения применены для текущей рабочей области, и они могут использоваться. А ещё, что все данные удалены из специального временного хранилища.
Если необходимо применить изменения без удаления из стэша — нужно использовать команду:
Общий процесс работы со стэшем можно описать на схеме:
Дополнительные команды и параметры
Чтобы увидеть список изменений, которые были скрыты в репозитории, можно вызвать команду:
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) останутся.
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
…Иногда может быть удобно разделить незакоммиченные части изменений на отдельные стэши. В этом случае поможет команда:
Для каждого изменения скрытие будет выполнено отдельно, с запросом подтверждения. Вот варианты ответа на это подтверждение:
?— узнать все вариантыy— скрыть изменениеn— не скрывать эту часть измененияq— скрыть все выбранные части и завершить работу
Просмотр конкретных изменений в стэше
Команда 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 'stash@{1}'
Dropped stash@{1} (bedb3c2add59a3f203e2367602328dca8b33b6e9)Чтобы полностью очистить хранилище, где находятся скрытые изменения, можно использовать команду:
Создание новой ветки из стэша
Для того, чтобы сразу создавать новую ветку на основе скрытых изменений, существует команда:
git stash branch <название ветки> <индекс стэша>
git stash branch <название ветки>
git stash branch some-feature stash@{2}Набор изменений, которые мы скрываем в стэш, — это на самом деле коммиты. Выполнение этой команды создаёт два или три коммита:
- Сам коммит
stash@{0}содержит файлы, которые скрываются с помощью этой команды - Родительский коммит — коммит
HEADв текущей рабочей области гита. - Если мы выполняем команду с флагом
--keep-untracked, будет создан отдельный коммит для untracked-файлов.
Что происходит при вызове команды pop?
- Скрытые изменения возвращаются в рабочую копию репозитория и индексируются в гит.
- Другие стэши сдвигаются.
- Извлечённые коммиты будут удалены.
В папке .git существует файл .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 для резервного копирования локальных изменений
Нужен сервер для практики? Закажите VPS на Simple-Server — root-доступ, NVMe, DDoS-защита и поддержка 24/7.