답변:
작업 트리가 깨끗한 지 확인한 다음
git reset --soft HEAD~3
git commit -m 'new commit message'
git reset --soft HEAD~3 && git commit -m "my message"
git config alias.mysquash '!f(){ git reset --soft HEAD~$1 && git commit ${2:+-m "$2"}; };f'
. git mysquash 3 'some message'
작동하지만, 나는 또한 그것을 조정 git musquash 3
하여 -m 플래그를 완전히 생략 하여이 git commit
경우 대화 형 UI를 얻을 수 있습니다.
개인적으로 Wilhelmtell의 솔루션을 좋아 합니다.
git reset --soft HEAD~3
git commit -m 'new commit message'
그러나 몇 가지 오류 검사로 별칭을 만들었습니다.
git squash 3 'my commit message'
(a) 스크립트를 코딩하고 (b) 오류 검사로 더 복잡한 작업을 수행하기 쉽도록 실제로 스크립트를 실행하는 별칭을 설정하는 것이 좋습니다. 아래는 스쿼시 작업을 수행하는 스크립트이고 그 아래는 git 별칭을 설정하는 스크립트입니다.
스쿼 싱용 스크립트 (squash.sh)
#!/bin/bash
#
#get number of commits to squash
squashCount=$1
#get the commit message
shift
commitMsg=$@
#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 스크립트를 git 별칭 에 연결하려면 다음 과 같이 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 '----------------'
$PATH
named에 넣을 수 git-squash.sh
있으며 자동으로 별칭이 지정됩니다 git squash
. 내가 알지 못하는 create-aiases.sh
스크립트 를 사용할 이유가있는 경우를 대비하여 답변을 변경하지 않았습니다 .
wilhelmtell 의 답변에 추가하려면 소프트 재설정 HEAD~2
한 다음 커밋을 수정하는 것이 편리합니다 HEAD~3
.
git reset --soft HEAD~2
git commit --all --amend --no-edit
이것은 모든 커밋을 커밋에 병합 HEAD~3
하고 커밋 메시지를 사용합니다. 깨끗한 작업 트리에서 시작하십시오.
나는 다음을 사용했다 :
EDITOR="sed -i '2,/^$/s/^pick\b/s/'" git rebase -i <ref>
아주 잘 작동했습니다. "pick"으로 시작하는 줄이있는 커밋 로그를 만들려고하지 마십시오. :)
다음 명령을 사용하여 마지막 커밋 내에서 마지막 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
브랜치가 마스터에서 분기 된 이후 모든 것을 스쿼시하려면 :
git reset --soft $(git merge-base --fork-point master) \
&& git commit --verbose --reedit-message=HEAD --reset-author
--reedit-message=HEAD
스 쿼싱의 일부가 아닌 마지막 커밋 의 메시지를 사용합니다 . 이것은 당신이 원하는 것이 아닐 것입니다. 오히려의 메시지를 얻으려면 먼저 포함되어야 할 것을 약속 하거나, (1) 대체 HEAD
당신은의 메시지, 또는 원하는 커밋의 해시 (2) (가) 먼저 포함되어야 커밋에 점프를 git commit --amend --reedit-message=HEAD
. 이것이 조화로운 대답이하는 일입니다.
당신은 꽤 가까워 질 수 있습니다
git rebase --onto HEAD ~ 4 HEAD ~ master
이것은 당신이 선형 역사를 가진 마스터라고 가정합니다. 중간 커밋을 버리기 때문에 스쿼시가 아닙니다. 커밋 메시지를 수정하려면 새 HEAD를 수정해야합니다.
HEAD~4
은 상위 HEAD로 다시 작성되기 때문에 이전 HEAD와 마찬가지로 가비지가 됩니다.