힘내 : 지점에서 모든 커밋을 스쿼시하는 방법


315

나는 다음과 같이 새로운 지점을 만듭니다 master.

git checkout -b testbranch

나는 그것에 20 커밋을합니다.

이제 20 개의 커밋을 스쿼시하고 싶습니다. 나는 그걸로 그렇게한다 :

git rebase -i HEAD~20

커밋이 몇 개인 지 모르면 어떻게해야합니까? 다음과 같은 작업을 수행하는 방법이 있습니까?

git rebase -i all on this branch

6
당신은 할 수 git rebase -i 58333012713fc168bd70ad00d191b3bdc601fa2dcommitnumber가 마지막 어디에 숙박을 커밋 느릅 나무 대화 형 REBASE을 할 것입니다 변경
denns

마지막으로이 방법을 사용 @denns은 리베이스하는 지점에 커밋 에서 환상적인했다. 정말 고마워!
Joshua Pinter

답변:


394

커밋을 모두 없애는 또 다른 방법은 인덱스를 마스터로 재설정하는 것입니다.

 git checkout yourBranch
 git reset $(git merge-base master yourBranch)
 git add -A
 git commit -m "one commit on yourBranch"

"yourBranch"가 어느 지점에서 왔는지 알기 때문에 완벽하지 않습니다.
참고 : Git을 사용 하면 원점을 쉽게 찾을 수 없습니다 ( 여기 에서 볼 수 있듯이 시각적 인 방법이 가장 쉽습니다 ).


편집 : 당신이 사용해야합니다 git push --force


Karlotcha Hoa 는 다음 과 같이 주석을 추가합니다 .

재설정을 위해 할 수있는 일

git reset $(git merge-base master $(git rev-parse --abbrev-ref HEAD)) 

[그것]은 현재있는 지점을 자동으로 사용합니다.
그리고 그것을 사용하면 명령이 branch name에 의존하지 않기 때문에 별칭을 사용할 수도 있습니다 .


2
YourBranch현재 위치를 커밋하기 위해 체크 아웃하는 것이 좋습니다. YourBranch당신이 할 때 이것은 그대로 유지됩니다reset
Eugen Konkov

1
@Abdurrahim 또는 git bash를 열면 thos 명령을 복사하여 붙여 넣을 수 있습니다!
VonC 2016 년

3
재설정을 위해 git reset $(git merge-base master $(git rev-parse --abbrev-ref HEAD))현재 사용중인 지점을 자동으로 사용할 수 있습니다 . 그리고 명령을 사용하면 분기 이름에 의존하지 않으므로 별칭을 사용할 수도 있습니다.
Karlotcha Hoa

1
@Druska 간단한 분기 사례의 경우 아니요, 제대로 작동합니다.
VonC

1
@Shimmy 예, 재설정 후 강제 푸시를 제공 한 경우 : git push --force(및 해당 지점에서 여러 사람이 작업중인 경우 동료에게 경고)
VonC

112

모든 커밋을 하나의 커밋으로 스쿼시하려는 지점을 체크 아웃하십시오. 그것의 호출을 말해 보자.feature_branch .

git checkout feature_branch

1 단계:

origin/feature_branch현지 master지점 으로 소프트 재설정을 수행하십시오 (필요에 따라 출발지 / 마스터로 재설정 할 수도 있음). 이렇게하면 추가 커밋이 모두 재설정됩니다.feature_branch 되지만 파일 변경 사항은 로컬로 변경하지 않습니다.

git reset --soft master

2 단계:

git repo 디렉토리의 모든 변경 사항을 새로 만들 커밋에 추가하십시오. 그리고 메시지로 같은 것을 커밋하십시오.

git add -A && git commit -m "commit message goes here"


6
이것은 rebase 오류나 병합 충돌을 일으키지 않는 가장 안정적인 솔루션이었습니다.
ANTARA

1
경고 : git add -A 로컬 폴더에있는 모든 것을 지점에 추가하십시오.
David H

이 솔루션을 사랑하십시오! 이것이 바로 내가 원하는 것입니다!
jacoballenwood

