Давайте дружить в Телеграме: рассказываем про новые фичи, общаемся в комментах, прислушиваемся к вашим идеям Подписаться

Лучшие практики по использованию команды git stash

Дмитрий Бахтенков
Дмитрий Бахтенков
Технический писатель
19 октября 2023 г.
644
9 минут чтения
Средний рейтинг статьи: 5

Git — это распределённая система управления версиями, которую разработал Линус Торвальдс. На данный момент она является стандартом в разработке ПО благодаря своей эффективности и гибкости.

В процессе разработки программ бывают ситуации, когда необходимо срочно переключиться на другую ветку с помощью команды checkout и внести изменения, относящиеся к другой задаче. Однако текущие изменения могут быть еще не готовы к коммиту, а терять их не хотелось бы. В таких ситуациях, на помощь приходит команда git stash. Этот инструмент становится незаменимым, позволяя безопасно сохранить текущие изменения на некоторое время, чтобы затем вернуться к ним, не нарушая целостность репозитория.

Разберем, как использовать git stash в процессе разработки.

Основы

Вспомним наш стандартный процесс при работе с кодовой базой и гитом. Мы что-то сделали (функцию, небольшой модуль), выполнили add, затем commit и push. Замечательно — задача сделана, переходим к следующей.

Image4

Но что делать в ситуации, когда меняется контекст и надо срочно переключиться?

Image2

Заканчивать писать модуль ещё долго, а выполнить другую задачу надо уже сейчас. Оставлять коммит недоделанным не хочется Тут на помощь и приходит stash. Что он делает?

Процесс сохранения временных изменений состоит из двух этапов:

  1. stash (спрятать). На этом этапе все изменения сохраняются в специальном хранилище. Можно указать комментарий, с которым они будут сохранены.
  2. 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

В ответе нам будет сказано, что изменения применены для текущей рабочей области, и они могут использоваться. А ещё, что все данные удалены из специального временного хранилища.

Image1

Если необходимо применить изменения без удаления из стэша — нужно использовать команду:

git stash apply

Общий процесс работы со стэшем можно описать на схеме:

Image3

Дополнительные команды и параметры

Список всех стэшей

Чтобы увидеть список изменений, которые были скрыты в репозитории, можно вызвать команду:

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}

Принцип работы

Набор изменений, которые мы скрываем в стэш, — это на самом деле коммиты. Выполнение этой команды создаёт два или три коммита:

  1. Сам коммит stash@{0} содержит файлы, которые скрываются с помощью этой команды
  2. Родительский коммит — коммит HEAD в текущей рабочей области гита.
  3. Если мы выполняем команду с флагом --keep-untracked, будет создан отдельный коммит для untracked-файлов.

Что происходит при вызове команды pop?

  1. Скрытые изменения возвращаются в рабочую копию репозитория и индексируются в гит.
  2. Другие стэши сдвигаются.
  3. Извлечённые коммиты будут удалены.

В папке .git существует файл .git/refs/stash — в нём содержится ссылка на последний коммит для стэша.

cat .\.git\refs\stash

Ответ:

07ea0c456356e883610f43c20d9cb298ff2ebb8a

Когда использовать?

Рассмотрим основные кейсы использования этого механизма на практике

Резервное копирование изменений перед merge или rebase

Команды merge / rebase необходимы при работе с множеством веток. Однако часто возникают конфликты, из-за которых можно потерять важные изменения в текущей рабочей области.

  1. Перед выполнением слияния убедитесь, что текущая ветка в актуальном состоянии, то есть не содержит несохранённых изменений. Если у вас есть несохранённые изменения, которые стоит сохранить перед слиянием, — выполните команду:
git stash push -m "Резервная копия перед слиянием веток"
  1. Выполнение слияния.

Выполните merge или rebase.

  1. Работа с конфликтами.

В процессе выполнения этих команд могут возникнуть конфликты между изменениями в текущей ветке и изменениями в другой ветке. Можно решить конфликты, с помощью средств IDE или же гита. 

  1. Восстановление изменений.

После успешного завершения этих манипуляций можно вернуть изменения в текущую рабочую область с помощью apply или pop.

Неотладочные изменения

Механизм Stash также может быть полезен для работы с неотладочными изменениями, такими как временные исправления, комментарии или форматирование кода. Вместо того, чтобы вносить эти изменения в текущий коммит, можно использовать git stash для их временного сохранения. Это поможет создавать чистые коммиты и улучшать структуру истории изменений в гит.

Эффективная работа с конфигурациями проекта

Ещё одним сценарием для git stash является эффективная работа с конфигурациями проекта. В зависимости от задачи или среды, в которой вы работаете, может потребоваться изменять конфигурационные файлы, однако сохранять их на постоянной основе может быть нецелесообразным.

  1. Сохранение разных конфигураций

Предположим, есть конфигурационный файл, который определяет параметры вашего приложения (например config.json). Вам необходимо иметь несколько разных версий этого файла для разных сценариев использования (например, локальная разработка, тестирование и production). Можно использовать стэш для сохранения этих конфигураций.

# Сохранение конфигурации для локальной разработки
git stash save "Локальная конфигурация"

# Сохранение конфигурации для тестирования
git stash save "Конфигурация для тестирования"

# Сохранение конфигурации для продуктивного окружения
git stash save "Production-конфигурация"
  1. Применение конфигурации по необходимости

Когда вам нужно переключиться между разными конфигурациями, просто используйте 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.

Зарегистрируйтесь и начните пользоваться
сервисами Timeweb Cloud прямо сейчас

15 лет опыта
Сосредоточьтесь на своей работе: об остальном позаботимся мы
165 000 клиентов
Нам доверяют частные лица и компании, от небольших фирм до корпораций
Поддержка 24/7
100+ специалистов поддержки, готовых помочь в чате, тикете и по телефону