Объединить первые две фиксации репозитория Git?
Предположим, у вас есть история, содержащая три коммита A, B и C:
A-B-C
Я хотел бы объединить два коммита A и B в один коммит AB:
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
Is есть способ или это просто невозможно?
7 ответов:
использовать
git rebase -i --rootкак из Git версия 1.7.12.в интерактивном файле rebase измените вторую строку commit B до сквош и оставьте остальные строки в 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 commits-это целые деревья, а не различия, даже если они обычно описываются и рассматриваются с точки зрения различий, которые они вводят.этот рецепт работает, даже если есть несколько коммитов между 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может быть непрактичным и медленным, просто из-за большого количества коммитов, которые должен обрабатывать скрипт rebase два раза, один раз для создания интерактивного списка редакторов перебазирования (где вы выбираете, какое действие предпринять для каждого коммита), и один раз для фактического выполнения повторного применения коммитов.
здесь альтернатива решение это позволит избежать затрат времени на создание интерактивного списка редакторов rebase не используя интерактивный перебазирования в первую очередь. Таким образом, это похоже на решение Чарльза Бейли. Вы просто создаете сиротского отделения из второго коммита, а затем перебазировать все потомки коммитов поверх него:
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 checkout -b a A git checkout B <files> git commit --amend git checkout master git rebase aЭто должно оставить вас с веткой, которая имеет AB и C в качестве коммитов.
Comments