Переместить существующую, незафиксированную работу в новую ветку в Git

3128

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

Как переместить существующие незафиксированные изменения в новую ветку и сбросить текущую?

Я хочу сбросить текущую ветку, сохранив при этом существующую работу над новой функцией.

Дейн О'Коннор
источник
Эта же интересная тема stackoverflow.com/q/556923/269514 ?
Гилберто

Ответы:

3645

Используйте следующее:

git checkout -b <new-branch>

Это оставит вашу текущую ветку как есть, создаст и извлечет новую ветку и сохранит все ваши изменения. Затем вы можете вносить изменения в файлы для фиксации:

git add <files>

и добавьте в свою новую ветку :

git commit -m "<Brief description of this commit>"

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

Вы не сбрасываете исходную ветку, она остается как есть. Последний коммит <old-branch>останется прежним. Поэтому вы checkout -bи потом совершаете.


Обновление 2020 / Git 2.23

Git 2.23 добавляет новый switch подкоманду в попытке очистить часть путаницы, возникающей из-за перегруженного использования checkout(переключение веток, восстановление файлов, отсоединение HEAD и т. Д.)

Начиная с этой версии Git, замените вышеприведенную команду на:

git switch -c <new-branch>

Поведение идентично и остается неизменным.

knittl
источник
15
Просто чтобы убедиться, мне нужно зафиксировать незавершенную функцию ДО того, как я сброслю свою первоначальную ветку? Или эти незафиксированные файлы будут сохранены независимо от фиксации?
Дейн О'Коннор
192
К вашему сведению: изменения в рабочем каталоге и внесенные в индекс изменения не относятся к ветви. git checkout -b <new branch>изменения, где эти изменения закончатся.
Якуб Наренбский
152
Если у вас уже есть ветка и вы хотите перенести изменения в существующую ветку,
оформите
14
Если вы хотите перенести новую ветку в удаленный репозиторий: stackoverflow.com/questions/2765421/…
Dewayne
10
@JDSmith: незафиксированные изменения НЕ принадлежат какой-либо ветви. Они находятся только в рабочем каталоге git checkout ./ удалят их git reset --hardбезвозвратно
knittl
331

В качестве альтернативы:

  1. Сохранить текущие изменения во временном хранилище:

    $ git stash

  2. Создайте новую ветку на основе этого тайника и переключитесь на новую ветку:

    $ git stash branch <new-branch> stash@{0}

Совет: используйте клавишу табуляции, чтобы уменьшить ввод имени тайника.

Робин Цю
источник
51
Если другая ветвь уже существует, вы можете просто переключиться на нее с помощью checkout, а затем git stash apply.
Archonic
6
Я не понимаю подсказку «Совет: используйте клавишу табуляции, чтобы уменьшить ввод имени тайника». Разве "stash @ {0}" не является именем? Я не могу запустить его успешно.
Герберт
7
Почему это лучше, чем принятый ответ stackoverflow.com/a/1394804/754997 ?
Крис Пейдж
10
Я не понимаю, почему это лучше, чем принятый ответgit checkout -b <new branch name>
Noitidart
6
Вам не нужно, git add -Aпрежде чем копить.
Вичле
48

Если вы выполняли коммиты в своей основной ветке во время кодирования, но теперь хотите переместить эти коммиты в другую ветку, это быстрый способ:

  1. Скопируйте свою текущую историю в новую ветвь, включая все незафиксированные изменения:

    git checkout -b <new-feature-branch>
    
  2. Теперь принудительно откатим исходную "грязную" ветку: (без переключения на нее)

    git branch -f <previous-branch> <earlier-commit-id>
    

    Например:

    git branch -f master origin/master
    

    или если вы сделали 4 коммита:

    git branch -f master HEAD~4
    

Предупреждение: git branch -f master origin/master будет сброс отслеживания информации для этой отрасли. Таким образом, если вы настроили своюmasterветвь для отправки в другое место,origin/masterто эта конфигурация будет потеряна.

Предупреждение. Существует также опасность перебазирования после ветвления, которое описано здесь . Единственный способ избежать этого - создать новую историю с помощью cherry-pick. Эта ссылка описывает самый безопасный метод защиты от ошибок . Если у вас есть незафиксированные изменения, вы можете захотетьgit stashв начале иgit stash popв конце.

joeytwiddle
источник
6
Это отвечает на вопрос, который немного отличается от того, что задал оператор. Я решил разместить этот ответ здесь, потому что это то, куда Google привел меня, когда я искал ответ. Актуальный вопрос, который касается этой ситуации , здесь .
Joeytwiddle
26

Общий сценарий следующий: я забыл создать новую ветку для новой функции и делал всю работу в старой ветви функции. Я перенес всю «старую» работу в основную ветвь и хочу, чтобы моя новая ветвь выросла из «основной». Я не сделал ни одного коммита моей новой работы. Вот структура ветви: "master" -> "Old_feature"

git stash 
git checkout master
git checkout -b "New_branch"
git stash apply
Алекс Буров
источник
18

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

git cherry-pick <commitID>

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

пароль
источник
2
Хорошее решение для переноса частичных изменений в новую ветку ... так как вы можете зафиксировать то, что вы хотите сейчас, спрятать все другие изменения, проверить ветку, из которой вы хотите ветвиться, cherry-pick, которая фиксирует новую ветку, вернуться к исходной ветке, сделайте полный сброс назад коммита, затем сделайте трещотку, добавьте, зафиксируйте и спойте аллилуйя.
Мередит
1
@Мередит, хаха, ты что-то в этом роде. Это здорово, если вы не планируете свои изменения заранее ... и кто это делает;)
пароль
1

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

Все, что вам нужно сделать, - это переключиться на новую ветку в GitHub Desktop, и она предложит вам оставить свои изменения в текущей ветке (которая будет сохранена) или перенести ваши изменения с вами в новую ветку. Просто выберите второй вариант, чтобы внести изменения в новую ветку. Затем вы можете совершить как обычно.

GitHub Desktop

Кристофер Доман
источник
1

Это может быть полезно для всех, кто использует инструменты для GIT

команда

Переключить ветку - она ​​переместит ваши изменения в новую ветку. Затем вы можете зафиксировать изменения.

 $ git checkout -b <new-branch>

TortoiseGit

Щелкните правой кнопкой мыши по вашему хранилищу и затем используйте TortoiseGit-> Switch / Checkout

введите описание изображения здесь введите описание изображения здесь

SourceTree

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

введите описание изображения здесь

Przemek Struciński
источник
0

Я использовал @Robin answer & перечисление всего, что я сделал,

git status                               <-- review/list uncommitted changes
git stash                                <-- stash uncommitted changes
git stash branch <new-branch> stash@{1}  <-- create a branch from stash
git add .                                <-- add local changes
git status                               <-- review the status; ready to commit
git commit -m "local changes ..."        <-- commit the changes
git branch --list                        <-- see list of branches incl the one created above
git status                               <-- nothing to commit, working tree (new-branch) is clean
git checkout <old-branch>                <-- switch back

! Если в репо более одного тайника, посмотрите, какой из них применить к новой ветке:

git stash list  
  stash@{0}: WIP on ...  
  stash@{1}: WIP on ...

и осмотреть индивидуальный тайник,

git stash show stash@{1}

Или проверить все тайники одновременно:

git stash list -p
NBhat
источник