1
멍청한 놈을위한 최고의 솔루션 – 비파괴적이고 oops 순간 만 앱 비밀과 같이 너무 많이 체크인 할 수 있습니다. 적절한 gitignore 파일이
있는지는

@NSduToit 짧은 답변 : 아니요, 그럴 필요는 없습니다. 내 대답에서 위에서 언급 한 단계를 수행하면 코드 변경으로 커밋이 완료됩니다. 코드 변경 사항이있는 다른 커밋과 마찬가지로 생각할 수 있습니다. -f플래그 없이 원격 지사로 푸시 할 수 있습니다 .
shanky

110

당신이하고있는 일은 꽤 오류가 발생하기 쉽습니다. 그냥 해:

git rebase -i master

분기의 커밋 만 현재 최신 마스터에 자동으로 리베이스합니다.


5
고마워, 나는 그것을 얻었지만 왜 내 시스템 오류가 발생하기 쉬운
user3803850

10
아마도 숫자를 잘못 얻기가 쉽기 때문에?
Daniel Scott

13
이것이 최선의 해결책이라고 동의했습니다. 그러나이 링크 를 따라 가면 필요한 것을 더 잘 설명 할 수 있습니다.
Christo

3
커밋을 스쿼시하는 대신 브랜치를 마스터에 병합하고 git reset을 origin / master로 재설정하여 모든 커밋을 스테이지 해제 할 수 있습니다. 이렇게하면 기존의 비 commit -am "the whole thing!"
스테이지

2
@ nurettin 나는 reset origin/master메소드가 마스터에서 직접 커밋을하는 것과 동일하기 때문에 실제로 나쁜 것이라고 생각합니다. '병합 지점'이력, 풀 요청 옵션이 없습니다. @WaZaA의 대답은 내가 생각하는 정상적인 자식 워크 플로우를 유지하는 데 훨씬 더 도움이됩니다.
Drenai

79

이를 수행하는 또 다른 간단한 방법은 원점 분기로 이동하여을 수행하는 것 merge --squash입니다. 이 명령은 "squashed"커밋을 수행하지 않습니다. 당신이 그것을 할 때, 당신의 지점의 모든 커밋 메시지가 수집됩니다.

$ git checkout master
$ git merge --squash yourBranch
$ git commit # all commit messages of yourBranch in one, really useful
 > [status 5007e77] Squashed commit of the following: ...


1
부모 브랜치로 스쿼시하고 싶지 않다면 부모 브랜치를 기반으로 새 브랜치를 만들고 전환하여 스쿼시 병합을 수행하십시오.
샬럿

건배 친구, 좋은 팁!
Nestor Milyaev

좋은! 먼저 "마스터"에서 "임시"분기를 만들어 "yourBranch"를 스쿼시 한 ​​다음 "임시"를 "마스터"로 병합합니다.
lazieburd

34

마스터에서 분기한다고 가정하면 항상 yourBranch재설정 단계 를 시작할 필요가 없습니다 .

git checkout yourBranch
git reset --soft HEAD~$(git rev-list --count HEAD ^master)
git add -A
git commit -m "one commit on yourBranch"

설명 :

  • git rev-list --count HEAD ^master마스터에서 기능 분기를 만든 이후 커밋을 계산합니다 (f.ex). 20.
  • git reset --soft HEAD~20마지막 20 개의 커밋을 소프트 리셋합니다. 이렇게하면 파일에 변경 사항이 남지만 커밋은 제거됩니다.

용법 :

내 .bash_profile gisquash에서 하나의 명령 으로이 작업을 수행 하기 위해 별칭을 추가했습니다 .

# squash all commits into one
alias gisquash='git reset --soft HEAD~$(git rev-list --count HEAD ^master)'

재설정하고 커밋 한 후에는 git push --force .

힌트 :

Gitlab> = 11.0을 사용하는 경우 브랜치를 병합 할 때 스쿼시 옵션 이 있으므로 더 이상이 작업을 수행 할 필요가 없습니다 . Gitlab 스 쿼싱 옵션


15

스 태싱에 대한 몇 가지 Stackoverflow 질문과 답변을 읽은 결과, 이것은 지점의 모든 커밋을 스쿼시하기에 좋은 라이너라고 생각합니다.

