마지막 X 커밋을 Git을 사용하여 하나의 커밋으로 어떻게 스쿼시 할 수 있습니까?
답변
매뉴얼에git rebase -i <after-this-commit>
설명 된대로 두 번째 및 후속 커밋에서 “pick”을 사용 하고 “squash”또는 “fixup”으로 바꿉니다 .
이 예에서, <after-this-commit>
rebase 명령에 대한 커밋이 분석되는 현재 분기의 HEAD로부터의 SHA1 해시 또는 상대 위치입니다. 예를 들어, 사용자가 과거에 현재 HEAD에서 5 개의 커밋을 보려면 명령은 git rebase -i HEAD~5
입니다.
답변
git rebase
또는 없이이 작업을 상당히 쉽게 수행 할 수 있습니다 git merge --squash
. 이 예에서는 마지막 3 개의 커밋을 스쿼시합니다.
새로운 커밋 메시지를 처음부터 작성하려면 다음과 같이 충분합니다.
git reset --soft HEAD~3 &&
git commit
기존 커밋 메시지를 연결하여 새 커밋 메시지 편집을 시작하려면 (예 : pick / squash / squash /… / squash git rebase -i
명령어 목록 과 유사 ) 해당 메시지를 추출하여 전달해야합니다. 그들에게 git commit
:
git reset --soft HEAD~3 &&
git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})"
이 두 가지 방법 모두 마지막 3 개의 커밋을 같은 방식으로 하나의 새로운 커밋으로 뭉칩니다. 소프트 리셋은 스쿼시하지 않으려는 마지막 커밋으로 HEAD를 다시 가리 킵니다. 소프트 재설정으로 인덱스와 작업 트리를 건드리지 않고 새 커밋에 대해 원하는 상태로 인덱스를 유지합니다 (즉, 이미 “버려 버리려는 커밋의 모든 변경 사항이 이미 있습니다”).
답변
git merge --squash
이보다 약간 더 우아하게 사용할 수 있습니다 git rebase -i
. 당신이 마스터에 있고 마지막 12 개의 커밋을 하나로 묶고 싶다고 가정 해보십시오.
경고 : 먼저 작업을 커밋해야합니다. 단계적이거나 단계적이지 않은 변경 사항을 버릴 git status
것이므로 깨끗한 지 확인하십시오.git reset --hard
그때:
# Reset the current branch to the commit just before the last 12:
git reset --hard HEAD~12
# HEAD@{1} is where the branch was just before the previous command.
# This command sets the state of the index to be as it would just
# after a merge from that commit:
git merge --squash HEAD@{1}
# Commit those squashed changes. The commit message will be helpfully
# prepopulated with the commit messages of all the squashed commits:
git commit
에 대한 문서는git merge
설명 --squash
자세히 옵션을 선택합니다.
업데이트 :git reset --soft HEAD~12 && git commit
Chris Johnsen이 그의 대답 에서 제안한 것보다 더 간단한이 방법의 유일한 장점 은 스쿼시하는 모든 커밋 메시지로 커밋 메시지가 미리 채워져 있다는 것입니다.
답변
git reset
가능하면 특히 Git-novices를 피하는 것이 좋습니다 . 많은 커밋을 기반으로 프로세스를 자동화 해야하는 경우가 아니라면 덜 이국적인 방법이 있습니다 …
- 작업중인 분기에 스쿼시 된 커밋을 넣습니다 (아직없는 경우)-gitk를 사용하십시오.
- 대상 지점을 확인하십시오 (예 : ‘마스터’)
git merge --squash (working branch name)
git commit
커밋 메시지는 스쿼시를 기반으로 미리 채워집니다.
답변
을 바탕으로 크리스 욘센의 대답은 ,
bash에서 전역 “스쿼시”별칭 추가 : (또는 Windows의 Git Bash)
git config --global alias.squash '!f(){ git reset --soft HEAD~${1} && git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})"; };f'
… 또는 Windows 명령 프롬프트 사용 :
git config --global alias.squash "!f(){ git reset --soft HEAD~${1} && git commit --edit -m\"$(git log --format=%B --reverse HEAD..HEAD@{1})\"; };f"
당신은 ~/.gitconfig
지금이 별칭을 포함해야한다 :
[alias]
squash = "!f(){ git reset --soft HEAD~${1} && git commit --edit -m\"$(git log --format=%B --reverse HEAD..HEAD@{1})\"; };f"
용법:
git squash N
… 마지막 N
커밋을 자동으로 묶습니다 .
참고 : 결과 커밋 메시지는 모든 스와치 된 커밋을 순서대로 조합 한 것입니다. 마음에 들지 않으면 언제든지 git commit --amend
수동으로 수정할 수 있습니다. 또는 취향에 맞게 별칭을 편집하십시오.
답변
이 편리한 블로그 게시물 덕분 에이 명령을 사용하여 마지막 3 개의 커밋을 스쿼시 할 수 있음을 발견했습니다.
git rebase -i HEAD~3
추적 정보 / 원격 리포지토리가없는 로컬 지점에 있어도 편리합니다.
이 명령은 대화식 rebase 편집기를 열고 평소대로 재정렬, 스쿼시, 리워드 등을 수행 할 수 있습니다.
대화식 rebase 편집기 사용 :
대화식 rebase 편집기는 마지막 3 개의 커밋을 보여줍니다. 이 제한 조건은 HEAD~3
명령을 실행할 때 결정됩니다 git rebase -i HEAD~3
.
가장 최근의 커밋 HEAD
이 첫 번째 줄에 먼저 표시됩니다.로 시작하는 줄 #
은 주석 / 문서입니다.
표시되는 문서는 매우 명확합니다. 주어진 행 pick
에서 명령을 원하는 명령으로 변경할 수 있습니다 .
fixup
이 명령 은 커밋 변경 사항을 위의 줄에 커밋으로 “제곱”하고 커밋 메시지를 삭제 하기 때문에 명령을 사용하는 것을 선호 합니다.
1 행의 커밋 HEAD
이 대부분이므로 대부분의 경우이를 그대로 둡니다 pick
. 당신은 사용할 수 없습니다 squash
또는 fixup
이 있기 때문에 다른이 (가)에 커밋 스쿼시 것을 약속합니다.
커밋 순서를 변경할 수도 있습니다. 이를 통해 연대순으로 인접하지 않은 커밋을 스쿼시하거나 수정할 수 있습니다.
실용적인 일상 예
최근에 새로운 기능을 커밋했습니다. 그 이후로 두 가지 버그 수정을했습니다. 그러나 이제는 내가 저지른 새로운 기능에서 버그 (또는 철자 오류)를 발견했습니다. 짜증나! 커밋 기록을 오염시키는 새로운 커밋을 원하지 않습니다!
내가하는 첫 번째 일은 실수를 고치고 코멘트로 새로운 커밋을하는 것 squash this into my new feature!
입니다.
그런 다음 새로운 기능 (이 경우 ) 의 커밋 SHA 를 실행 git log
하거나 gitk
얻습니다 1ff9460
.
다음으로를 사용하여 대화식 rebase 편집기를 불러옵니다 git rebase -i 1ff9460~
. ~
커밋 후 SHA 편집기에서 커밋이 포함 편집기를 알려줍니다.
다음으로 수정 ( fe7f1e0
)이 포함 된 커밋을 기능 커밋 아래 로 이동 하고로 변경 pick
합니다 fixup
.
편집기를 닫을 때 수정 사항이 기능 커밋으로 찌그러지고 커밋 기록이 멋지고 깨끗하게 보입니다!
이것은 모든 커밋이 로컬 인 경우 잘 작동하지만 이미 원격으로 푸시 된 커밋을 변경하려고하면 동일한 분기를 체크 아웃 한 다른 개발자에게 실제로 문제가 발생할 수 있습니다!