git에서 커밋을 스쿼시한다는 것은 무엇을 의미합니까? in git은 무엇을 의미합니까?

Squashing commits in git은 무엇을 의미합니까? Github에서 커밋을 어떻게 스쿼시합니까?

저는 Git을 처음 접했고 coala-analyzer의 새로운 버그에 할당되도록 요청했습니다. 버그를 수정했고 이제 커밋을 스쿼시하라는 요청을 받았습니다. 어떻게하나요?



답변

Git은 작업 디렉토리 (들)의 스냅 샷에 대한 고급 데이터베이스라고 생각할 수 있습니다.

Git의 아주 좋은 기능 중 하나는 커밋 기록을 다시 작성할 수 있다는 것입니다.
이렇게하는 주된 이유는 그러한 기록의 상당수가 그것을 생성 한 개발자에게만 관련이 있기 때문에 공유 저장소에 제출하기 전에 단순화하거나 더 멋지게 만들어야하기 때문입니다.

커밋을 스 쿼싱 한다는 것은 관용적 관점에서 해당 커밋에 도입 된 변경 사항을 부모로 이동하여 두 개 (또는 그 이상) 대신 하나의 커밋으로 끝나는 것을 의미합니다.
이 프로세스를 여러 번 반복하면 n 커밋을 단일 커밋으로 줄일 수 있습니다 .

당신이 커밋 태그에서 작업을 시작하면 시각적으로 시작 , 당신이 원하는

새 커밋의 파란색 음영이 약간 더 어둡다는 것을 알 수 있습니다. 이것은 의도적 인 것입니다.

Git에서 스 쿼싱은 Interactive Rebase 라는 특수한 형태 의 Rebase를 사용하여 수행됩니다 .
커밋 세트를 브랜치 B 로 리베이스 할 때 단순화하면 원래 조상이 아닌 B 에서 시작하여 수행 된 커밋에 의해 도입 된 모든 변경 사항을 적용합니다 .

시각적 단서

파란색의 다른 음영을 다시 확인하십시오.

대화 형 리베이스를 사용하면 커밋을 리베이스하는 방법을 선택할 수 있습니다. 이 명령을 실행하는 경우 :

 git rebase -i branch

리베이스 할 커밋을 나열하는 파일이 생성됩니다.

 pick ae3...
 pick ef6...
 pick 1e0...
 pick 341...

나는 커밋 이름을하지 못했지만,이 네 사람은에서 커밋되는 것이다 시작머리

이 목록의 좋은 점 은 편집 가능 하다는 것입니다 .
커밋을 생략하거나 스쿼시 할 수 있습니다 .
당신이해야 할 일은 첫 번째 단어를 squash 로 변경하는 것 입니다.

 pick ae3...
 squash ef6...
 squash 1e0...
 squash 341...

편집기를 닫고 병합 충돌이 발견되지 않으면 다음 기록으로 끝납니다.

귀하의 경우에는 다른 브랜치로 리베이스하는 것이 아니라 이전 커밋으로 리베이스하고 싶지 않습니다.
첫 번째 예에서와 같이 히스토리를 변환하려면 다음과 같이 실행해야합니다.

git rebase -i HEAD~4

첫 번째 커밋을 제외한 모든 커밋 을 스쿼시 하도록 “명령”을 변경 한 다음 편집기를 닫습니다.


역사 변경에 대한 참고 사항

Git에서는 커밋이 편집되지 않습니다. 잘라낼 수 있고, 연결할 수 없게 만들거나, 복제 할 수는 있지만 변경할 수는 없습니다.
리베이스하면 실제로 새 커밋을 생성하는 것입니다.
이전 항목은 더 이상 심판이 도달 할 수 없으므로 기록에 표시되지 않지만 여전히 존재합니다!

이것은 실제로 rebase를 위해 얻는 것입니다.

이미 어딘가에 밀어 넣었다면 역사를 다시 작성하면 실제로 분기가 만들어집니다!


답변

rebase 명령에는 --interactive(또는 -i) 모드 에서 사용할 수있는 몇 가지 멋진 옵션 이 있으며 가장 널리 사용되는 옵션 중 하나는 커밋을 스쿼시하는 기능입니다. 이것이하는 일은 작은 커밋을 더 큰 커밋으로 결합하는 것입니다. 이는 하루의 작업을 마무리하거나 변경 사항을 다르게 패키징하려는 경우 유용 할 수 있습니다. 이 작업을 쉽게 수행 할 수있는 방법을 살펴 보겠습니다.

