Локальное хранилище Git: как работать с git stash
Упростите себе жизнь и не создавайте миллион ненужных веток в репозитории.
Кадр: мультсериал «Утиные истории» (2017–2021)
Разбираемся, зачем нужна команда git stash, какие у неё возможности и почему вам стоит применять её в работе уже сегодня.
Зачем «откладывать» код
Представьте, что вы садитесь утром за компьютер и видите новое сообщение: «Привет, Андрей! Не мог бы пофиксить этот дурацкий баг с кнопкой у нас на главной странице? Все подробности уже у тебя в задаче. Желательно сделать это сегодня до вечера». Вы приступаете к работе.
Пока вы тестируете гипотезы в коде, вам прилетает новое задание: «Тут такое дело, нужно срочно пофискить другой баг на сервере. Из-за него у нас не работает оплата на сайте. Бросай всё и иди исправлять». Но у вас уже почти получилось сделать то задание — не удалять же весь код, который вы написали.
Вариантов решения такой дилеммы несколько. Например, можно создать новую ветку и поместить туда все изменения — закоммитить. Но из-за этого в репозитории проекта появятся десятки веток с очень странными названиями: TEST 1, BUTTON FIX, «НЕ ТРОГАТЬ!!!» — и однажды он просто превратится в свалку.
Есть и второй способ — скопировать все файлы, в которых вы делали изменения, и переименовать их понятным для вас образом: «имя_файла_ФИКС-БАГА». Но это нужно будет делать с каждым файлом — и, в принципе, это очень неудобно. Поэтому такой вариант тоже не подходит.
Хотелось бы что-то автоматизированное и удобное. Именно для этого и придумали команду git stash.
Что делает команда git stash
Команда git stash упрощает работу с изменениями в коде. Она помогает быстро сохранить всё в архив и скрыть правки, чтобы переключиться на другую ветку и продолжить работу без них.
При этом изменения не добавляются в репозиторий в виде коммита: они складываются в локальное хранилище у вас на компьютере. Этим git stash и удобна.
Теперь давайте вернёмся снова к нашему примеру. Мы поняли, что нам нужно где-то сохранить все изменения и пойти фиксить другой срочный баг. Давайте же это сделаем.
git stash save
Итак, код ещё не дописан, поэтому коммитить его в основную ветку — бессмысленно. Значит, нам нужно сохранить изменения локально. Для этого воспользуемся командой git stash save:
Мы видим, что изначально у нас были изменения в файлах: index.html и style.css. А после запуска команды git stash save все изменения пропали — но это не навсегда.
Теперь все правки лежат в локальном хранилище, а наш проект как бы находится в состоянии, в котором он был до того, как мы начали фиксить баг. В подобный локальный архив можно положить сколько угодно сохранений. Все они будут лежать там в виде списка, или, лучше сказать, стека, работающего по принципу: «Первый вошёл — первый вышел».
Хорошо, мы можем сложить много изменений в хранилище — но как мы потом разберём, какое именно сохранение нам нужно достать. Хотелось бы как-то подписать все эти сейвы. Для этого нужно всего лишь указать в кавычках имя сохранения:
Ещё может так случиться, что мы добавили новые файлы, которых изначально в проекте не было, — следовательно, их нам тоже нужно будет спрятать. Делается это всё той же командой git stash save, но с добавлением параметра --include-untracked, или -u:
Если нужно добавить в локальное хранилище все игнорируемые файлы, то используем параметр --all, или -a:
Есть ещё более продвинутый способ добавления отдельных файлов через git stash — с помощью параметра --patch, или -p. Если указать его, Git будет предлагать вам по очереди все файлы, в которых содержатся изменения, и спрашивать: добавлять ли их в локальное хранилище или нет.
Чтобы понять, что означают все эти буквы при выборе, можно ввести знак ?, и появится справка:
Основными опциями тут будут y и n, которые означают: откладывать файл или не откладывать.
Теперь, когда мы умеем локально сохранять изменения, пора научиться смотреть, какие из них уже находятся в локальном хранилище.
git stash list
Мы пошли делать ту самую срочную задачу и быстро её закончили. Пора возвращаться к нашим изменениям. Но для начала нужно посмотреть, что мы вообще закинули в локальное хранилище. Делается это командой git stash list:
Команда выводит список всех сохранений и их описания, которые задаются в кавычках после команды git stash save. Мы также видим, что у нас есть непонятное сохранение «WIP on main: 4532d67 our new homepage». Оно получило такое название по дефолту — просто потому, что мы не задали ему название в кавычках.
git stash show
Давайте теперь посмотрим, что находится внутри наших сохранений — а уже потом применим их к проекту. Используем команду git stash show:
Итак, мы видим, что в этом сохранении есть два изменения в файле index.html и четыре — в файле style.css. А это как раз то, над чем мы и работали до возникновения другой, более срочной задачи.
Стоит сразу отметить, что когда мы ввели эту команду, то взяли самое верхнее локальное сохранение — «stash@{0}: "Bug Fix: Main page"». Оно берётся по умолчанию, так как у него индекс 0. Если нам нужно взять другое, придётся дописать к команде stash@{индекс_сохранения}:
В нём оказались точно такие же изменения, но на самом деле это разные локальные сохранения. А ведь могло бы быть и так:
Ещё не очень понятно, какие именно в этом сохранении изменения. Чтобы устранить эту неопределённость, воспользуемся параметром --patch, или -p, который покажет разницу между вашими файлами и изменёнными:
git stash apply
Теперь, когда мы нашли нужные изменения, пора их достать и применить к проекту. Для этого воспользуемся командой git stash apply. Она достанет из локального хранилища последнее сохранение:
Если мы хотим применить другое сохранение, то указываем его после слова apply:
git stash pop
После вызова команды git stash apply изменения всё ещё остаются в локальном архиве. Чтобы достать сохранение и полностью удалить его из хранилища, используем команду git stash pop:
Если теперь посмотреть список сохранений, последнего там уже не окажется:
Чтобы удалить конкретное сохранение, нужно указать его после слова pop:
git stash branch
Допустим, мы всё же хотим создать новую ветку в репозитории со всеми изменениями из локального хранилища. Для этого есть команда git stash branch:
И вот у нас уже готова новая ветка, в которую мы накатили все нужные изменения из локального хранилища. При этом сохранение в самом хранилище удалилось:
git stash drop
Бывает, что нужно удалить старые сохранения из локального хранилища, чтобы они не занимали лишнего места или просто не мешали. Это можно сделать с помощью команды git stash drop:
git stash clear
Наконец мы закончили работу над проектом на сегодня и запушили все коммиты, но список локальных сохранений до сих пор не пуст. Пора его полностью удалить. Применяем команду git stash clear:
Что запомнить
- git stash — это команда, которая позволяет записывать изменения в коде в локальное хранилище и возвращаться к ним позже. И всё это происходит на компьютере, а не в репозитории.
- В это хранилище можно поместить сколько угодно записей. При этом над ними можно проводить разные действия — например, добавлять, удалять или просматривать их содержимое.
- Базовые команды для git stash — это git stash save, git stash list и git stash apply. Они помогут вам сохранить изменения в хранилище, посмотреть список доступных сохранений и применить их к своему проекту.
Больше интересного про код в нашем телеграм-канале. Подписывайтесь!