Объединить первые два коммита репозитория Git?
-
22-07-2019 - |
Вопрос
Предположим, у вас есть история, содержащая три коммита. А, Б и С:
A-B-C
Я хотел бы объединить два коммита А и Б к одному коммиту АБ:
AB-C
Я пытался
git rebase -i A
который открывает мой редактор со следующим содержимым:
pick e97a17b B
pick asd314f C
Я меняю это на
squash e97a17b B
pick asd314f C
Затем Git 1.6.0.4 говорит:
Cannot 'squash' without a previous commit
Есть ли способ или это просто невозможно?
Решение
Используйте git rebase -i --root
с Git версии 1.7.12 . р>
В интерактивном файле rebase измените вторую строку коммита B на squash и оставьте другие строки в pick :
pick f4202da A
squash bea708e B
pick a8c6abc C
Это объединит два коммита A и B в один коммит AB .
Найдено в этом ответе .
Другие советы
Ты пытался:
git rebase -i A
Можно начать так, если продолжить edit
скорее, чем squash
:
edit e97a17b B
pick asd314f C
тогда беги
git reset --soft HEAD^
git commit --amend
git rebase --continue
Сделанный.
A
был начальным коммитом, но теперь вы хотите, чтобы B
был начальным коммитом. Коммиты git - это целые деревья, а не diff-ы, даже если они обычно описываются и рассматриваются в терминах diff, которые они вводят.
Этот рецепт работает, даже если между A и B и B и C имеется несколько коммитов.
# Go back to the last commit that we want
# to form the initial commit (detach HEAD)
git checkout <sha1_for_B>
# reset the branch pointer to the initial commit,
# but leaving the index and working tree intact.
git reset --soft <sha1_for_A>
# amend the initial tree using the tree from 'B'
git commit --amend
# temporarily tag this new initial commit
# (or you could remember the new commit sha1 manually)
git tag tmp
# go back to the original branch (assume master for this example)
git checkout master
# Replay all the commits after B onto the new initial commit
git rebase --onto tmp <sha1_for_B>
# remove the temporary tag
git tag -d tmp
В случае интерактивного перебазирования вы должны сделать это до A, чтобы список был:
pick A
pick B
pick C
стать:
pick A
squash B
pick C
Если A является начальным коммитом, вам нужно будет иметь другой начальный коммит, прежде чем A. Git будет думать о различиях, он будет работать на разнице между (A и B) и (B и C). Следовательно сквош не работает в вашем примере.
Если у вас сотни или тысячи коммитов, используйте ответ Костмо из
git rebase -i --root
может быть непрактичным и медленным просто из-за большого количества коммитов, которые приходится обрабатывать сценарию перебазирования дважды, один раз для создания интерактивного списка редакторов перебазирования (где вы выбираете, какое действие следует предпринять для каждого коммита), и один раз для фактического выполнения повторного применения коммитов.
Вот альтернативное решение это позволит избежать временных затрат на создание списка редакторов интерактивного перебазирования. не используя интерактивную перебазировку в первую очередь.В этом смысле это похоже на Решение Чарльза Бэйли.Вы просто создаете сиротская ветвь из второго коммита, а затем перебазируйте все коммиты-потомки поверх него:
git checkout --orphan orphan <second-commit-sha>
git commit -m "Enter a commit message for the new root commit"
git rebase --onto orphan <second-commit-sha> master
Документация
В связанном вопросе мне удалось придумать другой подход к необходимости раздавливания против первого коммита, то есть сделать его вторым.
Если вам интересно: Git: как вставить коммит в качестве первого, сдвинув все остальные?
Команда Git для отряда:git rebase -i HEAD~[количество коммитов]
Допустим, у вас есть история коммитов git:
выбрать 5152061 подвиг:Добавлена поддержка сохранения изображения.(А)
выберите 39c5a04 Исправление:исправление ошибок.(Б)
выберите исправление 839c6b3:конфликт разрешен.(С)
Теперь вы хотите сжать A и B в AB, выполните следующие шаги:
выбрать 5152061 подвиг:Добавлена поддержка сохранения изображения.(А)
s 39c5a04 Исправление:исправление ошибок.(Б)
выберите исправление 839c6b3:конфликт разрешен.(С)
Примечание:для сжатия коммита мы можем использовать сквош или s.Конечным результатом будет:
выбрать 5152061 подвиг:Добавлена поддержка сохранения изображения.(АБ)
выберите исправление 839c6b3:конфликт разрешен.(С)
Вы должны выполнить немного магии командной строки.
git checkout -b a A
git checkout B <files>
git commit --amend
git checkout master
git rebase a
Это должно оставить вас с веткой, в которой AB и C являются коммитами.