Я пытаюсь выкачать ряд коммитов - HEAD HEAD ~ 3. Есть ли быстрый способ сделать это, или мне нужно использовать rebase -interactive?
Есть ли способ раздавить несколько коммитов неинтерактивно?
Ответ 1
Убедитесь, что рабочее дерево чиста, затем
git reset --soft HEAD~3
git commit -m'new commit message'
Ответ 2
Мне лично нравится решение wilhelmtell:
git reset --soft HEAD~3
git commit -m 'new commit message'
Однако я сделал псевдоним с некоторой проверкой ошибок, чтобы вы могли это сделать:
git squash 3 'my commit message'
Я рекомендую настраивать псевдонимы, которые фактически запускают скрипты, чтобы было проще (а) кодировать ваши скрипты и (б) выполнять более сложную работу с проверкой ошибок. Ниже приведена script, которая выполняет работу squash, а затем ниже, чем script для настройки ваших псевдонимов git.
Script для раздачи (squash.sh)
#!/bin/bash
#
#get number of commits to squash
squashCount=$1
#get the commit message
shift
[email protected]
#regular expression to verify that squash number is an integer
regex='^[0-9]+$'
echo "---------------------------------"
echo "Will squash $squashCount commits"
echo "Commit message will be '$commitMsg'"
echo "...validating input"
if ! [[ $squashCount =~ $regex ]]
then
echo "Squash count must be an integer."
elif [ -z "$commitMsg" ]
then
echo "Invalid commit message. Make sure string is not empty"
else
echo "...input looks good"
echo "...proceeding to squash"
git reset --soft HEAD~$squashCount
git commit -m "$commitMsg"
echo "...done"
fi
echo
exit 0
Затем, чтобы подключить этот squash.sh script к алиасу git, создайте еще один script для настройки ваших псевдонимов git, подобных этому (create_aliases.command или create_aliases.sh):
#!/bin/sh
echo '-----------------------'
echo 'adding git aliases....'
echo '-----------------------'
echo
git config --global alias.squash "!bash -c 'bash <path to scripts directory>/squash.sh \$1 \$2' -"
#add your other git aliases setup here
#and here
#etc.
echo '------------------------------------'
echo 'here is your global gitconfig file:'
echo '------------------------------------'
more ~/.gitconfig
echo
echo
echo '----------------'
echo 'end of script...'
echo '----------------'
Ответ 3
Я использовал:
EDITOR="sed -i '2,/^$/s/^pick\b/s/'" git rebase -i <ref>
Работал неплохо. Просто не пытайтесь иметь журнал фиксации с линией, начинающейся с "pick":)
Ответ 4
Используйте следующую команду для раздачи последних 4 коммитов в течение последнего коммита:
git squash 4
С псевдонимом:
squash = !"f() { NL=$1; GIT_EDITOR=\"sed -i '2,$NL s/pick/squash/;/# This is the 2nd commit message:/,$ {d}'\"; git rebase -i HEAD~$NL; }; f"
sq = !git squash $1
sqpsf = !git squash $1 && git psf
Из https://github.com/brauliobo/gitconfig/blob/master/configs/.gitconfig
Ответ 5
Чтобы добавить к ответу wilhelmtell, я нахожу удобным мягкое reset для HEAD ~ 2, а затем изменяет фиксацию HEAD ~ 3:
git reset --soft HEAD~2
git commit --all --amend --no-edit
Это слияние всех коммитов с фиксацией HEAD ~ 3 и использование сообщения commit. Обязательно начинайте с чистого рабочего дерева.
Ответ 6
Вот один лайнер для сквоша последних двух коммитов. В этом примере сообщение второго последнего фиксации будет сохранено. Вы можете изменить сообщение, как пожелаете.
git commit -am "$(git log -1 --skip=1 --pretty=%B | xargs && git reset --soft HEAD~2)"
Эта команда будет очень полезна, если вы создадите псевдоним для этой команды и вместо этого используйте псевдоним.
Ответ 7
Вы можете получить довольно близко с
git rebase --onto HEAD~4 HEAD~ master
Это предполагает, что вы находитесь на главном с линейной историей. Это не совсем сквош, потому что он отбрасывает промежуточные коммиты. Вам нужно будет изменить новый HEAD, чтобы изменить сообщение фиксации.