Как я могу разделить коммит Git, похороненный в истории? - PullRequest
288 голосов
/ 29 ноября 2010

Я разболтал свою историю и хочу внести в нее некоторые изменения.Проблема в том, что у меня есть коммит с двумя несвязанными изменениями, и этот коммит окружен некоторыми другими изменениями в моей локальной (не выдвинутой) истории.но большинство руководств, которые я вижу, имеют отношение к разделению вашего последнего коммита или незафиксированных локальных изменений.Возможно ли сделать это с коммитом, который немного утопает в истории, без необходимости «заново делать» мои коммиты с тех пор?

Ответы [ 4 ]

440 голосов
/ 29 ноября 2010

Существует руководство по разбиению коммитов на справочной странице rebase .Краткая сводка:

  • Выполните интерактивное обновление, включая целевой коммит (например, git rebase -i <commit-to-split>^ branch), и отметьте его для редактирования.

  • Когда перебазирование достигнет этого коммита, используйте git reset HEAD^ для сброса до коммита, но сохраняйте свое рабочее дерево нетронутым.

  • Постепенно добавляйте изменения и фиксируйте их, делая столько коммитов, сколько необходимо,add -p может быть полезно добавить только некоторые изменения в данном файле.Используйте commit -c ORIG_HEAD, если вы хотите повторно использовать исходное сообщение о фиксации для определенного коммита.

  • Если вы хотите проверить, что вы делаете (хорошоидея!) используйте git stash, чтобы скрыть часть, которую вы не зафиксировали (или stash --keep-index, прежде чем вы даже ее подтвердите), протестируйте, затем git stash pop, чтобы вернуть остальное в рабочее дерево.Продолжайте делать коммиты до тех пор, пока не получите все коммиты изменений, т. Е. Получите чистое рабочее дерево.

  • Запустите git rebase --continue, чтобы продолжить применение коммитов после теперь разделенного коммита.

2 голосов
/ 12 ноября 2018

Вот как это сделать с Magit .

Скажите, что вы хотите изменить ed417ae;он содержит два несвязанных изменения и скрывается под одним или несколькими коммитами.Нажмите ll, чтобы отобразить журнал, и перейдите к ed417ae:

initial log

Затем нажмите r, чтобы открыть всплывающее окно rebase

rebase popup

и m для изменения фиксации в точке.

Обратите внимание, что * * * * * * * * * * * * * * * * * * * * * * * * * * *

* 10 28

Обратите внимание на то, что * * * * * * * * *1026* теперь есть в коммите, который вы хотите разделить.

Мы хотим переместить HEAD к родителю, поэтому перейдите к родителю (47e18b3) и нажмите x (magit-reset-quickly, привязанный к o, если вы используете evil-magit), и введите, чтобы сказать "да"Я имел в виду совершить в точке ".Теперь ваш журнал должен выглядеть следующим образом:

log after resetting

Теперь нажмите q, чтобы перейти к обычному статусу Magit, затем используйте обычную нестабильность uвведите команду unstatage, что не происходит в первом коммите, выполните коммит c как обычно, затем s tage и c опустите то, что происходит во втором коммите, и когда закончите: нажмите r, чтобы открытьвсплывающее окно

rebase popup

и еще один r для продолжения, и все готово!ll теперь показывает:

all done log

1 голос
/ 03 октября 2018

Чтобы разделить коммит <commit> и добавить новый коммит перед этим и сохранить дату автора <commit>, - выполните следующие действия:

  1. Изменить коммит до <commit>

    git rebase -i <commit>^^
    

    Примечание: возможно, также потребуется отредактировать <commit>.

  2. Вишневый кир <commit> в указатель

    git cherry-pick -n <commit>
    
  3. Интерактивный сброс ненужных изменений из индекса и сброс рабочего дерева

    git reset -p && git checkout-index -f -a
    

    В качестве альтернативы просто скопируйте ненужные изменения в интерактивном режиме: git stash push -p -m "tmp other changes"

  4. Внести другие изменения (если есть) и создать новый коммит

    git commit -m "upd something" .
    

    При желании повторите пункты 2-4, чтобы добавить дополнительные промежуточные коммиты.

  5. Продолжить ребазинг

    git rebase --continue
    
0 голосов
/ 29 ноября 2010

Если вы еще не нажали, просто используйте git rebase. Более того, используйте git rebase -i для интерактивного перемещения коммитов. Вы можете переместить нарушающий коммит на передний план, затем разделить его, как вам нравится, и переместить патчи назад (при необходимости).

...