Временное сохранение изменений - git stash

17 декабря 2025
Автор

Олег Марков

Введение

При работе с Git почти у каждого разработчика возникает ситуация, когда нужно срочно переключиться на другую задачу, но текущие изменения еще не готовы для коммита. Коммитить «сырую» работу не хочется, а выбрасывать изменения тем более.

Здесь на помощь приходит команда git stash. Она позволяет временно убрать изменения «в сторону», очистить рабочую директорию и вернуться к ним позже. Смотрите, я покажу вам, как это работает, как устроен стек сохранений и какие возможности кроме простого сохранения и восстановления изменений вы получаете.

В этой статье мы разберем:

  • что такое stash и как он хранится в репозитории;
  • базовые команды git stash и их различия;
  • как сохранять только часть изменений;
  • как работать с несколькими stash-записями;
  • как сравнивать, переименовывать и переносить stashes между ветками;
  • типичные ошибки и как их избежать.

Теперь давайте по шагам разберем все возможности git stash.

Что такое git stash и как он работает

Концепция временного сохранения

Git stash — это механизм временного сохранения незакоммиченных изменений. Можно представить его как отдельный стек «черновиков», в который вы складываете свои правки, чтобы освободить рабочую директорию.

Важно понимать несколько моментов:

  • stash сохраняет изменения относительно последнего коммита в текущей ветке;
  • сохранения организованы в виде стека — последняя запись сверху;
  • stash не привязан жестко к ветке — его можно применять в другой ветке (но нужно следить за конфликтами);
  • каждое сохранение — это по сути пара (или три) служебных коммитов в специальной области refs/stash.

Какие файлы попадают в git stash

По умолчанию git stash:

  • сохраняет:
    • изменения в уже отслеживаемых файлах (modified);
    • удаленные отслеживаемые файлы (deleted);
  • не затрагивает:
    • неотслеживаемые файлы (untracked, ?? в git status);
    • игнорируемые файлы (ignored, указанные в .gitignore).

Но эти ограничения можно менять флагами, о которых мы поговорим далее.

Давайте перейдем к базовым командам.

Базовое использование git stash

Классический сценарий применения

Представьте, что вы работаете над фичей в ветке feature/login, правите несколько файлов, но тут приходит запрос: «Срочно поправь баг в main». Изменения еще не готовы к коммиту.

Пошаговый сценарий:

  1. Сохранить текущие изменения во временное хранилище.
  2. Очистить рабочую директорию до состояния последнего коммита.
  3. Переключиться на другую ветку, сделать правку, закоммитить.
  4. Вернуться на исходную ветку и восстановить свои изменения.

Пример:

# Проверяем текущий статус
git status

# Временно убираем изменения
git stash

# Переключаемся на основную ветку
git checkout main

# Фиксим баг, коммитим и пушим
# ...

# Возвращаемся к своей ветке
git checkout feature/login

# Достаем сохраненные изменения
git stash pop

Комментарии к примеру:

  • git stash создаст новую запись в стеке и очистит рабочую директорию.
  • git stash pop:
    • применит последние сохраненные изменения;
    • удалит соответствующую запись из стека.

git stash save и git stash (различия)

Раньше основная форма выглядела так:

git stash save "Сообщение"

Сейчас рекомендуемая и более современная форма — просто:

git stash push -m "Сообщение"   # с явным указанием subcommand

или даже:

git stash                       # сокращение для git stash push

Разница:

  • git stash без аргументов = git stash push;
  • git stash save считается устаревающим стилем и повторяет поведение git stash push.

Чтобы не путаться, лучше запомнить: используете git stash push и git stash pop/apply.

Различия между git stash pop и git stash apply

Это один из частых вопросов, давайте разберемся.

git stash apply

  • применяет изменения из stash к рабочей директории;
  • не удаляет запись из стека.

Пример:

# Смотрим список сохранений
git stash list

# Применяем конкретное сохранение, но не удаляем его
git stash apply stash@{2}

Здесь:

  • stash@{2} — это третье по счету сохранение в вашем стеке;
  • после команды apply эта запись по-прежнему останется в git stash list.

apply удобно использовать, когда вы:

  • хотите применить один и тот же stash в несколько веток;
  • не уверены, все ли пройдет без конфликтов, и хотите иметь резерв.

git stash pop

  • делает то же самое, что apply, но удаляет запись из стека при успешном применении.

Пример:

# Применяем последнее сохранение и удаляем его из стека
git stash pop

Если при pop возникнут конфликты при слиянии, stash все равно будет удален, если Git посчитает применение успешным на уровне рефов. Из-за этого многие предпочитают безопасный подход:

