병합 메소드

Tier: Free, Premium, Ultimate Offering: GitLab.com, Self-managed, GitLab Dedicated

프로젝트에서 선택한 병합 메소드는 병합 요청에서의 변경 사항이 기존 브랜치에 병합되는 방식을 결정합니다.

이 페이지의 예시는 main 브랜치에 커밋 A, C, E가 있고 feature 브랜치에 커밋 B, D가 있다고 가정합니다.

gitGraph commit id: "A" branch feature commit id: "B" commit id: "D" checkout main commit id: "C" commit id: "E"

프로젝트의 병합 메소드 구성

  1. 왼쪽 사이드바에서 검색 또는 이동을 선택하고 프로젝트를 찾습니다.
  2. 설정 > 병합 요청을 선택합니다.
  3. 이러한 옵션 중에서 원하는 병합 메소드를 선택합니다:
    • 병합 커밋
    • 반선형 히스토리로 병합 커밋
    • 빠른-앞으로 병합
  4. 병합 시 커밋 합병에서 커밋 처리에 대한 기본 동작을 선택합니다:
    • 허용 안 함: 합병이 절대로 수행되지 않으며 사용자는 동작을 변경할 수 없습니다.
    • 허용: 합병이 기본적으로 꺼져 있지만 사용자가 동작을 변경할 수 있습니다.
    • 규칙: 합병이 항상 수행되며 사용자는 동작을 변경할 수 없습니다.
    • 권고: 합병이 기본적으로 켜져 있지만 사용자가 동작을 변경할 수 있습니다.
  5. 변경 사항 저장을 선택합니다.

병합 커밋

기본적으로 GitLab은 브랜치를 main에 병합할 때 병합 커밋을 생성합니다. 커밋이 합병될 때 병합 커밋이 항상 생성되며, 커밋이 합병될 때 합병 시 커밋 합병 여부에 관계없이 합병 커밋이 main 브랜치에 추가될 수 있습니다.

이 그래프는 병합 커밋 전략을 사용할 때 feature 브랜치가 main에 병합되는 방법을 보여줍니다. 이 그래프들은 명령어 git merge --no-ff <feature> 및 GitLab UI에서 병합 메소드병합 커밋을 선택했을 때와 동등합니다.

병합 전략:

%%{init: { 'gitGraph': {'logLevel': 'debug', 'showBranches': true, 'showCommitLabel':true,'mainBranchName': 'main'}} }%% gitGraph commit id: "A" branch feature commit id: "B" commit id: "D" checkout main commit id: "C" commit id: "E" merge feature

병합 커밋 방법으로 기능 브랜치를 병합한 후 main 브랜치는 다음과 같이 보입니다:

%%{init: { 'gitGraph': {'logLevel': 'debug', 'showBranches': true, 'showCommitLabel':true,'mainBranchName': 'main'}} }%% gitGraph commit id: "A" commit id: "C" commit id: "E" commit id: "합병 커밋"

비교적으로 합병 축소feature 브랜치의 모든 커밋의 가상 복사본인 squash 커밋을 생성합니다. 원본 커밋(B 및 D)은 feature 브랜치에서 변경되지 않고 squash 커밋이 main 브랜치에 배치됩니다:

%%{init: { 'gitGraph': {'showBranches': true, 'showCommitLabel':true,'mainBranchName': 'main'}} }%% gitGraph commit id:"A" branch feature checkout main commit id:"C" checkout feature commit id:"B" commit id:"D" checkout main commit id:"E" commit id:"합병 커밋" type: HIGHLIGHT

합병 커밋 방식으로 생성된 그래프는 다음과 같이 GitLab UI에서 설정되었을 때와 동등합니다: - 병합 메소드: 병합 커밋. - 병합 시 커밋 합병은 다음 중 하나여야 합니다: - 규칙. - 허용 또는 권고 중 하나, 합병 요청에서 합병을 선택해야 함.

합병 커밋 방식은 다음 명령어와 동등합니다:

  git checkout `git merge-base feature main`
  git merge --squash <feature>
  SOURCE_SHA=`git rev-parse HEAD`
  git checkout <main>
  git merge --no-ff $SOURCE_SHA

반선형 히스토리를 가진 병합 커밋

