머지 리퀘스트 문제 해결
GitLab v19.5Offering: GitLab Self-Managed, GitLab Dedicated
요약
머지 리퀘스트를 사용할 때 다음과 같은 문제가 발생할 수 있습니다. Sidekiq 이 변경 사항을 충분히 빠르게 반영하지 못할 때 발생할 수 있습니다. Sidekiq 이 CI 상태 변경을 충분히 빠르게 처리하지 못한 경우입니다.
머지 리퀘스트를 사용할 때 다음과 같은 문제가 발생할 수 있습니다.
머지 리퀘스트에서 파이프라인 상태를 가져올 수 없음#
Sidekiq 이 변경 사항을 충분히 빠르게 반영하지 못할 때 발생할 수 있습니다.
Sidekiq#
Sidekiq 이 CI 상태 변경을 충분히 빠르게 처리하지 못한 경우입니다. 몇 초 기다리면 상태가 자동으로 갱신됩니다.
파이프라인 상태를 가져올 수 없음#
다음 순서로 진행되면 머지 리퀘스트 파이프라인 상태를 가져올 수 없습니다.
- 머지 리퀘스트를 생성합니다
- 해당 머지 리퀘스트를 닫습니다
- 프로젝트에서 변경 사항이 발생합니다
- 해당 머지 리퀘스트를 다시 엽니다
파이프라인 상태를 정상적으로 가져오려면 머지 리퀘스트를 다시 닫았다가 여는 과정을 한 번 더 수행합니다.
Rails 콘솔에서 머지 리퀘스트 리베이스#
/rebase 빠른 동작 외에도,
Rails 콘솔에 접근할 수 있는 사용자는
Rails 콘솔에서 머지 리퀘스트를 리베이스할 수 있습니다. <username>,
<namespace/project>, <iid>는 실제 값으로 바꿉니다.
데이터를 직접 변경하는 명령은 올바르게 실행하지 않거나 적절한 조건이 아닐 때 손상을 일으킬 수 있습니다. 만약을 대비해 복원할 수 있는 인스턴스 백업을 준비한 테스트 환경에서 실행할 것을 강력히 권장합니다.
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)
잘못된 머지 리퀘스트 상태 수정#
변경 사항이 머지된 뒤에도 머지 리퀘스트가 Open 상태로 남아 있다면,
Rails 콘솔에 접근할 수 있는 사용자가
머지 리퀘스트의 상태를 바로잡을 수 있습니다. <username>, <namespace/project>,
<iid>는 실제 값으로 바꿉니다.
데이터를 직접 변경하는 명령은 올바르게 실행하지 않거나 적절한 조건이 아닐 때 손상을 일으킬 수 있습니다. 만약을 대비해 복원할 수 있는 인스턴스 백업을 준비한 테스트 환경에서 실행할 것을 강력히 권장합니다.
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 콘솔에서 머지 리퀘스트 닫기#
UI 나 API로 머지 리퀘스트가 닫히지 않는다면 Rails 콘솔 세션에서 닫아 봅니다.
데이터를 변경하는 명령은 올바르게 실행하지 않거나 적절한 조건이 아닐 때 손상을 일으킬 수 있습니다. 항상 테스트 환경에서 먼저 실행하고 복원할 수 있는 인스턴스 백업을 준비합니다.
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 콘솔에서 머지 리퀘스트 삭제#
UI 나 API로 머지 리퀘스트가 삭제되지 않는다면 Rails 콘솔 세션에서 삭제해 봅니다.
데이터를 직접 변경하는 명령은 올바르게 실행하지 않거나 적절한 조건이 아닐 때 손상을 일으킬 수 있습니다. 만약을 대비해 복원할 수 있는 인스턴스 백업을 준비한 테스트 환경에서 실행할 것을 강력히 권장합니다.
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)
머지 리퀘스트 pre-receive 훅 실패#
머지 리퀘스트가 타임아웃되면 Puma 워커 타임아웃 문제를 나타내는 메시지가 표시될 수 있습니다.
-
GitLab UI에서는 다음과 같이 표시됩니다.
Something went wrong during merge pre-receive hook. 500 Internal Server Error. Try again. -
gitlab-rails/api_json.log로그 파일에서는 다음과 같이 표시됩니다.Rack::Timeout::RequestTimeoutException Request ran for longer than 60000ms
이 오류는 머지 리퀘스트가 다음 조건에 해당할 때 발생할 수 있습니다.
- diff가 많습니다.
- 대상 브랜치보다 커밋이 많이 뒤처져 있습니다.
- 잠긴 Git LFS 파일을 참조합니다.
GitLab Self-Managed 사용자는 관리자에게 서버 로그 검토를 요청해 오류 원인을 파악할 수 있습니다. GitLab.com 사용자는 지원팀에 문의해 도움을 받습니다.
캐시된 머지 리퀘스트 수#
그룹에서는 사이드바에 열린 머지 리퀘스트의 총개수가 표시됩니다. 이 값이 1000을 넘으면 캐시됩니다. 캐시된 값은 천 단위(또는 백만 단위)로 반올림되며 24시간마다 갱신됩니다.
head ref를 통해 로컬에서 머지 리퀘스트 체크아웃#
머지 리퀘스트에는 리포지터리의 모든 히스토리와, 머지 리퀘스트에 연결된 브랜치에 추가된 커밋이 함께 담깁니다. 로컬에서 머지 리퀘스트를 체크아웃하는 방법은 다음과 같습니다.
소스 프로젝트가 대상 프로젝트의 포크(비공개 포크 포함)여도 로컬에서 머지 리퀘스트를 체크아웃할 수 있습니다.
이는 머지 리퀘스트마다 제공되는 머지 리퀘스트 head ref
(refs/merge-requests/:iid/head)를 활용한 방식입니다. 브랜치 대신 ID를 사용해
머지 리퀘스트를 체크아웃할 수 있습니다.
머지 리퀘스트 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' -
이제 어떤 리포지터리와 원격에서든 특정 머지 리퀘스트를 체크아웃할 수 있습니다.
예를 들어 GitLab에 표시된 ID 5 인 머지 리퀘스트를 origin 원격에서
체크아웃하려면 다음 명령을 실행합니다.
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 스크립트로도 실행할 수 있습니다.
오류: 브랜치가 존재할 때 source branch <branch_name> does not exist.#
이 오류는 GitLab 캐시가 Git 리포지터리의 실제 상태를 반영하지 못할 때 발생할 수
있습니다. Git 데이터 폴더가 noexec 플래그로 마운트된 경우에도 발생할 수 있습니다.
사전 요구 사항:
- 관리자여야 합니다.
캐시를 강제로 갱신하려면 다음 단계를 수행합니다.
-
다음 명령으로 GitLab Rails 콘솔을 엽니다.
sudo gitlab-rails console -
Rails 콘솔에서 다음 스크립트를 실행합니다.
# Get the project project = Project.find_by_full_path('affected/project/path') # Check if the affected branch exists in cache (it may return `false`) project.repository.branch_names.include?('affected_branch_name') # Expire the branches cache project.repository.expire_branches_cache # Check again if the affected branch exists in cache (this time it should return `true`) project.repository.branch_names.include?('affected_branch_name') -
머지 리퀘스트를 새로 고칩니다.
자동화가 머지 리퀘스트를 승인할 때 승인 재설정#
머지 리퀘스트 생성이나 푸시를 자동화한다면 해당 머지 리퀘스트의 승인도 자동화하고 싶을 수 있습니다. GitLab Premium과 Ultimate에서는 기본적으로 소스 브랜치에 커밋이 추가되면 모든 승인이 제거됩니다. 이 문제를 피하려면 머지 리퀘스트를 승인하기 전에 커밋이 처리되도록 하는 로직을 자동화에 추가합니다.
머지 리퀘스트가 예상치 않게 Merged로 표시됨#
머지된 머지 리퀘스트에 merged manually 시스템 메모가 있다면, 소스 브랜치의 커밋이
GitLab UI 외부에서 머지되었거나 다른 머지 리퀘스트의 일부로 머지된 것입니다.
GitLab UI 외부에서 머지됨#
UI 외부에서 git merge로 브랜치를 대상 브랜치에 직접 머지하면,
GitLab 이 이 작업을 감지해 해당 머지 리퀘스트를 merged manually로 표시합니다.
이런 상황은 대상 브랜치로의 직접 푸시가 허용된 경우에 발생할 수 있습니다. 이를 방지하려면 대상 브랜치를 보호하고 직접 푸시를 허용하지 않도록 구성합니다 (Allowed to push and merge를 No one으로 설정).
자세한 내용은 브랜치 보호를 참고합니다.
다른 머지 리퀘스트의 일부로 머지됨#
해당 머지 리퀘스트에 다른 머지 리퀘스트의 일부로 이미 머지된 커밋이 포함된 경우입니다. 보호된 브랜치에서 이런 상황이 발생했다면, 보호된 브랜치 설정에 따라 커밋이 머지되기 전에 승인을 거친 것입니다.
자세한 내용은 같은 커밋을 포함한 여러 브랜치를 참고합니다.
경우에 따라 GitLab 이 Merged with !<merge_request_id> 대신 merged manually를 표시할 수 있습니다.
자세한 내용은 이슈 456426을 참고합니다.