git stash apply stash@{0}   # используем apply
# решаем конфликты, проверяем работу
git stash drop stash@{0}    # вручную удаляем, когда все ок

Так меньше шансов случайно потерять изменения.

Создание stash с разными опциями

Простое сохранение: git stash push

Базовая форма:

git stash push

Эта команда:

  • сохраняет изменения в отслеживаемых файлах;
  • убирает их из рабочей директории;
  • оставляет неотслеживаемые файлы как есть.

Часто хочется подписать сохранение:

git stash push -m "Черновик формы логина"

Комментарий:

  • флаг -m задает человекочитаемое описание;
  • позже вы увидите его в git stash list.

Сохранение вместе с неотслеживаемыми файлами

Иногда вы создаете новые файлы, которые еще не добавляли в индекс (git add), но хотите тоже их сохранить во временное хранилище. Тогда используйте -u или --include-untracked:

git stash push -u -m "Изменения + новые файлы"

Что произойдет:

  • все изменения в отслеживаемых файлах сохранятся;
  • все неотслеживаемые файлы тоже попадут в stash;
  • в рабочей директории станет «чисто» (как после git status без изменений).

Сохранение с игнорируемыми файлами

Реже, но все же бывает, что нужно stash-ить даже игнорируемые файлы (например, временные конфиги разработчика, которые не должны попадать в репозиторий, но вы не хотите их потерять).

В этом случае:

git stash push -a -m "Сохранить все вообще"

Флаг -a или --all:

  • включает и неотслеживаемые, и игнорируемые файлы;
  • это максимально «глубокое» сохранение состояния рабочей директории.

Сохранение только индексированных изменений

Иногда вы уже сделали git add для части файлов, а другая часть еще в рабочей директории как modified. Смотрите, как можно сохранить только те изменения, которые уже добавлены в индекс:

git stash push --keep-index -m "Проверить только закоммичиваемые изменения"

Что делает --keep-index:

  • сохраняет незакоммиченные изменения, которые не в индексе;
  • изменения, которые вы уже добавили в индекс, оставляет нетронутыми.

Типичный сценарий:

  1. Вы готовите коммит, делаете git add нужных файлов.
  2. Хотите запустить тесты только для будущего коммита без «лишних» правок.
  3. Делаете git stash push --keep-index.
  4. Запускаете тесты.
  5. Делаете git stash pop (или apply), чтобы вернуть остальные изменения.

Теперь давайте посмотрим, как работать с несколькими сохранениями.

Работа со стеком сохранений

Просмотр списка сохранений

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

git stash list

Вы увидите что-то вроде:

stash@{0}: On feature/login: Черновик формы логина
stash@{1}: On main: Фикс стилей шапки
stash@{2}: On feature/profile: Рефакторинг профиля пользователя

Обратите внимание:

  • stash@{0} — самое последнее сохранение;
  • stash@{1}, stash@{2} и так далее — более старые;
  • после On <ветка> указано сообщение, которое вы передали через -m.

Просмотр содержимого конкретного stash

Иногда вы хотите понять, что именно лежит в конкретном сохранении, прежде чем его применять. Здесь я размещаю пример, чтобы вам было проще понять:

# Сравнить stash@{1} с текущим состоянием HEAD
git stash show stash@{1}

Эта команда покажет короткий список измененных файлов. Чтобы увидеть полный diff, добавьте -p:

git stash show -p stash@{1}

Комментарий:

  • это удобно, когда у вас много сохранений, и вы хотите вспомнить, что внутри;
  • флаг -p (или --patch) показывает построчные изменения.

Применение конкретного stash

По умолчанию git stash pop и git stash apply работают с последним сохранением (stash@{0}), но вы можете явно указать запись:

# Применяем второе по счету сохранение, но не удаляем его
git stash apply stash@{1}

# Применяем и удаляем
git stash pop stash@{1}

Если вы применяете не верхний элемент стека через pop, Git:

  • попытается применить указанный stash;
  • после успеха удалит именно его, а не stash@{0};
  • остальные записи сдвинет (индексы пересчитаются).

Удаление отдельных и всех сохранений

Если сохранение больше не нужно, его можно убрать:

# Удалить конкретный stash
git stash drop stash@{2}

# Удалить последний (аналог drop stash@{0})
git stash drop

Удалить все сохранения разом:

git stash clear

С этой командой нужно быть аккуратнее — она безвозвратно очищает весь стек.

Частичное сохранение изменений (stash только части файлов)

Бывает, что в рабочей директории намешано много всего, а stash-ить нужно только часть изменений. Давайте разберемся на примере.

