커밋 된 후 커밋을 스쿼시하는 방법은 무엇입니까?


550

이것은 여러 커밋을 스쿼시하는 것에 대한 좋은 설명을 제공합니다.

http://git-scm.com/book/en/Git-Branching-Rebasing

그러나 이미 푸시 된 커밋에는 작동하지 않습니다. 로컬 및 원격 저장소에서 가장 최근의 커밋을 어떻게 스쿼시합니까?

편집 : 내가 할 때 git rebase -i origin/master~4 master첫 번째를로 유지하고 pick다른 세 개를로 설정 squash한 다음 종료하십시오 (emacs의 cx cc를 통해).

$ git rebase -i origin/master~4 master
# Not currently on any branch.
nothing to commit (working directory clean)

Could not apply 2f40e2c... Revert "issue 4427: bpf device permission change option added"
$ git rebase -i origin/master~4 master
Interactive rebase already started

여기서 2f40은 pick커밋입니다. 그리고 이제 4 개의 커밋 중 어느 것도에 나타나지 않습니다 git log. 커밋 메시지를 입력 할 수 있도록 편집기를 다시 시작해야했습니다. 내가 무엇을 잘못하고 있지?

답변:


779

스쿼시와 로컬로 커밋

git rebase -i origin/master~4 master

그런 다음

git push origin +master

차이 사이 --force+

의 문서에서 git push:

참고 --force때문에 그것을 사용하여 가압되는 모든 심판에 적용 push.default되도록 설정 matching혹은 구성 여러 목적지로 푸시 remote.*.push(이들 원격 상대방 뒤에 엄격 로컬 심판을 포함한) 현재의 분기 이외 심판을 덮어 쓸 수있다. 하나의 브랜치로만 푸시하려면 참조 + 스펙 앞의를 사용 하여 푸시합니다 (예 : git push origin +master푸시를 master분기 로 강제 ).


30
당신은 또한 수 있습니다git push --force origin master
Daenyth

7
Daenyth : 예,하지만이 구문이 더 짧기 때문에 항상이 구문을 선호합니다.
Alan Haggai Alavi

86
물론 다른 사람이 원격 저장소에서 가져온 경우이 작업을 원하지 않을 수도 있습니다.이 경우의 대답은 "그렇지 않습니다"입니다.
Cascabel

10
또한 OP가 명령을 정확하게 복사하고 있다고 생각합니다. git rebase -i origin/master실제로 커밋을 그보다 더 멀리 되 돌리는 방법을 알고 싶습니다 git rebase -i origin/master~20 master.
Cascabel

6
gstackoverflow :+접두사가 붙은 참조 스펙 만 강제합니다. --force모든 참조 사양을 강제로 푸시합니다. 업데이트 된 답변을 참조하십시오.
Alan Haggai Alavi

119

지점에서 나는 이렇게 할 수있었습니다 (마지막 4 커밋에 대해)

git checkout my_branch
git reset --soft HEAD~4
git commit
git push --force origin my_branch

1
이미 푸시 된 지점에서 소프트 명령 으로이 작업을 수행하면 다른 많은 사람들이 나를 위해 노력합니다.
cchamberlain

3
톤? 어떻게 4 이상이 될 수 있습니까? 정교하게 할 수 있습니까?
jakob-r

확실하지 않지만 이미 푸시 된 커밋을 스쿼시하려고하는 것과 관련이 있습니다. - 다른 사람처럼 보인다는 여기에 비슷한 경험 stackoverflow.com/questions/5189560/...
cchamberlain

4
나는 이것을 예상 답변으로 받아 들였을 것입니다. 대답을 받아 들인 더 깨끗합니다.
vikramvi

4
이것은 단지 4 단계에서 가장 명확하고 허용 답변입니다
아메 Salagre

45

대답에 약간의 차이가 있었지만, 나는 스쿼시하는 데 많은 어려움을 겪고 마침내 그것을 얻었습니다.

