Как раздавить коммиты в git после того, как их толкнули? - PullRequest
471 голосов
/ 14 апреля 2011

Это дает хорошее объяснение раздавливания нескольких коммитов:

http://git -scm.com / книга / а / Гит-Ветвление-перебазирование

но он не работает для коммитов, которые уже были переданы. Как раздавить последние несколько коммитов как в локальном, так и в удаленном репо?

РЕДАКТИРОВАНИЕ: Когда я делаю git rebase -i origin/master~4 master, оставляю первый как pick, устанавливаю остальные три как squash, а затем выхожу (через cx cc в emacs), я получаю:

$ git rebase -i origin/master~4 master
# Not currently on any branch.
nothing to commit (working directory clean)

Could not apply 2f40e2c... Revert "issue 4427: bpf device permission change option added"
$ git rebase -i origin/master~4 master
Interactive rebase already started

, где 2f40 - коммит pick. И теперь ни один из 4 коммитов не появляется в git log. Я ожидал, что мой редактор будет перезапущен, чтобы я мог ввести сообщение коммита. Что я делаю не так?

Ответы [ 7 ]

659 голосов
/ 14 апреля 2011

Сквош фиксирует локально с

git rebase -i origin/master~4 master

и затем принудительно нажмите

git push origin +master

Разница между --force и +

Из документации git push:

Обратите внимание, что --force применяется ко всем ссылкам, которые выдвигаются, следовательно, используя с push.default, установленным на matching или с многократным нажатием адресаты, настроенные с remote.*.push, могут перезаписывать ссылки на другие чем текущая ветвь (включая местные ссылки, которые строго позади их удаленный аналог). Чтобы форсировать толчок только к одной ветви, используйте + перед refspec, чтобы нажать (например, git push origin +master, чтобы заставить толчок к ветке master).

94 голосов
/ 16 сентября 2015

На ветке я смог сделать это так (за последние 4 коммита)

git checkout my_branch
git reset --soft HEAD~4
git commit
git push --force origin my_branch
21 голосов
/ 22 декабря 2017

Незначительная разница с принятым ответом, но у меня было много трудностей при раздавливании, и я наконец получил его.

$ git rebase -i HEAD~4
  • На открывшемся интерактивном экране замените pick на squash вверху для всех коммитов, которые вы хотите раздавить.
  • Сохраните и закройте редактор через esc --> :wq

Нажмите на пульт, используя:

$ git push origin branch-name --force
20 голосов
/ 05 сентября 2016

Множество проблем можно избежать, только создав branch для работы, а не для работы master:

git checkout -b mybranch

Следующие работы для remote коммитов уже выдвинуты и смесь remote пушит коммитов / local только коммиты:

# example merging 4 commits

git checkout mybranch
git rebase -i mybranch~4 mybranch

# at the interactive screen
# choose fixup for commit: 2 / 3 / 4

git push -u origin +mybranch

У меня также есть примечания к запросу на извлечение , которые могут быть полезны.

12 голосов
/ 26 сентября 2017

git rebase -i master

вы откроете редактор vm и увидите что-то вроде этого

Pick 2994283490 commit msg1
f 7994283490 commit msg2
f 4654283490 commit msg3
f 5694283490 commit msg4
#Some message 
#
#some more

Здесь я изменил выбор для всех других коммитов на "f" (стоит дляfixup).

git push -f origin feature/feature-branch-name-xyz

это исправит все коммиты в одном коммите и удалит все остальные коммиты.Я сделал это, и это помогло мне.

0 голосов
/ 07 января 2019

1) git rebase -i HEAD ~ 4

To elaborate: It works on the current branch; the HEAD~4 means squashing the latest four commits; interactive mode (-i)

2) В этот момент редактор открыл со списком коммитов, чтобы изменить второй и последующие коммиты, заменив pick на squash и сохранив его.

вывод: успешно перебазирован и обновлен refs / heads / branch-name.

3) git push origin refs / Heads / Branch-Name --force

Выход: ... дистанционный пульт: remote: чтобы создать запрос на слияние для имени филиала, посетите: дистанционный: http://xxx/sc/server/merge_requests/new?merge_request%5Bsource_branch%5D=sss удаленный: для ip: sc / server.git + 84b4b60 ... 5045693 имя-ветви -> имя-ветви (принудительное обновление)

0 голосов
/ 23 октября 2018

Для сжатия двух коммитов, один из которых уже был выдвинут, в одной ветке сработало следующее:

git rebase -i HEAD~2
    [ pick     older-commit  ]
    [ squash   newest-commit ]
git push --force

По умолчанию это будет включать в себя сообщение о коммите самого нового коммита в качестве комментария кболее старый коммит.

...