Использование git stash push с указанием файлов

Вы можете явно указать, какие файлы попадут в stash:

git stash push -m "Только изменения в login.go" path/to/login.go

В этом случае:

  • изменения в path/to/login.go сохранятся в stash;
  • остальные изменения останутся в рабочей директории;
  • stash будет содержать только указанный файл.

Можно указать несколько файлов или каталогов:

git stash push -m "Фронтенд изменения" src/frontend/ package.json

Комбинация с индексом (staging area)

Есть полезный прием:

  1. Добавить в индекс только те изменения, которые вы хотите stash-ить.
  2. Использовать --keep-index, чтобы разделить изменения.

Пример:

# Добавляем изменения, которые хотим временно убрать
git add src/feature_a/

# Сохраняем их в stash, но при этом оставляем их в индексе
git stash push --keep-index -m "Временный stash feature_a"

# Теперь можно сделать, например, коммит по остальной части кода
# или наоборот - по этим изменениям

Но чаще --keep-index применяют именно для временного удаления неиндексированных изменений, чтобы тестировать только «почти готовый» коммит.

Работа со stash и ветками

Применение stash в другой ветке

Ситуация: вы сделали временное сохранение в ветке feature/login, а потом решили, что эти изменения нужно перенести в новую ветку feature/new-login. Покажу вам, как это реализовано на практике.

Пошагово:

# Находимся на feature/login и делаем временное сохранение
git stash push -m "Черновик нового логина"

# Создаем новую ветку от нужной базы
git checkout -b feature/new-login origin/main

# Применяем сохранение в новую ветку
git stash pop stash@{0}

Важно:

  • git stash не «привязан» жестко к ветке, но его содержимое — это изменения относительно конкретного базового коммита;
  • если вы применяете stash в ветке с сильно отличающейся историей, возможны конфликты.

Создание ветки из stash: git stash branch

Отдельная полезная команда — git stash branch. Она берет:

  • базовый коммит, от которого был сделан stash;
  • сам stash;

и создает на их основе новую ветку. Это удобно, когда:

  • вы что-то накидали «на коленке»;
  • вдруг поняли, что из этого получится нормальная фича;
  • хотите оформить ее в отдельную ветку.

Пример:

# Смотрим список временных сохранений
git stash list

# Создаем ветку из второго stash
git stash branch feature/async-login stash@{1}

Что произойдет:

  1. Git найдет коммит, относительно которого был сделан stash@{1}.
  2. Создаст от него новую ветку feature/async-login и переключится на нее.
  3. Попробует применить stash@{1} к этой ветке.
  4. При успешном применении удалит stash@{1} из стека.

Если применение не удалось (слишком много конфликтов), stash не будет удален.

Конфликты при применении git stash

Почему возникают конфликты

Конфликты при git stash apply или pop — обычное явление, особенно если вы:

  • долго держали изменения в stash;
  • в базовой ветке успело многое поменяться;
  • применяете stash в ветку, отличающуюся от исходной.

По сути, Git выполняет мини-слияние:

  • берет базовый коммит;
  • берет изменения из stash;
  • берет текущее состояние рабочей ветки;
  • пытается совместить их.

Если изменения затрагивают одни и те же строки в файлах, возникают конфликты.

Как решать конфликты после git stash apply/pop

Здесь алгоритм такой же, как при обычном конфликте слияния:

# Применили stash и получили конфликты
git stash apply stash@{0}

# Git покажет, что есть конфликтующие файлы
git status

# Открываем конфликтующие файлы, вручную правим <<<<<<< HEAD и >>>>>>>
# После правок помечаем файл как решенный
git add path/to/conflicted-file

# Когда все конфликты решены, можно продолжить работу
# Например, сделать коммит с восстановленными правками
git commit -m "Восстановить изменения из stash и разрешить конфликты"

Если вы использовали git stash pop:

  • при возникновении конфликтов stash обычно все равно считается примененным, и запись удаляется;
  • чтобы подстраховаться, многие командой pop пользуются реже, предпочитая apply + drop, как мы уже обсуждали.

Stash и разные области изменений: рабочая директория и индекс

Что именно сохраняет git stash внутри

Давайте посмотрим чуть глубже. Внутри один stash — это:

  • один коммит с изменениями рабочей директории (modified/removed файлы);
  • один коммит с изменениями индекса (staged часть), если они есть;
  • иногда третий объект для неотслеживаемых файлов.

То есть git stash умеет раздельно сохранять:

  • то, что уже было добавлено в индекс (staged);
  • то, что просто изменено в рабочей копии (unstaged).

