병합 요청 문제 해결

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

병합 요청 작업 중 다음과 같은 문제가 발생할 수 있습니다.

병합 요청이 파이프라인 상태를 가져올 수 없음

이 문제는 Sidekiq가 변경 사항을 빠르게 처리하지 못할 경우 발생할 수 있습니다.

Sidekiq

Sidekiq가 CI 상태 변화를 빠르게 처리하지 못했습니다. 몇 초 기다리면 상태가 자동으로 업데이트될 것입니다.

파이프라인 상태를 가져올 수 없음

다음과 같은 경우에 병합 요청 파이프라인 상태를 가져올 수 없습니다:

  1. 병합 요청이 생성됨
  2. 병합 요청이 닫힘
  3. 프로젝트에서 변경 사항이 발생함
  4. 병합 요청이 다시 열림

파이프라인 상태를 제대로 가져올 수 있도록 하려면 병합 요청을 다시 닫고 열어야 합니다.

Rails 콘솔에서 병합 요청 리베이스

Tier: Free, Premium, Ultimate

/rebase 퀵 액션 외에도, Rails 콘솔에 접근할 수 있는 사용자는 Rails 콘솔에서 병합 요청을 리베이스할 수 있습니다. <username>, <namespace/project>, <iid>를 적절한 값으로 교체하세요:

caution
데이터를 직접 변경하는 명령은 올바르게 실행되지 않거나 올바른 조건에서 실행되지 않을 경우 손상을 초래할 수 있습니다. 항상 테스트 환경에서 인스턴스를 백업한 후 준비하여 실행하는 것을 권장합니다.
u = User.find_by_username('<username>')
p = Project.find_by_full_path('<namespace/project>')
m = p.merge_requests.find_by(iid: <iid>)
MergeRequests::RebaseService.new(project: m.target_project, current_user: u).execute(m)

잘못된 병합 요청 상태 수정

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

변경 사항이 병합된 후에도 병합 요청이 열림 상태로 남아 있는 경우, Rails 콘솔에 접근할 수 있는 사용자는 병합 요청의 상태를 수정할 수 있습니다. <username>, <namespace/project>, <iid>를 적절한 값으로 교체하세요:

caution
데이터를 직접 변경하는 명령은 올바르게 실행되지 않거나 올바른 조건에서 실행되지 않을 경우 손상을 초래할 수 있습니다. 항상 테스트 환경에서 인스턴스를 백업한 후 준비하여 실행하는 것을 권장합니다.
u = User.find_by_username('<username>')
p = Project.find_by_full_path('<namespace/project>')
m = p.merge_requests.find_by(iid: <iid>)
MergeRequests::PostMergeService.new(project: p, current_user: u).execute(m)

이 명령을 병합되지 않은 변경 사항이 있는 병합 요청에 대해 실행하면, 병합 요청이 잘못된 메시지를 표시하게 됩니다: merged into <branch-name>.

Rails 콘솔에서 병합 요청 닫기

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

UI 또는 API를 통해 병합 요청을 닫을 수 없는 경우, Rails 콘솔 세션에서 시도해 볼 수 있습니다:

caution
데이터를 변경하는 명령은 올바르게 실행되지 않거나 올바른 조건에서 실행되지 않을 경우 손상을 유발할 수 있습니다. 항상 먼저 테스트 환경에서 명령을 실행하고 복구할 준비가 된 백업 인스턴스를 보유하세요.
u = User.find_by_username('<username>')
p = Project.find_by_full_path('<namespace/project>')
m = p.merge_requests.find_by(iid: <iid>)
MergeRequests::CloseService.new(project: p, current_user: u).execute(m)

머지 요청 삭제하기 (Rails 콘솔에서)

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

UI 또는 API를 통해 머지 요청 삭제가 작동하지 않는 경우, Rails 콘솔 세션에서 삭제를 시도할 수 있습니다:

caution
데이터를 직접 변경하는 모든 명령은 올바르지 않게 실행하거나 적절한 조건에서 실행되지 않을 경우 손상을 초래할 수 있습니다.
우리는 인스턴스의 백업이 준비되어 있는 테스트 환경에서 실행할 것을 적극 권장합니다.
u = User.find_by_username('<username>')
p = Project.find_by_full_path('<namespace/project>')
m = p.merge_requests.find_by(iid: <iid>)
Issuable::DestroyService.new(container: m.project, current_user: u).execute(m)

머지 요청 사전 수신 후크 실패

머지 요청이 타임아웃되면, Puma 작업자 타임아웃 문제를 나타내는 메시지를 볼 수 있습니다:

  • GitLab UI에서:

    머지 사전 수신 후크 중 오류가 발생했습니다.
    500 내부 서버 오류. 다시 시도하세요.
    
  • gitlab-rails/api_json.log 로그 파일에서:

    Rack::Timeout::RequestTimeoutException
    요청이 60000ms 이상 실행되었습니다
    

이 오류는 머지 요청이 다음과 같은 경우 발생할 수 있습니다:

  • 많은 차이를 포함하고 있습니다.
  • 대상 브랜치에 대해 많은 커밋이 뒤쳐져 있습니다.
  • 잠겨 있는 Git LFS 파일을 참조합니다.

자체 관리 설치에서 사용자는 관리자에게 서버 로그 검토를 요청하여 오류의 원인을 파악할 수 있습니다. GitLab SaaS 사용자는 지원팀에 연락하여 도움을 요청해야 합니다.

