В настоящее время я работаю над веткой и хочу, чтобы некоторые коммиты слились с другими ветвями:
a-b-c-d-e-f-g (branchA)
/
--o-x-x-x-x-x-x-x-x-x-x (master)
\
x-x-x-x-x (branchB)
(Буквы обозначают коммиты, а «x» - нерелевантные коммиты.)
Однако я заметил, что было бы неплохо объединить несколько коммитов. Я хочу «объединить» коммиты a, d, e и g в один патч и передать его мастеру. Коммиты b и f должны идти как одна фиксация в BranchB. Есть ли хороший мерзкий способ добиться этого?
Ответы:
Команда, которую вы ищете, - это
git rebase
, в частности,-i/--interactive
опция.Я собираюсь предположить, что вы хотите оставить фиксацию c в ветке A, и что вы действительно имеете в виду, что хотите переместить другие коммиты в другие ветки, а не слияние, поскольку слияние выполняется просто. Начнем с манипулирования веткой A.
Это
^
означает предыдущую фиксацию, поэтому эта команда говорит, что нужно перебазировать ветку A, используя фиксацию перед «a» в качестве основы. Git представит вам список коммитов в этом диапазоне. Измените их порядок и скажите git раздавить подходящие:Теперь история должна выглядеть так:
Теперь давайте возьмем только что сжатый коммит b + f для branchB.
И то же самое для a + d + e + g для master:
Наконец, обновите branchA, чтобы он указывал на c:
Теперь у нас должно быть:
Обратите внимание, что если у вас было несколько коммитов, которые вы хотели перемещать между ветвями, вы можете снова использовать rebase (не интерактивно):
Наконец, отказ от ответственности: вполне возможно изменить порядок коммитов таким образом, чтобы некоторые из них перестали применяться чисто. Это могло произойти из-за того, что вы выбрали неверный порядок (установка патча перед фиксацией, представляющая исправленную функцию); в этом случае вы захотите отменить rebase (
git rebase --abort
). В противном случае вам придется разумно исправить конфликты (как и в случае конфликтов слияния), добавить исправления, а затем запустить,git rebase --continue
чтобы двигаться дальше. Эти инструкции также содержатся в сообщении об ошибке, которое печатается при возникновении конфликта.источник
git branch -f branchA branchA^^
неправильная? А именно, не следует ли branchA указывать на c в этой точке, чтобы первая строка диаграммы была,c (branchA)
а неc - [a+d+e+g] - [b+f] (branchA)
?git branch -f branchA branchA^^
почему вы не можете просто сделать вgit reset --hard <sha1 of c>
ветке A?Где
3
количество коммитов, которые нужно переупорядочить ( источник ).Это откроет vi , в котором перечислены коммиты от самых старых (вверху) до самых новых (внизу).
Теперь измените порядок строк, сохраните и выйдите из редактора.
ddp
переместит текущую строку внизddkP
переместит текущую строку вверх ( источник )источник
git rebase --interactive
это та команда, которую вы хотите.Пример:
Текущий статус таков:
Я хочу изменить порядок
9a24b81
коммитов (Третья фиксация) и7bdfb68
(Вторая фиксация). Для этого я сначала нахожу коммит перед первым коммитом, который мы хотим изменить . Это фиксация186d1e0
(первая фиксация).В
git rebase --interactive COMMIT-BEFORE-FIRST-COMMIT-WE-WANT-TO-CHANGE
этом случае команда для выполнения :В редакторе по умолчанию откроется файл со следующим содержимым:
Обратите внимание, что порядок коммитов в файле противоположен тому, который используется для журнала git. В журнале git самая последняя фиксация находится вверху. В этом файле самая последняя фиксация находится внизу.
Как поясняется в комментарии внизу файла, я могу делать разные вещи, например сдавливать, отбрасывать и переупорядочивать коммиты. Чтобы изменить порядок коммитов, я редактирую файл так, чтобы он выглядел так (нижние комментарии не отображаются):
Команда
pick
в начале каждой строки означает «использовать (т.е. включить) эту фиксацию», и когда я сохраню временный файл с командами rebase и выйду из редактора, git выполнит команды и обновит репозиторий и рабочий каталог:Обратите внимание на переписанную историю коммитов.
Ссылки:
источник
git rebase --interactive
для достижения цели OP?Если вы хотите изменить порядок только последних двух коммитов , вы можете использовать этот
git reorder
псевдоним: https://stackoverflow.com/a/33388211/338581источник
git rebase - это то, что вы хотите. Обратите внимание на опцию --interactive.
источник