주의 사항 : 외부 저장소로 푸시되지 않은 커밋에만이 작업을 수행하십시오. 다른 사람이 삭제할 커밋을 기반으로 작업을 수행하면 많은 충돌이 발생할 수 있습니다. 다른 사람과 공유 한 기록을 다시 쓰지 마십시오.

이제 몇 개의 작은 커밋을 수행했고 그중 하나를 더 큰 커밋으로 만들고 싶다고 가정 해 보겠습니다. 우리 저장소의 역사는 현재 다음과 같습니다 :

마지막 4 개의 커밋은 함께 묶어두면 훨씬 더 행복 할 것이므로 대화식 리베이스를 통해 그렇게합시다.

$ git rebase -i HEAD~4

pick 01d1124 Adding license
pick 6340aaa Moving license into its own file
pick ebfd367 Jekyll has become self-aware.
pick 30e0ccb Changed the tagline in the binary, too.

# Rebase 60709da..30e0ccb onto 60709da
#
# Commands:
#  p, pick = use commit
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

그래서 여기서 몇 가지 일이 일어났습니다. 먼저 HEAD가 HEAD ~ 4 인 마지막 4 개의 커밋을 사용하여 리베이스하고 싶다고 Git에게 말했습니다. Git은 이제 위의 텍스트와 함께 수행 할 수있는 작업에 대한 약간의 설명이있는 편집기에 나를 넣었습니다. 이 화면에서 많은 옵션을 사용할 수 있지만 지금은 모든 것을 하나의 커밋으로 스쿼시 할 것입니다. 따라서 파일의 처음 네 줄을 이렇게 변경하면 트릭이됩니다.

pick 01d1124 Adding license
squash 6340aaa Moving license into its own file
squash ebfd367 Jekyll has become self-aware.
squash 30e0ccb Changed the tagline in the binary, too.

기본적으로 이것은 Git에게 네 개의 커밋을 모두 목록의 첫 번째 커밋으로 결합하도록 지시합니다. 이 작업이 완료되고 저장되면 다음과 같은 다른 편집기가 나타납니다.

# This is a combination of 4 commits.
# The first commit's message is:
Adding license

# This is the 2nd commit message:

Moving license into its own file

# This is the 3rd commit message:

Jekyll has become self-aware.

# This is the 4th commit message:

Changed the tagline in the binary, too.

    # Please enter the commit message for your changes. Lines starting
    # with '#' will be ignored, and an empty message aborts the commit.
    # Explicit paths specified without -i nor -o; assuming --only paths...
    # Not currently on any branch.
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #   new file:   LICENSE
    #   modified:   README.textile
    #   modified:   Rakefile
    #   modified:   bin/jekyll
    #

너무 많은 커밋을 결합하고 있기 때문에 Git을 사용하면 프로세스에 포함 된 나머지 커밋을 기반으로 새 커밋의 메시지를 수정할 수 있습니다. 원하는대로 메시지를 편집 한 다음 저장하고 종료하십시오. 완료되면 커밋이 성공적으로 처리되었습니다!

Created commit 0fc4eea: Creating license file, and making jekyll self-aware.
 4 files changed, 27 insertions(+), 30 deletions(-)
  create mode 100644 LICENSE
    Successfully rebased and updated refs/heads/master.

그리고 우리가 다시 역사를 보면 …

그래서 이것은 지금까지 비교적 고통스럽지 않았습니다. 리베이스 중에 충돌이 발생하면 일반적으로 해결하기가 매우 쉽고 Git이 가능한 한 많이 안내합니다. 이것의 기본은 문제의 충돌, git add파일을 수정 한 다음 git rebase --continue프로세스를 재개하는 것입니다. 물론 git rebase --abort원하는 경우 a 를 수행하면 이전 상태로 돌아갈 수 있습니다. 어떤 이유로 리베이스에서 커밋을 잃어버린 경우 reflog를 사용하여 되돌릴 수 있습니다.

자세한 내용은이 링크 에서 찾을 수 있습니다 .