Из-за этого при применении stash состояние индекса и рабочей директории тоже восстанавливается примерно в том виде, в каком вы его сохраняли.

Пример с изменениями в индексе и рабочей директории

Давайте посмотрим, что происходит в типичной ситуации:

# Меняем два файла
vim a.go
vim b.go

# Добавляем в индекс только a.go
git add a.go

# Смотрим статус
git status
# Вы увидите:
#   изменения для коммита: a.go
#   неиндексированные изменения: b.go

# Делаем обычный stash
git stash push -m "Изменения в a.go и b.go"

Что сохранится:

  • и staged, и unstaged изменения попадут в stash;
  • рабочая директория станет чистой, индекс — тоже.

При git stash apply:

  • файл a.go вернется в состояние «изменен и уже добавлен в индекс»;
  • файл b.go вернется как «изменен, но не в индексе».

Просмотр и анализ stash через git show и git diff

Детальный просмотр содержимого stash

Мы уже смотрели на git stash show -p, но можно использовать и обычные инструменты Git:

# Показать полное содержимое stash как обычный коммит
git show stash@{0}

Обратите внимание, как этот фрагмент кода решает задачу диагностики:

  • git show показывает diff и метаинформацию;
  • вы видите точное состояние изменений, которые собираетесь восстановить.

Сравнение двух stash-записей

Иногда бывает полезно сравнить разные временные сохранения между собой:

git diff stash@{2} stash@{0}

Так вы увидите, чем отличаются два «черновика». Это не самый частый кейс, но полезен, когда вы, например, экспериментировали с разными подходами в коде и сохранили их в несколько stashes.

Частичные stashes через интерактивный режим (патчи)

Git stash не имеет отдельного интерактивного флага, как git add -p, но вы можете комбинировать его с индексом.

Прием: git add -p + git stash

Смотрите, я покажу вам пошаговый пример:

# У вас есть большой файл с разными изменениями
vim app.go

# Добавляем в индекс только часть изменений интерактивно
git add -p app.go   # выбираете hunks, которые хотите временно убрать

# Теперь в индексе только часть изменений
git status

# Используем stash как механизм временного перемещения
git stash push -m "Часть изменений app.go"

# В результате:
# - выбранные куски переместились в stash
# - остальные изменения остались в рабочем файле

То есть через git add -p вы решаете, какие hunks попадут в stash, а какие останутся. Это гибкий способ частичного временного сохранения без создания лишних локальных веток.

Риски при использовании git stash и как их уменьшить

Основные риски

Основные проблемы, с которыми сталкиваются разработчики:

  • забытые stashes, которые копятся месяцами;
  • применение stash в «не той» ветке и конфликты, которые сложно разрулить;
  • потеря изменений из-за неосторожного git stash clear или из-за конфликтного git stash pop.

Практичные рекомендации

  1. Давайте осмысленные сообщения

    Используйте -m, чтобы через месяц понимать, что было внутри:

    git stash push -m "WIP - валидация формы регистрации"
    
  2. Не превращайте stash в долговременное хранилище

    Если понимаете, что работа затягивается, лучше:

    • создать отдельную ветку;
    • применить stash туда;
    • сделать один или несколько рабочих коммитов.
  3. Предпочитайте apply + drop для важных изменений

    Вместо:

    git stash pop
    

    можно использовать:

    git stash apply stash@{0}
    # проверить, что все в порядке
    git stash drop stash@{0}
    

    Так меньше шансов случайно потерять изменения.

  4. Периодически проверяйте git stash list

    Если видите старые записи:

    • или удалите их (git stash drop, git stash clear);
    • или превратите в отдельные ветки (git stash branch).

Практические сценарии использования git stash

Быстро переключиться на горячий фикс (hotfix)

Сценарий:

  1. Работаете над новой фичей в feature/checkout.
  2. Появляется срочный баг в main.

Действия:

# Сохраняем текущие изменения, в том числе новые файлы
git stash push -u -m "WIP checkout improvements"

# Переключаемся на main
git checkout main

# Создаем ветку для hotfix
git checkout -b hotfix/cart-bug

# Фиксим баг, коммитим, вливаем в main
# ...

# Возвращаемся к своей работе
git checkout feature/checkout

# Восстанавливаем изменения
git stash pop

Разделить большую задачу на несколько веток

Иногда вы начали делать одну большую задачу, но в процессе понимаете, что часть работы — это отдельная фича. Тогда удобно:

# Находясь в feature/large-feature
git stash push -m "Подзадача: новый компонент профиля"

# Создаете новую ветку
git checkout -b feature/profile-component

# Применяете stash в новую ветку
git stash pop

