병합 충돌을 해결하기 위한 Rebase

Git에서 rebase는 당신의 브랜치를 다른 브랜치의 내용으로 업데이트합니다.

Rebase는 당신의 브랜치의 변경 사항이 대상 브랜치의 변경 사항과 충돌하지 않음을 확인합니다.

병합 충돌이 발생한 경우, 이를 수정하기 위해 rebase할 수 있습니다.

Rebase 중에 발생하는 일

Rebase를 수행하면:

  1. Git은 당신이 브랜치를 처음 생성한 이후에 대상 브랜치에 제출된 모든 커밋을 가져옵니다.

  2. Git은 당신의 브랜치에 있는 커밋을 가져온 브랜치의 모든 커밋 위에 쌓습니다:

    Git rebase 일러스트

대부분의 리베이스는 main에 대해 수행되지만, release-15-3와 같은 다른 브랜치에 대해서도 rebase할 수 있습니다. origin 대신 다른 원격 저장소(예: upstream)를 지정할 수도 있습니다.

경고: git rebase는 커밋 기록을 다시 작성합니다. 공유 브랜치에서 진행하는 것은 위험할 수 있습니다. 복잡하고 해결하기 어려운 병합 충돌을 초래할 수 있습니다. 기본 브랜치에 대해 당신의 브랜치를 리베이스하는 대신, 대신 끌어오는 것을 고려하세요 (git pull origin master). 끌어오는 것은 비슷한 효과를 가지지만 다른 사람의 작업을 해칠 위험이 적습니다.

Git을 사용하여 Rebase하기

Git을 사용하여 rebase를 수행할 때, 각 커밋이 당신의 브랜치에 적용됩니다. 병합 충돌이 발생하면, 이를 해결하라는 메시지가 표시됩니다.

커밋을 위한 더 많은 고급 옵션을 원한다면, 인터랙티브 리베이스를 수행하십시오.

전제 조건:

  • 브랜치에 강제 푸시할 수 있는 권한이 있어야 합니다.

대상 브랜치에 대해 당신의 브랜치를 rebase하기 위해 Git을 사용하는 방법은 다음과 같습니다:

  1. 터미널을 열고 당신의 프로젝트로 변경합니다.

  2. 대상 브랜치의 최신 내용을 확인합니다. 이 예제에서는 대상 브랜치가 main입니다:

    git fetch origin main
    
  3. 당신의 브랜치를 체크 아웃합니다:

    git checkout my-branch
    
  4. 선택 사항. 당신의 브랜치의 백업을 만듭니다:

    git branch my-branch-backup
    

    이 시점 이후 my-branch에 추가된 변경 사항은 백업 브랜치에서 복원할 경우 손실됩니다.

  5. main 브랜치에 대해 rebase합니다:

    git rebase origin/main
    
  6. 병합 충돌이 존재하는 경우:
    1. 편집기에서 충돌을 수정합니다.

    2. 파일을 추가합니다:

      git add .
      
    3. rebase를 계속합니다:

      git rebase --continue
      
  7. 다른 사람의 커밋을 보호하면서 대기 브랜치에 당신의 변경 사항을 강제로 푸시합니다:

    git push origin my-branch --force-with-lease
    

UI에서 Rebase 하기

GitLab UI에서 병합 요청을 rebase할 수 있습니다.

전제 조건:

UI에서 Rebase하기 위해:

  1. 당신의 병합 요청으로 이동합니다.

  2. 댓글에 /rebase를 입력합니다.

  3. 댓글 달기를 선택합니다.

GitLab은 기본 브랜치에 대한 브랜치의 rebase를 예약하고 가능한 한 빨리 실행합니다.

Git을 사용한 대화형 리베이스

각 커밋을 처리하는 방법을 지정하려면 대화형 리베이스를 사용하세요.

명령줄에서 대화형 리베이스를 수행해야 합니다.

사전 준비 사항:

  • Vim이 이 지침을 따르기 위한 텍스트 편집기여야 합니다.

