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


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
  • 대화식 화면이 열리면 스쿼시 하려는 모든 커밋의 상단에 pick 을 squash 로 바꿉니다.
  • 저장하고 편집기를 닫습니다 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.