Объединить все изменения из другой ветки в один коммит
В Git есть ли способ слить все изменения из одной ветки в другую, но сквош в одну фиксацию одновременно?
Я часто работаю над новой функцией в отдельной ветке и буду регулярно совершать/нажимать - в основном для резервного копирования или для передачи того, что я работаю на другой машине. В основном эти коммиты говорят "Feature xxx WIP" или что-то лишнее.
Как только эта работа будет завершена, и я хочу объединить ветвь WIP обратно в master, я бы хотел отбросить все эти промежуточные коммиты и просто иметь чистую фиксацию.
Есть ли простой способ сделать это?
В качестве альтернативы, как насчет команды, которая выкалывает все фиксации на ветке с точки, где она была разветвленной?
Ответы
Ответ 1
Другим вариантом является git merge --squash <feature branch>
затем, наконец, выполните git commit
.
Из Git слияния
--squash
--no-squash
Создайте рабочее дерево и состояние индекса, как если бы произошло реальное слияние (за исключением информации о слиянии), но на самом деле не выполняйте коммит, не перемещайте HEAD
и не записывайте $GIT_DIR/MERGE_HEAD
чтобы следующая команда git commit
создала слияние совершить. Это позволяет вам создать один коммит поверх текущей ветки, эффект которого такой же, как и слияние другой ветки (или более в случае осьминога).
Ответ 2
Нашел! Команда Merge имеет параметр --squash
git checkout master
git merge --squash WIP
в этот момент все сливается, возможно, конфликтует, но не совершается. Теперь я могу:
git add .
git commit -m "Merged WIP"
Ответ 3
Попробуйте git rebase -i master
в вашей ветке функций. Затем вы можете изменить все, кроме одного "выбрать", чтобы "сквош", чтобы комбинировать коммиты. См. squashing commits with rebase
Наконец, вы можете выполнить слияние с главной ветвью.
Ответ 4
Я создал свой псевдоним git, чтобы сделать именно это. Я называю это git freebase
! Он возьмет существующую грязную ветвь объектов без возможности восстановления и создаст ее заново, чтобы она стала новой веткой с тем же именем, а ее коммиты будут сжаты в один коммит и перенесены в указанную вами ветвь (по умолчанию master). В самом конце, это позволит вам использовать любое сообщение коммита, которое вам нравится, для вашей новой "бесплатной" ветки.
Установите его, поместив следующий псевдоним в ваш .gitconfig:
[alias]
freebase = "!f() { \
TOPIC="$(git branch | grep '\\*' | cut -d ' ' -f2)"; \
NEWBASE="${1:-master}"; \
PREVSHA1="$(git rev-parse HEAD)"; \
echo "Freebaseing $TOPIC onto $NEWBASE, previous sha1 was $PREVSHA1"; \
echo "---"; \
git reset --hard "$NEWBASE"; \
git merge --squash "$PREVSHA1"; \
git commit; \
}; f"
Используйте его из своей ветки функций, выполнив: git freebase <new-base>
Я проверял это всего несколько раз, поэтому сначала прочтите его и убедитесь, что вы хотите запустить его. В качестве небольшой меры безопасности он печатает начальный sha1, чтобы вы могли восстановить старую ветку, если что-то пойдет не так.
Я буду поддерживать его в моем репозитории dotfiles на github: https://github.com/stevecrozz/dotfiles/blob/master/.gitconfig
Ответ 5
git merge --squash <feature branch>
- хороший вариант. "git commit" сообщает вам все сообщения о фиксации ветки объекта с вашим выбором, чтобы сохранить его.
За меньшее слияние.
git merge
do x times - git reset HEAD ^ --soft
затем git commit.
Риск-удаленные файлы могут вернуться.
Ответ 6
Я хотел раздавить все коммиты в моем хозяине в одном. Я пробовал это безуспешно:
$ git checkout --orphan new_master
$ git merge --squash master
fatal: Squash commit into empty head not supported yet
Итак, я сделал это:
$ tar cf /tmp/git.tar --exclude .git .
$ git checkout --orphan new_master
$ tar xf /tmp/git.tar
$ git commit -m "Initial commit"
который работал красиво.
Ответ 7
Вы можете сделать это с помощью команды "rebase". Позвольте называть ветки "основной" и "особенностью":
git checkout feature
git rebase main
Команда rebase будет воспроизводить все коммиты на "функции" как одну фиксацию с родительским, равным "main".
Возможно, вы захотите запустить git merge main
до git rebase main
, если "main" изменилось с момента создания "функции" (или с момента последнего слияния). Таким образом, у вас все еще есть полная история, если у вас возник конфликт слияния.
После перезагрузки вы можете объединить свою ветку на главную, что должно привести к ускоренному слиянию:
git checkout main
git merge feature
См. rebase страница Понимание Git Концептуально для хорошего обзора