Git rebase interactive: squash merge объединяется вместе
Я хотел иметь простое решение для сквоша двух компиляций вместе во время интерактивной перезагрузки.
Мой репозиторий выглядит так:
X --- Y --------- M1 -------- M2 (my-feature)
/ / /
/ / /
a --- b --- c --- d --- e --- f (stable)
То есть, у меня есть ветвь my-feature
, которая была недавно объединена, без каких-либо реальных коммитов между ними. Я не просто хочу переустанавливать ветвь my-feature
, так как это отдельная опубликованная ветвь, я просто хочу скворовать последние два комманда слияния в один (еще не опубликовали эти коммиты)
X --- Y ---- M (my-feature)
/ /
/ /
a --- ... -- f (stable)
Я пробовал:
git rebase -p -i M1^
Но я получил:
Refusing to squash a merge: M2
Что я наконец сделал:
git checkout my-feature
git reset --soft HEAD^ # remove the last commit (M2) but keep the changes in the index
git commit -m toto # redo the commit M2, this time it is not a merge commit
git rebase -p -i M1^ # do the rebase and squash the last commit
git diff M2 HEAD # test the commits are the same
Теперь новый компилятор слияния больше не считается компиляцией (он сохранил только первого родителя). Итак:
git reset --soft HEAD^ # get ready to modify the commit
git stash # put away the index
git merge -s ours --no-commit stable # regenerate merge information (the second parent)
git stash apply # get the index back with the real merge in it
git commit -a # commit your merge
git diff M2 HEAD # test that you have the same commit again
Но это может усложниться, если у меня много коммитов, есть ли у вас лучшее решение?
Спасибо.
Милдред
Ответы
Ответ 1
Это старая тема, но я просто наткнулся на нее, ища аналогичную информацию.
Тройка, аналогичная описанной в Subtree octopus merge, является действительно хорошим решением для этого типа проблем:
git checkout my-feature
git reset --soft Y
git rev-parse f > .git/MERGE_HEAD
git commit
Это займет индекс, как он существует в конце моей функции, и использовать его для создания нового фиксации с Y, а "f" - вторым родителем. Результат такой же, как если бы вы никогда не выполняли M1, но сразу пошли на выполнение M2.
Ответ 2
если вы не опубликовали последние две транзакции слияния, вы можете сделать reset и простое слияние.
git reset --hard Y
git merge stable
Ответ 3
Я пришел к этой теме, желая раздавить одно объединение слиянием; поэтому мой ответ не так полезен для первоначального вопроса.
X
\
\
a --- b --- c --- M1 (subtree merge)
То, что я хотел, состояло в том, чтобы скомпилировать M1-слияние и скворовать все как одну фиксацию поверх b.
a --- b --- S (include the changes from c, X and M1)
Я пробовал всевозможные комбинации, но это то, что сработало:
git checkout -b rebase b (checkout a working branch at point b)
git merge --squash M1
Это применит изменения к индексу, где они могут быть совершены git commit
Ответ 4
Ни один из указанных методов не работает для меня с недавней версией git. В моем случае следующее выполнило трюк:
git reset --soft Y
git reset --hard $(git commit-tree $(git write-tree) -p HEAD -p stable < commit_msg)
Сначала вам нужно записать сообщение фиксации в файл commit_msg.