перемещение измененных файлов в другую ветку для регистрации


422

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

Ответы:


751

git stash твой друг.

Если вы еще не сделали коммит, просто запустите git stash. Это сохранит все ваши изменения.

Переключитесь на ветку, в которую хотите внести изменения, и запустите git stash pop.

Есть много применений для git stash. Это, безусловно, одна из наиболее полезных причин.

Пример:

# work on some code
git stash
git checkout correct-branch
git stash pop

122
Не нужно прятать незафиксированные изменения, они идут вместе с вами, когда вы проверяете ветку. Stash больше подходит для длительного хранения временных вещей (вещи, которые вы хотите закончить и зафиксировать позже, но вам нужно сделать что-то еще прямо сейчас).
Теккуб

2
Я понял это. Поэтому я должен спрятать, переключить ветку, а затем поп C:\kf [develop +0 ~4 -0]> git checkout feature/customers<br/> error: Your local changes to the following files would be overwritten by checkout:<br/> AspWebApp.vNext/global.asa<br/> RestApi/Web.config<br/> Please, commit your changes or stash them before you can switch branches.<br/> Aborting
IsmailS

3
@Tekkub "долгосрочное хранение временных вещей", когда это высказывание выглядит очень неловко, еще один момент использования stash - он помещает его в стек, поэтому, если вы не хотите, чтобы он переносился и работал над чем-то другим, это полезно таким образом , Да, вы не должны, но просто чувствует себя чище и лучше контролировать.
Atherion

браво детка! следует добавить то, что вы должны сделать, если вы сделали коммиты
Ишан Шривастава

2
@Tekkub Это верно только в том случае, если ветвь, на которую вы переключаетесь, соответствует ветке, в которой вы находитесь. Если, например, вы случайно работаете над веткой prod и вам нужно переключиться на ветку stage, но stage изменился в промежутке времени, это единственный способ сделать это.
danielson317

248

Если вы еще не зафиксировали свои изменения , просто используйте, git checkoutчтобы перейти к новой ветви, а затем зафиксировать их как обычно - изменения в файлах не привязаны к определенной ветви, пока вы не подтвердите их.

Если бы уже зафиксировали изменения:

  1. Введите git logи запомните SHA коммита, который вы хотите переместить.
  2. Проверьте ветку, в которую вы хотите переместить коммит.
  3. Тип git cherry-pick SHAзаменив SHA сверху.
  4. Вернитесь в исходную ветку.
  5. Используйте git reset HEAD~1для сброса назад перед фиксацией неправильной ветки.

cherry-pick берет данный коммит и применяет его к текущему извлеченному заголовку, что позволяет вам копировать коммит в новую ветку.


9
Тебе даже не нужно выбирать вишню. git reset HEAD~N --softа затем git checkout -bпереместить весь теперь незафиксированный код в новую ветку.
Аарон

19
Изменения в файлах не привязаны к определенной ветке, пока вы не подтвердите их. <- это. Это решило для меня загадку. Спасибо.
Чаллака

8
При попытке переключить ветви я получаю следующую ошибку: «локальные изменения в следующих файлах будут перезаписаны при оформлении заказа». Так что не похоже, что я могу перейти в другую ветку и выполнить коммит нормально.
Миша

3
@ Миша это не сработает, если вы переключаетесь между двумя ветвями с разной историей
watashiSHUN

1
@ Аарон, это намного лучше (для сценария после коммита)! Пожалуйста, сделайте отдельный ответ.
Джектоз

16

К сожалению, это происходит со мной довольно регулярно, и я использую, git stashесли я понял свою ошибку раньше, git commitи использую git cherry-pickиначе, обе команды объяснены довольно хорошо в других ответах

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

Если вы еще не зафиксировали свои изменения, просто используйте git checkout, чтобы перейти в новую ветку, а затем зафиксируйте их как обычно

Заявление @Amber не является ложным, когда вы переходите в newBranch , git checkout -b newBranchсоздается новый указатель, который указывает на тот же коммит, что и ваша текущая ветвь.
На самом деле, если у вас есть другая ветка, которая делится историей с вашей текущей веткой (обе указывают на один и тот же коммит), вы можете «переместить свои изменения»git checkout targetBranch

Однако обычно разные ветви означают разную историю, и Git не позволит вам переключаться между этими ветками с грязным рабочим каталогом или промежуточной областью. в этом случае вы можете сделать git checkout -f targetBranch(очистить и выбросить изменения) или git stage+ git checkout targetBranch(очистить и сохранить изменения), простой запуск git checkout targetBranchвыдаст ошибку:

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


5

Мягкий сброс мерзавец поместит зафиксированные изменения обратно в свой индекс. Затем проверьте ветку, которую вы намеревались зафиксировать. Затем git commit с новым сообщением commit.

  1. git reset --soft <commit>

  2. git checkout <branch>

  3. git commit -m "Commit message goes here"

Из git docs :

git reset [<mode>] [<commit>]Эта форма сбрасывает текущий заголовок ветви и, возможно, обновляет индекс (сбрасывая его в дерево) и рабочее дерево в зависимости от. Если опущено, по умолчанию используется --mixed. Должно быть одно из следующего:

--softНе затрагивает индексный файл или рабочее дерево (но сбрасывает заголовок, как это делают все режимы). Это оставляет все ваши измененные файлы «Изменениями, которые нужно зафиксировать», как это будет указано в git status.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.