Статьи

Совет: используя силу Git Stash

Представьте, что вы работаете над функцией в программном проекте, управляемом Git. Вы находитесь в процессе внесения некоторых изменений, когда получаете запрос на исправление критической ошибки. Чтобы начать решать проблему, вам нужна новая ветка и чистый рабочий каталог. Когда речь идет об основных командах Git, у вас есть два варианта:

  • Запустите git reset --hard чтобы удалить ваши незафиксированные изменения.
  • Запишите свою незавершенную работу как новый коммит.

Первый вариант теряет всю вашу работу, в то время как последний приводит к частичной фиксации, которая не имеет смысла. Ни один из этих сценариев не все, что желательно.

Это где команда git stash вступает в игру. Как и git reset --hard , он дает вам чистый рабочий каталог, но он также записывает ваши неполные изменения внутренне. После исправления критической ошибки вы можете повторно применить эти изменения и продолжить с того места, где остановились. Вы можете думать о git stash как о «кнопке паузы» для вашей текущей работы.

В этом руководстве предполагается, что вы установили Git и знакомы с его основным рабочим процессом. Вам должно быть удобно организовывать изменения, создавать коммиты и работать с ветками. Вам также понадобится Git-репозиторий для экспериментов.

Прежде чем вы сможете запустить 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

Это примет как ваши поэтапные, так и не поэтапные изменения, запишет их внутри, а затем очистит рабочий каталог. Это дает вам возможность переключаться на новую ветку и разрабатывать другие функции, не беспокоясь о том, что ваш частичный коммит что-нибудь испортит.

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

1
git stash pop

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

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

Для большинства сценариев вышеупомянутые команды — все, что вам нужно, когда дело доходит до «кнопки паузы». Но понимание того, как спрятанные изменения представлены, открывает двери для более сложного использования.

До сих пор мы говорили только о сохранении одного набора изменений. Однако каждый раз, когда вы запускаете 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 не совсем обычная команда, она может быть очень удобным инструментом для создания значимых коммитов. Это позволяет хранить неполную работу, избегая необходимости фиксировать частичные снимки в вашей постоянной истории проекта. Помните об этом в следующий раз, когда вы захотите сделать паузу, над которой вы работали, и вернуться к ней позже.