Как изменить более старый Git commit?
Я сделал 3 git совершает, но не был нажат.
Как изменить старый (ddc6859af44) и (47175e84c), который не является последним?
$git log
commit f4074f289b8a49250b15a4f25ca4b46017454781
Date: Tue Jan 10 10:57:27 2012 -0800
commit ddc6859af448b8fd2e86dd0437c47b6014380a7f
Date: Mon Jan 9 16:29:30 2012 -0800
commit 47175e84c2cb7e47520f7dde824718eae3624550
Date: Mon Jan 9 13:13:22 2012 -0800
Ответы
Ответ 1
git rebase -i HEAD^^^
Теперь отметьте те, которые вы хотите изменить, с помощью edit
или e
(замените pick
). Теперь сохраните и выйдите.
Теперь внесите изменения, затем
git add -A
git commit --amend --no-edit
git rebase --continue
Если вы хотите добавить дополнительное удаление, удалите параметры из команды commit. Если вы хотите настроить сообщение, опустите только параметр --no-edit
.
Ответ 2
Я подготовил свой коммит, который я хотел внести с более старым, и был удивлен, увидев, что rebase -i жаловался, что у меня есть незафиксированные изменения. Но я не хотел, чтобы мои изменения снова указывали параметр редактирования старшего коммита. Таким образом, решение было довольно простым и понятным:
- подготовьте свое обновление к старшему, добавьте его и выполните
-
git rebase -i <commit you want to amend>^
- обратите внимание на ^
, чтобы вы увидели указанную фиксацию в текстовом редакторе
-
вы получите следующее:
pick 8c83e24 use substitution instead of separate subsystems file to avoid jgroups.xml and jgroups-e2.xml going out of sync
pick 799ce28 generate ec2 configuration out of subsystems-ha.xml and subsystems-full-ha.xml to avoid discrepancies
pick e23d23a fix indentation of jgroups.xml
-
Теперь для объединения e23d23a с 8c83e24 вы можете изменить порядок строк и использовать сквош следующим образом:
pick 8c83e24 use substitution instead of separate subsystems file to avoid jgroups.xml and jgroups-e2.xml going out of sync
squash e23d23a fix indentation of jgroups.xml
pick 799ce28 generate ec2 configuration out of subsystems-ha.xml and subsystems-full-ha.xml to avoid discrepancies
-
напишите и выйдите из файла, вы будете вместе с редактором, чтобы объединить сообщения фиксации. Сделайте это и сохраните/выйдите из текстового документа
- Вы закончили, ваши изменения изменены.
кредит идет на: http://git-scm.com/book/en/Git-Tools-Rewriting-History
Там также есть полезная продемонстрированная магия git.
Ответ 3
Вы можете использовать git rebase
для перезаписи истории фиксации. Это может быть потенциально разрушительным для ваших изменений, поэтому используйте с осторожностью.
Сначала сделайте свое изменение "изменить" как обычное совершение. Затем выполните интерактивную переадресацию, начиная с родителя вашей старой фиксации
git rebase -i 47175e84c2cb7e47520f7dde824718eae3624550^
Это запустит ваш редактор со всеми фиксациями. Измените порядок, чтобы ваше "исправление" совершалось ниже того, которое вы хотите изменить. Затем замените первое слово в строке на "commit" commit с помощью s
, которое объединит ( s quash) его с фиксацией раньше. Сохраните и выйдите из редактора и следуйте инструкциям.
Ответ 4
Вы можете использовать git rebase --interactive
, используя команду edit
для фиксации, которую вы хотите изменить.
Ответ 5
Я использовал другой способ несколько раз. Фактически, это руководство git rebase -i
, и оно полезно, если вы хотите переставить несколько коммитов, включая раздавливание или разделение некоторых из них. Главное преимущество заключается в том, что вам не нужно принимать решение о каждой совершении судьбы в один момент. Вы также будете иметь все функции Git, доступные во время процесса, в отличие от во время переустановки. Например, вы можете в любое время отобразить журнал как исходной, так и перезаписанной истории или даже выполнить другую перезагрузку!
Я буду ссылаться на коммиты следующим образом, поэтому легко читаем:
C # good commit after a bad one
B # bad commit
A # good commit before a bad one
Ваша история в начале выглядит следующим образом:
x - A - B - C
| |
| master
|
origin/master
Мы воссоздаем его таким образом:
x - A - B*- C'
| |
| master
|
origin/master
Это процедура:
git checkout B # get working-tree to the state of commit B
git reset --soft A # tell git that we are working before commit B
git checkout -b rewrite-history # switch to a new branch for our alternative history
Улучшите свою старую фиксацию с помощью git add
(git add -i
, git stash
и т.д.). Вы можете даже разделить свою старую фиксацию на две или более.
git commit # recreate commit B (result = B*)
git cherry-pick C # copy C to our new branch (result = C')
Промежуточный результат:
x - A - B - C
| \ |
| \ master
| \
| B*- C'
| |
| rewrite-history
|
origin/master
Пусть заканчивается:
git checkout master
git reset --hard rewrite-history # make this branch master
Чтобы это, вы можете push
продвигаться вперед.
Ответ 6
В случае, если OP хочет выжать 2 коммиты, указанные в 1, вот альтернативный способ сделать это без перезагрузки
git checkout HEAD^ # go to the first commit you want squashed
git reset --soft HEAD^ # go to the second one but keep the tree and index the same
git commit --amend -C [email protected]{1} # use the message from first commit (omit this to change)
git checkout [email protected]{3} -- . # get the tree from the commit you did not want to touch
git add -A # add everything
git commit -C [email protected]{3} # commit again using the message from that commit
Синтаксис @{N)
удобен, так как он позволит вам ссылаться на историю того, где были ваши ссылки. В этом случае это HEAD, который представляет вашу текущую фиксацию.