모든 병합에 대해 병합 커밋이 생성되지만, 브랜치는 빠른-앞으로 병합이 가능한 경우에만 병합됩니다. 이를 통해 병합 요청 빌드가 성공한 경우, 병합 후 대상 브랜치 빌드도 성공됨이 보장됩니다. 이 병합 메소드를 사용하여 생성된 예시 커밋 그래프: mermaid gitGraph commit id: "Init" branch mr-branch-1 commit commit checkout main merge mr-branch-1 branch mr-branch-2 commit commit checkout main merge mr-branch-2 commit branch squash-mr commit id: "Squashed commits" checkout main merge squash-mr 반선형 히스토리의 병합 커밋 방법을 선택한 경우, 병합 요청 페이지에서 빠른-앞으로 병합이 가능한 경우에만 해당 방법을 허용합니다. 빠른-앞으로 병합이 불가능한 경우, 사용자에게 리베이스 옵션을 제공합니다. 자세한 내용은 반선형 병합 메소드에서 리베이스를 참조하세요.

이 방법은 병합 커밋 방법과 동일한 Git 명령어를 사용합니다. 그러나 소스 브랜치가 대상 브랜치의 오래된 버전에 기반한 경우(main과 같은), 소스 브랜치를 리베이스해야 합니다. 이 병합 방법은 더 깔끔한 히스토리를 생성하면서도 모든 브랜치가 어디에서 시작되었고 병합되었는지 확인할 수 있습니다.

Fast-forward merge

가끔은 워크플로 정책이 병합 커밋 없는 깨끗한 커밋 기록을 요구할 수 있습니다. 이러한 경우에는 fast-forward 병합이 적절합니다. Fast-forward 병합 요청을 사용하면 선형적인 Git 이력을 유지하고 병합 커밋을 만들지 않고 병합 요청을 받을 수 있습니다. 이 병합 방법을 사용하여 생성된 예시 커밋 그래프:

gitGraph commit id: "Init" commit id: "Merge mr-branch-1" commit id: "Merge mr-branch-2" commit id: "Commit on main" commit id: "Merge squash-mr"

이 방법은 일반 병합의 경우 git merge --ff <source-branch>와 스쿼시 병합의 경우 git merge --squash <source-branch>와 동일합니다.

Fast-forward 병합 요청이 활성화되면(--ff-only), 병합 커밋이 생성되지 않고 모든 병합이 빨리 앞으로 이동됩니다. 병합은 브랜치를 fast-forward할 수 있는 경우에만 허용됩니다. Fast-forward 병합이 불가능한 경우 사용자는 리베이스 옵션을 선택할 수 있습니다.([semi-)linear 병합 방법에서 리베이스]

참고: Fast-forward 병합 전략을 사용하는 프로젝트는 병합 커밋이 만들어지지 않기 때문에 배포 날짜로 병합 요청 필터링할 수 없습니다. Fast-forward 병합이 활성화된 상태에서는 배포-MR 관계에 의존하는 기능이 작동하지 않습니다. 이 버그는 이슈 398611에서 추적됩니다.

Fast-forward 병합 방법을 선택하여 병합 요청 페이지를 방문했을 때, fast-forward 병합이 가능한 경우에만 수락할 수 있습니다.

Fast-forward 병합 요청

Semi-linear 병합 방법에서 리베이스

이러한 병합 방법에서는 소스 브랜치가 대상 브랜치와 최신 상태일 때에만 병합할 수 있습니다.

  • semi-linear 이력을 가진 병합 커밋.
  • Fast-forward 병합.

Fast-forward 병합이 불가능하지만 충돌이 없는 리베이스가 가능한 경우, GitLab에서는 다음을 제공합니다:

빠른 병합을 위해 소스 브랜치를 리베이스해야하는 경우에는 다음 조건이 모두 참인 경우에 로컬에서 소스 브랜치를 리베이스해야 합니다.

  • 대상 브랜치가 소스 브랜치보다 앞에 있는 경우.
  • 충돌이 없는 리베이스가 불가능한 경우.

로컬에서 빠른 병합 리베이스

스쿼시하기 전에 리베이스가 필요할 수 있지만, 스쿼시 자체가 리베이스와 동등하게 고려될 수 있습니다.

CI/CD 파이프라인 없이 리베이스

CI/CD 파이프라인을 트리거하지 않고 병합 요청 브랜치를 리베이스하려면, 파이프라인 없이 리베이스를 병합 요청 보고서 섹션에서 선택하세요.

이 옵션은:

  • Fast-forward 병합이 불가능하지만 충돌이 없는 리베이스가 가능한 경우에 사용 가능합니다.
  • 파이프라인은 성공해야 함 옵션이 활성화되어 있지 않은 경우에만 사용할 수 있습니다.

CI/CD 파이프라인 없이 리베이스는 자주 리베이스를 요구하는 선형적인 워크플로우를 가진 프로젝트에서 리소스를 절약합니다.

관련 주제