구현 세부 사항이 너무 많이 포함되지 않은 것은 의도적이며, 변경될 수 있는 부분입니다. 이러한 세부 사항은 코드가 더 잘 설명합니다. 여기 언급된 구성 요소는 병합 요청 차이가 생성, 저장 및 사용자에게 반환되는 방식에서 애플리케이션의 주요 부분입니다.
참고:
이 페이지는 살아있는 문서입니다. 이 문서에서 다루는 코드베이스의 부분이 변경되거나 제거될 때, 또는 새로운 구성 요소가 추가될 때 적절히 업데이트하세요.
데이터 모델
네 개의 주요 ActiveRecord 모델은 우리가 _diffs_라고 통칭하는 것을 나타냅니다. 이 데이터베이스 기반 레코드는 프로젝트의 Git 저장소에 포함된 데이터를 복제하며, Gitaly에 대한 과도한 접근 요청을 방지하는 캐시 역할을 합니다. 또한, 다음에 대한 논리적 위치를 제공합니다:
차이에 대한 메타데이터를 계산하고 검색합니다.
일반적인 클래스 및 인스턴스 기반 논리입니다.
MergeRequestDiff
MergeRequestDiff는 app/models/merge_request_diff.rb에 정의되어 있습니다. 이 클래스는 일련의 커밋으로부터 발생한 차이에 대한 메타데이터 및 컨텍스트를 보유합니다. 이는 차이 내용, 개별 커밋, 변경 사항이 포함된 파일과 상호작용하기 위한 주요 수단이 되는 메서드를 정의합니다.
모든 MergeRequestDiffCommit는 ActiveRecord 용어에서 :belongs_to로 정의된 해당 MergeRequest::DiffCommitUser 레코드가 있습니다. 이러한 레코드는 :commit_author와 :committer이며, 서로 다른 개인일 수 있습니다.
MergeRequest::DiffCommitUser
MergeRequest::DiffCommitUser는 app/models/merge_request/diff_commit_user.rb에 정의되어 있습니다.
이 클래스는 주어진 커밋의 name과 email을 기록하지만 User 레코드와의 연결은 포함되어 있지 않습니다.
연관된 MergeRequestDiff 레코드는 MergeRequestDiff 생성 시 stored_externally 속성을 true로 설정합니다.
ScheduleMigrateExternalDiffsWorker라는 cron 작업은 매시간 15분에 예약되어 있습니다.
이는 여전히 데이터베이스에 저장된 diff를 외부 저장소로 이동합니다.
MergeRequestDiffDetail
MergeRequestDiffDetail는 app/models/merge_request_diff_detail.rb에 정의되어 있습니다.
이 클래스는 Geo 복제를 위한 검증 정보를 제공하지만, 사용자에게 표시되는 diff에는 사용되지 않습니다.
#<MergeRequestDiffFile:0x00007fd1ef7c9048merge_request_diff_id: 28,relative_order: 0,new_file: true,renamed_file: false,deleted_file: false,too_large: false,a_mode: "0",b_mode: "100644",new_path: "files/ruby/feature.rb",old_path: "files/ruby/feature.rb",diff:
"@@ -0,0 +1,4 @@\n+# 이 파일은 기능 브랜치에서 변경되었습니다.\n+# 우리는 병합 충돌을 피하기 위해 서로 다른 코드를 여기에 넣습니다.\n+class Conflict\n+end\n",binary: false,external_diff_offset: nil,external_diff_size: nil>
흐름
이 흐름도는 다양한 기능에 대한 컨트롤러에서 모델로의 흐름을 설명하는 데 도움이 됩니다. 이 페이지는 접근 방법과 diff 작업에 대한 모든 옵션을 문서화하는 것이 아니라 가장 일반적인 것에만 집중합니다.
MergeRequestDiff* 레코드 생성
위에서 설명한 바와 같이, 우리는 병합 요청에서 diffs를 표시할 때 Gitaly의 정보를 캐시하기 위해 데이터베이스 테이블을 사용합니다. 활성화되면 diffs를 저장할 때 오브젝트 스토리지도 사용합니다.
우리는 두 가지 유형의 병합 요청 diff가 있습니다: 기본 diff와 HEAD diff. 각 유형은 다르게 생성됩니다.
기본 diff
병합 요청 브랜치에 푸시할 때마다 새 병합 요청 diff 버전을 생성합니다.
이 흐름도는 이 경우 각 구성 요소가 어떻게 사용되는지에 대한 기본 설명을 보여줍니다.
이 시퀀스 다이어그램은 이 흐름에 대한 더 자세한 설명을 보여줍니다.
HEAD diff
병합 요청의 병합 가능성이 확인될 때마다 병합 요청의 merge_status가 :unchecked, :cannot_be_merged_recheck, :checking, :cannot_be_merged_rechecking 중 하나일 경우,
소스 브랜치에서 대상 브랜치로 변경 사항을 병합하고 참조에 기록하려고 시도합니다.
성공적일 경우(즉, 충돌이 없는 경우),
생성된 커밋을 기반으로 차이를 생성하고 이를 HEAD diff로 표시합니다.
이 흐름은 다른 진입점이 있기 때문에 기본 차이 생성과 다릅니다.
이 순서도는 HEAD diff를 생성할 때 각 구성 요소가 어떻게 사용되는지를 간단히 설명합니다.
이 시퀀스 다이어그램은 이 흐름에 대한 보다 상세한 설명을 보여줍니다.
diffs_batch.json
가장 일반적인 diffs 뷰 방법은 GitLab UI의 병합 요청 페이지 상단에 있는 Changes 탭입니다. 이 탭을 선택하면 diffs 자체가 /-/merge_requests/:id/diffs_batch.json에 대한 페이지 기반 요청을 통해 로드되며, 이는 Projects::MergeRequests::DiffsController#diffs_batch에서 제공됩니다.
이 플로우차트는 각 구성 요소가 diffs_batch.json 요청에서 어떻게 사용되는지를 기본적으로 설명합니다.
하지만, diffs를 볼 때는 다양한 경우가 있으며, 각 경우에 따라 플로우가 다릅니다.
HEAD, 최신 또는 특정 diff 버전 보기
HEAD diff는 사용 가능한 경우 기본적으로 표시됩니다. 그렇지 않은 경우 최신 diff 버전으로 대체됩니다. 특정 diff 버전을 보는 것도 가능합니다. 이 경우에는 동일한 플로우가 적용됩니다.
그러나 Show whitespace changes가 선택되지 않은 경우 diffs를 볼 때:
공백 변경 사항이 무시됩니다.
플로우가 변경되며 이제 Gitaly가 포함됩니다.
병합 요청의 차이 버전 비교
차이 버전을 볼 때 서로 다른 차이 버전을 비교할 수도 있습니다.
흐름은 기본 흐름과 다르며, 두 개의 차이 버전 간 비교를 생성하기 위해 Gitaly에 요청을 합니다.
또한 강조 및 통계 캐시를 위해 Redis를 사용하지 않습니다.
커밋 차이 보기
병합 요청 차이를 보는 또 다른 기능은 특정 커밋의 차이를 보는 것입니다.
이는 기본 흐름과 다르며, 특정 커밋의 차이를 가져오기 위해 Gitaly가 필요합니다.
또한 강조 및 통계 캐시를 위해 Redis를 사용하지 않습니다.
diffs.json
머지 요청을 생성하는 동안 하단으로 스크롤하여 Changes 탭을 클릭하면
diffs를 볼 수도 있습니다.
이 시점에서는 머지 요청 기록이 생성되지 않았기 때문에 diffs_batch.json
엔드포인트를 사용하지 않습니다. 대신 diffs.json을 사용합니다.
이 플로우차트는 각 구성 요소가 diffs.json 요청에서 어떻게 사용되는지에 대한
기본 설명을 보여줍니다.