ветка git switch без отмены локальных изменений

182

Хорошо, скажем, однажды мы осуществляем кучу модификаций, и когда мы идем к их фиксации, мы замечаем, что работаем не с той веткой.

Как мы можем заставить git переключать ветки, не отказываясь от локальных изменений .

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

  • Резервное копирование измененного репо
  • git reset --hard
  • git checkout right-branch
  • Восстановить изменения
  • git commit -m "changes"
megawac
источник

Ответы:

343

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

Давайте возьмем классическую ошибку:

$ git checkout master
... pause for coffee, etc ...
... return, edit a bunch of stuff, then: oops, wanted to be on develop

Итак, теперь вы хотите, чтобы эти изменения, которые вы еще не совершили master, были внесены develop.

  1. Если вы неdevelop тем не менее, метод тривиален:

    $ git checkout -b develop
    

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

  2. Вы естьdevelop . Посмотрим, позволит ли Git переключаться, ничего не делая:

    $ git checkout develop
    

    Это либо удастся, либо пожаловаться. Если это удастся, отлично! Просто зафиксируй. Если нет ( error: Your local changes to the following files would be overwritten ...), у вас еще есть много вариантов.

    Вероятно, проще всего git stash(как postговорили все остальные ответчики, которые избивали меня до щелчка ). Запустите git stash saveили git stash push, 1 или просто обычный, git stashчто сокращенно от save/ push:

    $ git stash
    

    Это фиксирует ваш код (да, он действительно делает некоторые коммиты), используя странный не-ответвительный метод. Коммиты, которые он делает, не «включены» ни в какую ветку, но теперь безопасно хранятся в репозитории, так что теперь вы можете переключать ветки, а затем «применять» тайник:

    $ git checkout develop
    Switched to branch 'develop'
    $ git stash apply
    

    Если все идет хорошо, и вам нравятся результаты, вы должны тогда git stash dropзаначить. Это удаляет ссылку на странные не-ветвящиеся коммиты. (Они все еще находятся в хранилище и иногда могут быть получены в чрезвычайной ситуации, но для большинства целей вы должны считать, что они исчезли в этот момент.)

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

Многие люди используют git stash pop, что является сокращением git stash apply && git stash drop. Это хорошо, насколько это возможно, но это означает, что если приложение приводит к путанице, и вы решаете, что не хотите идти по этому пути, вы не сможете легко вернуть тайник. Вот почему я рекомендую отдельно apply, проверять результаты, dropтолько если / когда выполнено. (Это, конечно, вводит еще один момент, когда вы можете сделать еще один перерыв на кофе и забыть о том, что вы делали, вернуться и сделать что-то не то, так что это не идеальное лекарство.)


1save в git stash saveстаром глагол для создания нового притона. В Git версии 2.13 появился новый глагол, чтобы сделать вещи более согласованными popи добавить больше опций в команду создания. Git версии 2.16 формально не поддерживает старый глагол (хотя он все еще работает в Git 2.23, которая является последней версией на момент редактирования).

Торек
источник
3
Что если я захочу переключиться на другую ветку без фиксации на текущей ветви (например, изменения не завершены), а затем переключиться обратно для продолжения?
stt106
@ stt106: вы все еще должны фиксировать, но вы можете сделать это, как в этом и других ответах, git stashтак, чтобы коммиты - так как git stashвы получаете два коммита на вход в тайник, в необычном расположении - ни на одной ветви. Однако, за исключением очень коротких особых случаев, я обычно предпочитаю делать нормальный коммит. Вы можете git reset --softили git reset --mixedпозже, или использовать, git commit --amendчтобы отодвинуть это в сторону, когда вы вернетесь к работе над этой веткой. (В современной Git, вы можете также использовать git worktree add, которые могут быть четным лучшим решением.)
Торек
«Это либо удастся, либо пожаловаться». Каковы причины успеха или ошибки при оформлении заказа?
Nanocv
1
@nanocv: см stackoverflow.com/questions/22053757/...
Торек
все мои локальные изменения теряются, когда я переключаюсь с помощью описанных выше шагов, я нахожусь в <a> ветви и делаю свои изменения, и я хочу перейти в <b> ветку и протолкнуть все свои изменения в этом. когда я делаю git stash и перемещаюсь в другие ветки, он вытягивает все файлы <b> ветви, и мои локальные изменения теряются
Мукул Мунджал,
38

Используйте git stash

git stash

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

 git stash apply

Вы даже можете вытащить отдельные предметы. Чтобы полностью сдуть сундук:

 git stash clear
луч
источник
7
Последняя команда, вероятно, должна быть git stash drop; git stash clearуничтожит весь стек, включая, возможно, несвязанные тайники с этим набором команд.
Леланд
15
  • git stash чтобы сохранить ваши незафиксированные изменения
  • git stash list перечислить ваши сохраненные незафиксированные тайники
  • git stash apply stash@{x} где х может быть 0,1,2 .. нет тайников, которые вы сделали
сломанная нога
источник
4

Вы также можете :

  • Используйте git stashдля хранения ваших изменений или,

  • Создайте другую ветку и зафиксируйте ваши изменения там, а затем объедините эту ветку с вашим рабочим каталогом.

X3074861X
источник