Объединение нескольких коммитов перед нажатием Git

У меня есть куча коммитов в моем локальном репозитории, которые тематически похожи. Я хотел бы объединить их в одну фиксацию до нажатия на удаленный. Как мне это сделать? Я думаю, что rebase делает это, но я не могу понять документы.

Ответ 1

То, что вы хотите сделать, называется "squashing" в git. Есть много вариантов, когда вы делаете это (слишком много?), Но если вы просто хотите объединить все ваши разблокированные коммиты в одну фиксацию, сделайте следующее:

git rebase -i origin/master

Это вызовет ваш текстовый редактор (-i для "интерактивного" ) с файлом, который выглядит следующим образом:

pick 16b5fcc Code in, tests not passing
pick c964dea Getting closer
pick 06cf8ee Something changed
pick 396b4a3 Tests pass
pick 9be7fdb Better comments
pick 7dba9cb All done

Измените все pick на squash (или s), кроме первого:

pick 16b5fcc Code in, tests not passing
squash c964dea Getting closer
squash 06cf8ee Something changed
squash 396b4a3 Tests pass
squash 9be7fdb Better comments
squash 7dba9cb All done

Сохраните файл и выйдите из редактора. Затем откроется другой текстовый редактор, позволяющий объединить сообщения фиксации из всех коммитов в одно большое сообщение фиксации.

Voila! Googling "git squashing" даст вам объяснения всех других доступных вариантов.

Ответ 2

Если у вас есть лоты коммитов, и вы хотите только раздавить последние коммиты Х, найдите идентификатор фиксации комманды, из которого вы хотите начать раздавать, и сделайте

git rebase -i <that_commit_id>

Затем продолжайте, как описано в ответ leopd, изменив все pick на squash es, кроме первого.

Ответ 3

Вы можете сделать это с помощью git rebase -i, передав в ревизии, которую вы хотите использовать как "root":

git rebase -i origin/master

откроет окно редактора, в котором будут показаны все сделанные вами коммиты после последнего фиксации в origin/master. Вы можете отклонить коммиты, сквош-коммит в единую фиксацию или изменить предыдущие фиксации.

Есть несколько ресурсов, которые могут, вероятно, объяснить это лучше, и показать некоторые другие примеры:

http://book.git-scm.com/4_interactive_rebasing.html

и

http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html

- первые две хорошие страницы, которые я мог найти.

Ответ 4

Здесь есть несколько рабочих ответов, но я нашел это самым легким. Эта команда откроет редактор, где вы можете просто заменить pick на squash, чтобы удалить/объединить их в один

git rebase -i HEAD~4

где 4 - количество коммитов, которые вы хотите скворовать в один. Это объясняется здесь.

Ответ 5

Я придумал

#!/bin/sh

message=`git log --format=%B origin..HEAD | sort | uniq | grep -v '^$'`
git reset --soft origin
git commit -m "$message"

Объединяет, сортирует, унифицирует и удаляет пустые строки из сообщения фиксации. Я использую это для локальных изменений в wiki github (используя gollum)

Ответ 6

Вы можете выполнить сквош (join) с помощью Интерактивной Rebase. Существует довольно приятное видео на YouTube, в котором показано, как это сделать в командной строке или SmartGit:

Если вы уже являетесь пользователем SmartGit, вы можете выбрать все свои исходящие коммиты (удерживая клавишу Ctrl) и откройте контекстное меню (щелкните правой кнопкой мыши), чтобы раздавить ваши коммиты.

Это очень удобно:

введите описание изображения здесь

Существует также очень хороший учебник из Atlassian, который показывает, как он работает:

Ответ 7

И мой способ squashing multiple push (возможно, вы переместили в свой филиал много коммитов, и теперь вы хотите сделать запрос на перенос, и вы не хотите загромождать их множеством коммитов, которые у вас уже есть толкнул). То, как я это делаю (никакой другой более простой вариант, насколько я могу судить).

  • Создайте новую ветку ради squash (ветвь из исходной ветки, на которую вы хотите получить запрос).
  • Нажмите вновь созданную ветку.
  • Объединить ветвь с фиксацией (уже нажатой) в новую ветку.
  • Восстановите новую ветку и сквош.
  • Нажмите новую ветку.
  • Создайте новый запрос на перенос для новой ветки, которая теперь имеет одиночную фиксацию.

Пример:

git checkout from_branch_you_wish_to_pull_request_to
git checkout -b new_branch_will_have_single_squashed_commit
git push -u new_branch_will_have_single_squashed_commit
git merge older_branch_with_all_those_multiple_commits
git rebase -i (here you squash)
git push origin new_branch_will_have_single_squashed_commit

Теперь вы можете отправить запрос в from_branch_you_wish_to_pull_request_to

Ответ 8

Вероятно, вы захотите использовать Interactive Rebasing, подробно описанный в этой ссылке.

Вы можете найти другие полезные ресурсы, если вы ищете "git rebase interactive".