# Оформляете отдельные коммиты и PR

Временное скрытие экспериментального кода

Бывает, вы экспериментировали с подходом, результат пока неясен, но нужно на время вернуться к чистому состоянию. Тогда stash работает как «быстрая заморозка»:

git stash push -m "Экспериментальный алгоритм поиска"
# Поработали с чистым кодом
git stash pop   # когда хотите вернуть эксперимент

Заключение

Git stash — это не просто «корзина» для временного кода, а полноценный инструмент управления незакоммиченными изменениями. Он позволяет:

  • безопасно переключаться между ветками и задачами;
  • временно убирать «сырой» код, не засоряя историю коммитов;
  • хранить сразу несколько наборов изменений и по необходимости к ним возвращаться;
  • переносить черновики между ветками и даже создавать новые ветки прямо из stash.

Ключевые моменты, которые стоит запомнить:

  • git stash push — базовая команда для сохранения изменений;
  • git stash apply применяет изменения, но не удаляет их;
  • git stash pop применяет и удаляет запись (используйте осторожнее);
  • -u и -a управляют тем, какие файлы попадут в stash (включая неотслеживаемые и игнорируемые);
  • git stash branch удобен, когда из черновика выросла полноценная фича.

Чем лучше вы понимаете, как именно git stash сохраняет и восстанавливает состояние (рабочая директория + индекс), тем увереннее будете пользоваться им в реальных проектах.


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

1. Как восстановить stash, если я случайно сделал git stash clear?

Если вы уже выполнили git stash clear, стандартными средствами Git восстановить записи практически невозможно. Однако иногда объекты еще есть в базе, и помогает просмотр reflog:

# Смотрим историю перемещений ссылок
git reflog

# Ищем ссылки вида stash@{...} или коммиты, соответствующие stash
# Берем нужный хеш и создаем от него ветку
git branch restore-from-stash <hash>

Если ссылки на stash не сохранились в reflog, восстановление, как правило, невозможно.

2. Можно ли переименовать уже созданный stash?

Напрямую — нет. Но можно создать новый stash с нужным именем на основе старого и удалить оригинал:

# Применяем старый stash без удаления
git stash apply stash@{1}

# Создаем новый с нужным сообщением
git stash push -m "Новое понятное имя"

# Удаляем старый
git stash drop stash@{1}

Так вы получите функциональный аналог «переименования».

3. Как сохранить stash только для неотслеживаемых файлов?

Напрямую Git не умеет stash-ить строго только неотслеживаемые файлы, но можно использовать обходной путь:

# Временно добавляем только неотслеживаемые файлы
git add -N .

# Теперь они считаются измененными отслеживаемыми
git stash push -m "Только ранее неотслеживаемые файлы"

# По желанию можно сбросить индекс
git reset

Команда git add -N помечает файлы как отслеживаемые без фактического добавления содержимого.

4. Что делать, если после git stash pop остались конфликты и непонятное состояние?

Алгоритм такой:

  1. Посмотрите статус:

    git status
    
  2. Для каждого конфликтующего файла:

    • откройте его;
    • вручную решите конфликтные участки <<<<<<<, =======, >>>>>>>;
    • отметьте файл как решенный:

      git add path/to/file
      
  3. После всех правок сделайте коммит, чтобы зафиксировать итоговое состояние.

Если все совсем плохо и вы хотите откатиться:

git merge --abort  # если Git считает, что вы в процессе слияния
git reset --hard   # вернет к последнему коммиту (осторожно, потеряете незакоммиченные изменения)

5. Можно ли автоматически применять stash после успешного мержа или переключения ветки?

Прямого встроенного механизма нет, но можно использовать хуки Git (например, post-checkout или post-merge) и там вызывать свои скрипты:

# .git/hooks/post-checkout (сделайте исполняемым)
#!/bin/sh
# Пример - если есть stash, выводим напоминание
if git stash list | grep -q "WIP"; then
  echo "Есть незакрытые WIP-stash записи"
fi

Через хуки вы можете реализовать любую автоматизацию вокруг git stash, но стоит делать это аккуратно, чтобы не ломать ожидаемое поведение Git.

Сохранение с сообщением в Git - git stash saveСтрелочка вправо

Постройте личный план изучения Git до уровня Middle — бесплатно!

Git — часть карты развития Frontend

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Бесплатные лекции

Все гайды по Git

Открыть базу знаний

Лучшие курсы по теме

изображение курса

Основы Git

Антон Ларичев
AI-тренажеры
Гарантия
Бонусы
иконка звёздочки рейтинга4.9
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее

Отправить комментарий