git reset --soft $(git merge-base master YOUR_BRANCH) && git commit -am "YOUR COMMIT MESSAGE" && git rebase -i master

이것은 마스터가 기본 분기라고 가정합니다.


1
고마워요, 회사에는 많은 제한이 있으며 큰 소리로 저장하지 않은 편집기로 일반적인 방법으로 리베이스 할 수 없었습니다. 또한이 지점은 병합을 위해 Lead dev로 이동하여 git에서 스쿼시 및 병합 기능을 사용할 수 없었습니다. 이 1 개의 강선은 일하고 두통을 저장했습니다. 대단한 직업.
L1ghtk3ira

10

클릭을 선호하는 사람들을위한 솔루션 :

  1. 소스 트리 설치 (무료)

  2. 커밋이 어떻게 보이는지 확인하십시오. 아마도 당신은 이것과 비슷한 것을 가지고 있습니다. 여기에 이미지 설명을 입력하십시오

  3. 부모 커밋을 마우스 오른쪽 버튼으로 클릭하십시오 . 우리의 경우에는 마스터 브랜치입니다.

여기에 이미지 설명을 입력하십시오

  1. 버튼을 클릭하여 이전 커밋과 스쿼시 할 수 있습니다. 이 경우에는 두 번 클릭해야합니다. 커밋 메시지를 변경할 수도 있습니다 여기에 이미지 설명을 입력하십시오

  2. 결과는 훌륭하고 우리는 추진할 준비가되었습니다! 여기에 이미지 설명을 입력하십시오

참고 사항 : 부분 커밋을 원격으로 푸시하는 경우 스쿼시 후에 강제 푸시를 사용해야합니다


감사합니다!
Crystal

0

다른 해결책은 모든 커밋 로그를 파일에 저장하는 것입니다

자식 로그> branch.log

이제 branch.log는 시작 이후 모든 커밋 ID를 갖습니다. 아래로 스크롤하여 첫 번째 커밋을 사용하여 첫 번째 커밋을 수행합니다 (터미널에서는 어려울 것입니다).

git reset-소프트

모든 커밋이 중단됩니다


0

이전에 많은 답변에서 언급했듯이 Git 재설정은 원하는 것을 달성하는 가장 쉽고 간단한 방법입니다. 다음 워크 플로에서 사용합니다.

(개발 지점)

git fetch
git merge origin/master  #so development branch has all current changes from master
git reset origin/master  #will show all changes from development branch to master as unstaged
git gui # do a final review, stage all changes you really want
git commit # all changes in a single commit
git branch -f master #update local master branch
git push origin master #push it

0

이 모든 git reset, hard, soft 및 여기에 언급 된 모든 것이 단계를 올바르게 수행하고 일종의 지니를 수행하면 아마도 작동하지 않을 것입니다 (나에게는 적합하지 않음).
평균 Joe smo 인 경우 다음을 시도하십시오.
git merge --squash를 사용하는 방법?


내 목숨을 구하고 스쿼시로가는 길을 알게되었으므로 이것을 4 번이나 사용했습니다. 간단하고 깨끗하며 기본적으로 1 개의 comamnd. 한마디로 :


브랜치에 있다면 개발에서 "my_new_feature"라고 부르고 풀 요청에 35 개의 커밋 (또는 많은 수)이 있고 1을 원합니다.

A. 브랜치가 최신인지 확인하십시오. "my_new_feature"와의 충돌을 개발, 최신 화 및 병합 및 해결하십시오
(이 단계는 항상 가능한 한 빨리 수행해야합니다)

B. 새로운 분기로 최신 개발 및 분기를 가져와 "my_new_feature_squashed"

C. 마법이 여기 있습니다.
당신은 "my_new_feature"에서 "my_new_feature_squashed"로 작업을하고 싶다.
그렇게하라.
git merge --squash my_new_feature

모든 변경 사항은 이제 새로운 지점에있을 것입니다. 자유롭게 테스트 한 다음 해당 지점의 단일 커밋, 푸시, 새로운 PR을 수행하고 다음 날 반복을 기다리십시오.
코딩을 좋아하지 않습니까? :)


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.