캐시된 머지 요청 수

그룹에서 사이드바는 열려 있는 머지 요청의 총 수를 표시합니다. 이 값은 1000보다 클 경우 캐시됩니다. 캐시된 값은 천 단위(또는 백만 단위)로 반올림되며 24시간마다 업데이트됩니다.

head ref를 통해 로컬에서 머지 요청 확인하기

  • 머지 요청이 닫히거나 병합된 후 14일이 지나면 head refs를 삭제합니다 자체 관리 및 GitLab.com에서 활성화됨 GitLab 16.4에서.
  • 머지 요청이 닫히거나 병합된 후 14일이 지나면 head refs를 삭제합니다 일반 사용 가능 GitLab 16.6에서. 기능 플래그 merge_request_refs_cleanup이 제거되었습니다.

머지 요청은 저장소의 모든 이력과 머지 요청과 관련된 브랜치에 추가된 커밋을 포함합니다. 로컬에서 머지 요청을 확인하는 몇 가지 방법은 다음과 같습니다.

소스 프로젝트가 대상 프로젝트의 포크(비공식 포크 포함)인 경우에도 로컬에서 머지 요청을 확인할 수 있습니다.

이는 머지 요청마다 사용 가능한 머지 요청 head ref(refs/merge-requests/:iid/head)에 의존합니다. 이를 통해 브랜치가 아닌 ID를 사용하여 머지 요청을 확인할 수 있습니다.

GitLab 16.6 이후, 머지 요청 head ref는 머지 요청이 닫히거나 병합된 후 14일이 지나면 삭제됩니다. 이후 머지 요청은 더 이상 머지 요청 head ref에서 로컬 확인을 할 수 없습니다. 머지 요청은 여전히 재개할 수 있습니다. 머지 요청의 브랜치가 존재한다면, 해당 브랜치는 영향을 받지 않으므로 여전히 체크아웃할 수 있습니다.

로컬에서 glab를 사용하여 체크 아웃

glab mr checkout <merge_request_iid>

GitLab 터미널 클라이언트에 대한 자세한 정보는 여기를 참조하세요.

Git 별칭을 추가하여 로컬에서 체크 아웃

다음 별칭을 ~/.gitconfig에 추가하세요:

[alias]
    mr = !sh -c 'git fetch $1 merge-requests/$2/head:mr-$1-$2 && git checkout mr-$1-$2' -

이제 모든 리포지토리와 모든 원격에서 특정 병합 요청을 체크 아웃할 수 있습니다.

예를 들어, origin 원격에서 GitLab에 표시된 ID 5의 병합 요청을 체크 아웃하려면 다음을 수행하세요:

git mr origin 5

이 명령은 병합 요청을 로컬 mr-origin-5 브랜치로 가져오고 체크 아웃합니다.

주어진 리포지토리의 .git/config를 수정하여 로컬에서 체크 아웃

.git/config 파일에서 GitLab 원격에 대한 섹션을 찾습니다. 다음과 같이 보입니다:

[remote "origin"]
  url = https://gitlab.com/gitlab-org/gitlab-foss.git
  fetch = +refs/heads/*:refs/remotes/origin/*

다음 명령으로 파일을 열 수 있습니다:

git config -e

이제 위의 섹션에 다음 행을 추가하세요:

fetch = +refs/merge-requests/*/head:refs/remotes/origin/merge-requests/*

결국 다음과 같아야 합니다:

[remote "origin"]
  url = https://gitlab.com/gitlab-org/gitlab-foss.git
  fetch = +refs/heads/*:refs/remotes/origin/*
  fetch = +refs/merge-requests/*/head:refs/remotes/origin/merge-requests/*

이제 모든 병합 요청을 가져올 수 있습니다:

git fetch origin

...
From https://gitlab.com/gitlab-org/gitlab-foss.git
 * [new ref]         refs/merge-requests/1/head -> origin/merge-requests/1
 * [new ref]         refs/merge-requests/2/head -> origin/merge-requests/2
...

특정 병합 요청을 체크 아웃하려면:

git checkout origin/merge-requests/1

위의 모든 작업은 git-mr 스크립트를 사용하여 수행할 수 있습니다.

오류: “소스 브랜치 <branch_name>가 존재하지 않습니다.” (브랜치가 존재하는 경우)

이 오류는 GitLab 캐시가 Git 리포지토리의 실제 상태를 반영하지 않을 때 발생할 수 있습니다. 이는 Git 데이터 폴더가 noexec 플래그로 마운트되어 있을 때 발생할 수 있습니다.

필수 조건:

  • 관리자가 되어야 합니다.

캐시 업데이트를 강제로 수행하려면:

  1. 다음 명령으로 GitLab Rails 콘솔을 엽니다:

    sudo gitlab-rails console
    
  2. Rails 콘솔에서 다음 스크립트를 실행합니다:

    # 프로젝트 가져오기
    project = Project.find_by_full_path('affected/project/path')
    
    # 캐시에서 영향을 받는 브랜치가 존재하는지 확인 (false를 반환할 수 있음)
    project.repository.branch_names.include?('affected_branch_name')
    
    # 브랜치 캐시 만료
    project.repository.expire_branches_cache
    
    # 영향을 받는 브랜치가 캐시에 존재하는지 다시 확인 (이번에는 true를 반환해야 함)
    project.repository.branch_names.include?('affected_branch_name')
    
  3. 병합 요청을 새로 고침합니다.