대화형 리베이스를 수행하려면:

  1. 터미널을 열고 프로젝트로 이동합니다.

  2. 대상 브랜치의 최신 내용을 확인합니다.
    이 예에서 대상 브랜치는 main입니다:

    git fetch origin main
    
  3. 당신의 브랜치로 체크아웃합니다:

    git checkout my-branch
    
  4. 선택 사항. 브랜치의 백업을 만듭니다:

    git branch my-branch-backup
    

    이 시점 이후 my-branch에 추가된 변경 사항은
    백업 브랜치에서 복원하면 손실됩니다.

  5. GitLab UI에서 병합 요청으로 이동하여
    리베이스할 커밋 수를 확인합니다 Commits 탭을 통해.

  6. 이러한 커밋을 엽니다. 예를 들어, 브랜치의 마지막 다섯 개의 커밋을 편집하려면 (HEAD~5) 다음을 입력합니다:

    git rebase -i HEAD~5
    

    Git은 터미널 텍스트 편집기에서 마지막 다섯 개의 커밋을 엽니다.
    가장 오래된 커밋이 먼저 표시됩니다.
    각 커밋에는 취할 작업, SHA 및 커밋 제목이 표시됩니다:

    pick 111111111111 두 번째 구조 수정 라운드
    pick 222222222222 이 변경된 페이지에 대한 인바운드 링크 업데이트
    pick 333333333333 H4에서 H3로 전환
    pick 444444444444 편집에서 가져온 수정 사항 추가
    pick 555555555555 수정 사항은 개념 부분을 계속 발전시킵니다
    
    # Rebase 111111111111..222222222222 onto zzzzzzzzzzzz (5 commands)
    #
    # Commands:
    # p, pick <commit> = 커밋 사용
    # r, reword <commit> = 커밋 사용, 하지만 커밋 메시지 편집
    # e, edit <commit> = 커밋 사용, 하지만 수정할 수 있도록 멈춤
    # s, squash <commit> = 커밋 사용, 하지만 이전 커밋과 합치기
    # f, fixup [-C | -c] <commit> = "squash"와 비슷하지만 이전 것만 유지
    
  7. i를 눌러 Vim의 편집 모드로 전환합니다.

  8. 키보드 화살표를 사용하여 목록에서 두 번째 커밋으로 이동합니다.

  9. pick 단어를 squash 또는 fixup(또는 s 또는 f)으로 변경합니다.

  10. 나머지 커밋에 대해서도 같은 작업을 수행합니다. 첫 번째 커밋은 pick으로 둡니다.

  11. 편집 모드를 종료하고 저장한 후 종료합니다:

    • ESC를 누릅니다.
    • :wq를 입력합니다.
  12. 스quash할 때, Git은 커밋 메시지를 출력하므로 편집할 기회를 제공합니다:

    • #으로 시작하는 모든 행은 무시되며 커밋 메시지에 포함되지 않습니다.
      나머지는 모두 포함됩니다.

    • 그대로 두려면 :wq를 입력합니다. 커밋 메시지를 편집하려면 편집 모드로 전환하여
      커밋 메시지를 편집한 후 저장합니다.

  13. 대상 브랜치에 커밋합니다.

    • 리베이스 전에 커밋을 대상 브랜치에 푸시하지 않았다면,
      강제 푸시 없이 변경 내용을 푸시합니다:
    git push origin my-branch
    
    • 이미 이 커밋을 푸시한 경우, 강제 푸시를 사용합니다:
    git push origin my-branch --force-with-lease
    

포스 푸시

Git의 복잡한 작업은 원격 브랜치를 강제로 업데이트해야 합니다.

커밋 병합, 브랜치 리셋, 또는 브랜치 리베이스와 같은 작업은 브랜치의 히스토리를 수정합니다.

Git은 이러한 보다 파괴적인 변경 사항이 우발적으로 발생하는 것을 방지하기 위해 강제로 업데이트할 필요가 있습니다.

공유 브랜치에서 포스 푸시를 하는 것은 권장되지 않습니다. 다른 사람의 변경 사항을 파괴할 위험이 있기 때문입니다.

강제로 푸시하려는 브랜치가 보호됨일 경우:

그런 다음 강제로 푸시하고 다시 보호할 수 있습니다.

백업된 브랜치 복원

브랜치가 백업되어 있으며 리베이스 또는 포스 푸시를 시도할 수 있습니다.

문제가 발생하면 백업에서 브랜치를 복원합니다:

  1. 올바른 브랜치에 있는지 확인합니다:

    git checkout my-branch
    
  2. 백업에 대해 브랜치를 리셋합니다:

    git reset --hard my-branch-backup
    

리베이스 후 승인

브랜치를 리베이스하면 커밋이 추가됩니다.

프로젝트가 커밋을 추가하는 사용자의 승인을 방지하도록 설정된 경우, 리베이스한 머지 요청을 승인할 수 없습니다.

관련 주제

문제 해결

/rebase 빠른 작업 후 병합 불가능 상태

/rebase 명령은 백그라운드 작업을 예약합니다. 이 작업은 소스 브랜치의 변경 사항을 대상 브랜치의 최신 커밋에 리베이스하려고 시도합니다.

/rebase 빠른 작업을 사용한 후 이 오류가 나타나면, 리베이스를 예약할 수 없습니다:

이 병합 요청은 현재 병합 불가능 상태이며, 리베이스할 수 없습니다.

다음 조건 중 하나라도 참이면 이 오류가 발생합니다:

  • 소스 브랜치와 대상 브랜치 간에 충돌이 존재합니다.
  • 소스 브랜치에는 커밋이 없습니다.
  • 소스 또는 대상 브랜치가 존재하지 않습니다.
  • 오류가 발생하여 차이가 생성되지 않았습니다.

병합 불가능 상태 오류를 해결하려면:

  1. 모든 병합 충돌을 해결합니다.
  2. 소스 브랜치가 존재하고 커밋이 있는지 확인합니다.
  3. 대상 브랜치가 존재하는지 확인합니다.
  4. 차이가 생성되었는지 확인합니다.

/rebase/merge 빠른 작업 무시됨

/rebase가 사용되면, 소스 브랜치가 리베이스되기 전에 병합되거나 삭제되는 경합 조건을 피하기 위해 /merge가 무시됩니다.