Представьте, что вы работаете над функцией в программном проекте, управляемом Git. Вы находитесь в процессе внесения некоторых изменений, когда получаете запрос на исправление критической ошибки. Чтобы начать решать проблему, вам нужна новая ветка и чистый рабочий каталог. Когда речь идет об основных командах Git, у вас есть два варианта:
- Запустите
git reset --hard
чтобы удалить ваши незафиксированные изменения. - Запишите свою незавершенную работу как новый коммит.
Первый вариант теряет всю вашу работу, в то время как последний приводит к частичной фиксации, которая не имеет смысла. Ни один из этих сценариев не все, что желательно.
Это где команда git stash
вступает в игру. Как и git reset --hard
, он дает вам чистый рабочий каталог, но он также записывает ваши неполные изменения внутренне. После исправления критической ошибки вы можете повторно применить эти изменения и продолжить с того места, где остановились. Вы можете думать о git stash
как о «кнопке паузы» для вашей текущей работы.
Предпосылки
В этом руководстве предполагается, что вы установили Git и знакомы с его основным рабочим процессом. Вам должно быть удобно организовывать изменения, создавать коммиты и работать с ветками. Вам также понадобится Git-репозиторий для экспериментов.
1. Скрытые изменения
Прежде чем вы сможете запустить git stash
, вам нужно внести некоторые незафиксированные изменения в ваш репозиторий Git. Например, если вы отредактировали файл с именем foo.py
, ваш вывод git status
будет выглядеть так:
1
2
3
4
5
6
|
On branch master
Changes not staged for commit:
(use «git add <file>…» to update what will be committed)
(use «git checkout — <file>…» to discard changes in working directory)
modified: foo.py
|
Чтобы сохранить эти изменения, просто выполните git stash
без аргументов.
1
|
git stash
|
Это примет как ваши поэтапные, так и не поэтапные изменения, запишет их внутри, а затем очистит рабочий каталог. Это дает вам возможность переключаться на новую ветку и разрабатывать другие функции, не беспокоясь о том, что ваш частичный коммит что-нибудь испортит.
2. Повторное применение скрытых изменений
Когда вы будете готовы вернуться к своей незавершенной работе, выполните следующую команду, чтобы повторно применить сохраненные изменения:
1
|
git stash pop
|
Последний сохраненный набор изменений появится в вашем рабочем каталоге, и вы сможете продолжить с того места, на котором остановились. Это все, что нужно сделать.
3. Разрешение конфликтов
Как и команда git merge
, git stash pop
может привести к конфликтам, если те же разделы исходного кода изменились с тех пор, как вы запустили git stash
. Когда это произойдет, вы увидите следующее сообщение после запуска git stash pop
:
1
2
|
Auto-merging foo.py
CONFLICT (content): Merge conflict in foo.py
|
Вы также найдете затронутый файл, перечисленный в разделе Unmerged paths
в выводе git status
, а также затронутые строки в исходном файле.
1
2
3
4
5
|
<<<<<<< Updated upstream
print(«Recently committed changes»);
=======
print(«Incomplete work»);
>>>>>>> Stashed changes
|
Вам нужно будет вручную разрешить конфликт в исходном файле, но обычно вы не хотите фиксировать его немедленно, как после конфликта git merge
. Большую часть времени вы будете продолжать работать над своей незаконченной функцией, пока не подготовите содержательный коммит. Затем вы можете просто добавить его в индекс и зафиксировать как обычно. Другими словами, вы можете рассматривать git stash pop
конфликты так же, как и любые другие незафиксированные изменения.
4. Шкатулка
Для большинства сценариев вышеупомянутые команды — все, что вам нужно, когда дело доходит до «кнопки паузы». Но понимание того, как спрятанные изменения представлены, открывает двери для более сложного использования.
До сих пор мы говорили только о сохранении одного набора изменений. Однако каждый раз, когда вы запускаете git stash
, незафиксированные изменения сохраняются в стеке. Это означает, что вы можете хранить несколько наборов изменений одновременно.
Это полезно на ранних стадиях разработки, когда вы не уверены, в каком направлении хотите идти. Вместо того, чтобы терять изменения с помощью git reset --hard
, вы можете сохранить ваши снимки в процессе работы в стеке на тот случай, если вы захотите повторно применить один из них позже.
Вы можете проверить стек с параметром list
.
1
|
git stash list
|
Если вы ранее выполняли git stash
три раза, это вывело бы что-то вроде следующего:
1
2
3
|
stash@{0}: WIP on new-feature: 5cedccc Try something crazy
stash@{1}: WIP on new-feature: 9f44b34 Take a different direction
stash@{2}: WIP on new-feature: 5acd291 Begin new feature
|
Команда git stash pop
всегда повторно применяет самый последний снимок, который находится вверху стека stash. Но также можно выбрать, какой сохраненный снимок вы хотите повторно применить с помощью команды apply
. Например, если вы хотите повторно применить второй набор изменений, вы должны использовать следующую команду:
1
|
git stash apply stash@{1}
|
Как и в git stash pop
, изменения снова появятся в вашем рабочем каталоге, и вы сможете продолжить работу с неполной функцией. Обратите внимание, что это не приведет к автоматическому удалению снимка из стека хранилища. Вместо этого вам нужно будет удалить его вручную с помощью команды drop
.
1
|
git stash drop stash@{1}
|
Опять же, работа со стековым хранилищем для большинства пользователей Git является более подходящим вариантом. Команды git stash
и git stash pop
должны подойти для большинства ваших потребностей, хотя git stash list
также может оказаться полезным, если вы забыли, где выполнялась ваша последняя операция stash.
Вывод
Передача осмысленных снимков лежит в основе любого рабочего процесса Git. Целеустремленные инкапсулированные коммиты значительно облегчают навигацию по истории вашего проекта, выяснение того, где были обнаружены ошибки, и отмену изменений.
Хотя git stash
не совсем обычная команда, она может быть очень удобным инструментом для создания значимых коммитов. Это позволяет хранить неполную работу, избегая необходимости фиксировать частичные снимки в вашей постоянной истории проекта. Помните об этом в следующий раз, когда вы захотите сделать паузу, над которой вы работали, и вернуться к ней позже.