$ git rebase -i HEAD~4
  • 대화식 화면이 열리면 스쿼시 하려는 모든 커밋의 상단에 picksquash 로 바꿉니다.
  • 저장하고 편집기를 닫습니다 esc --> :wq

다음을 사용하여 리모컨으로 미십시오.

$ git push origin branch-name --force

2
간단하고 효과적인, 정교한 :
terwxqian

22

문제의 많은 단지를 작성하여 방지 할 수 있습니다 branch에 대한 작업에 & 하지 작업 master:

git checkout -b mybranch

다음 remote은 이미 푸시 된 커밋 및 remote푸시 된 커밋 / local커밋 만 혼합에서 작동합니다 .

# example merging 4 commits

git checkout mybranch
git rebase -i mybranch~4 mybranch

# at the interactive screen
# choose fixup for commit: 2 / 3 / 4

git push -u origin +mybranch

또한 도움이 될만한 끌어 오기 요청 메모 가 있습니다.


17

git rebase -i master

에디터 vm을 열면 다음과 같은 메시지가 나타납니다.

Pick 2994283490 commit msg1
f 7994283490 commit msg2
f 4654283490 commit msg3
f 5694283490 commit msg4
#Some message 
#
#some more

여기에서는 다른 모든 커밋에 대한 선택을 "f"(픽스 업용 스탠드)로 변경했습니다.

git push -f origin feature/feature-branch-name-xyz

이것은 한 커밋에 대한 모든 커밋을 고치고 다른 모든 커밋을 제거합니다. 나는 이것을했고 그것은 나를 도왔다.


3

Gitlab 또는 Github으로 작업 할 때 이런 방식으로 문제가 발생할 수 있습니다. 위의 방법 중 하나를 사용하여 커밋을 스쿼시하십시오. 내가 가장 선호하는 것은 :

git rebase -i HEAD~4
or
git rebase -i origin/master

커밋에 대한 스쿼시 또는 수정을 선택하십시오. 이 시점에서 git status로 확인하십시오. 메시지는 다음과 같습니다.

    On branch ABC-1916-remote
    Your branch and 'origin/ABC-1916' have diverged,
    and have 1 and 7 different commits each, respectively.
      (use "git pull" to merge the remote branch into yours)

그리고 당신은 그것을 당기고 싶은 유혹을받을 수 있습니다. 그렇게하지 않으면 이전과 같은 상황에 처하게됩니다.

대신 다음을 사용하여 원점으로 푸시하십시오.

git push origin +ABC-1916-remote:ABC-1916

+는 하나의 브랜치에만 푸시를 허용합니다.


당기기에 아무런 문제가 없습니다. 특히 충돌이있을 경우 강제로 밀어내는 것보다 쉽게 ​​해결할 수 있습니다
Ray_Poly

2

하나의 분기에서 두 개의 커밋을 스쿼시하기 위해 다음 분기가 작동했습니다.

git rebase -i HEAD~2
    [ pick     older-commit  ]
    [ squash   newest-commit ]
git push --force

기본적으로 여기에는 최신 커밋의 커밋 메시지가 이전 커밋에 대한 주석으로 포함됩니다.


2

1) git rebase -i HEAD~4

정교하게 : 그것은 현재 지점에서 작동합니다; HEAD ~ 4는 최신 4 개의 커밋을 스쿼시하는 것을 의미합니다. 대화식 모드 (-i)

2)이 시점에서 편집기는 커밋 목록과 함께 두 번째와 다음 커밋을 변경하고 pick을 squash로 바꾼 다음 저장합니다.

출력 : refs / heads / branch-name을 성공적으로 리베이스하고 업데이트했습니다.

삼) git push origin refs/heads/branch-name --force

산출:

remote:
remote: To create a merge request for branch-name, visit:
remote: http://xxx/sc/server/merge_requests/new?merge_request%5Bsource_branch%5D=sss
remote:To ip:sc/server.git
 + 84b4b60...5045693 branch-name -> branch-name (forced update)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.