Вопрос

Предположим, у вас есть история, содержащая три коммита. А, Б и С:

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 являются коммитами.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top