병합 요청 차이점 개발 가이드
이 문서에서는 병합 요청 차이점의 백엔드 설계와 흐름을 설명합니다.
기여자들이 다음을 이해하는 데 도움이 될 것입니다:
- 코드 디자인을 이해합니다.
- 개선을 통해 기여할 수 있는 부분을 식별합니다.
구현 세부 정보가 많이 없어서 일부러 고의로 변경되는 것이 일반적입니다. 코드가 이러한 세부 사항을 더 잘 설명합니다. 여기서 언급된 구성 요소는 병합 요청 차이점이 생성되고 저장되며 사용자에게 반환되는 방식에 대한 응용 프로그램의 주요 부분입니다.
참고:
이 페이지는 계속 업데이트되는 문서입니다. 이 문서에서 다루는 코드베이스의 부분이 변경되거나 제거되거나 새로운 구성 요소가 추가될 때 이에 맞게 업데이트하세요.
데이터 모델
네 개의 주요 ActiveRecord 모델은 우리가 _차이_로 통칭하는 것을 나타냅니다. 이러한 데이터베이스 지원 레코드는 프로젝트의 Git 저장소에 포함된 데이터를 복제하고 Gitaly로의 과도한 액세스 요청에 대한 캐시의 역할을 하며 다음과 같은 역할을 하는 논리적인 장소를 제공합니다.
- 차이의 조각에 대한 계산 및 검색된 메타데이터.
- 일반적인 클래스 및 인스턴스 기반 로직.
erDiagram
병합 요청 ||--|{ 병합 요청 차이: ""
병합 요청 차이 |{--|{ 병합 요청 차이 커밋: ""
병합 요청 차이 |{--|| 병합 요청 차이 상세: ""
병합 요청 차이 |{--|{ 병합 요청 차이 파일: ""
병합 요청 차이 커밋 |{--|| 병합 요청 차이 커밋 사용자: ""
MergeRequestDiff
MergeRequestDiff
는 app/models/merge_request_diff.rb
에 정의되어 있습니다. 이
클래스는 커밋 집합으로부터 생긴 차이에 관련된 메타데이터와 컨텍스트를 보유합니다. 차이 내용, 개별 커밋 및 변경 사항을 포함하는 파일과 상호 작용하는 주요 수단으로 사용되는 메소드를 정의합니다.
#<MergeRequestDiff:0x00007fd1ed63b4d0
id: 28,
state: "collected",
merge_request_id: 28,
created_at: Tue, 06 Sep 2022 18:56:02.509469000 UTC +00:00,
updated_at: Tue, 06 Sep 2022 18:56:02.754201000 UTC +00:00,
base_commit_sha: "ae73cb07c9eeaf35924a10f713b364d32b2dd34f",
real_size: "9",
head_commit_sha: "bb5206fee213d983da88c47f9cf4cc6caf9c66dc",
start_commit_sha: "0b4bc9a49b562e85de7cc9e834518ea6828729b9",
commits_count: 6,
external_diff: "diff-28",
external_diff_store: 1,
stored_externally: nil,
files_count: 9,
patch_id_sha: "d504412d5b6e6739647e752aff8e468dde093f2f",
sorted: true,
diff_type: "regular",
verification_checksum: nil>
차이 내용은 보통이 이 클래스를 통해 액세스됩니다. 사용자에게 반환되기 전에 차이, 파일 및 커밋 내용에 대해 로직이 종종 적용됩니다.
MergeRequestDiff#commits_count
MergeRequestDiff
이 저장될 때, 연관된 MergeRequestDiffCommit
레코드가
세어지고 commits_count
열에 캐시됩니다. 이 숫자는 커밋 탭에 대한 카운터로 병합 요청 페이지에 표시됩니다.
MergeRequestDiffCommit
레코드가 삭제되면 카운터가 업데이트되지 않습니다.
MergeRequestDiffCommit
MergeRequestDiffCommit
은 app/models/merge_request_diff_commit.rb
에서 정의되어 있습니다.
이 클래스는 해당 MergeRequestDiff
에 포함된 단일 커밋에 해당하며 커밋에 대한 헤더 정보를 보유합니다.
#<MergeRequestDiffCommit:0x00007fd1dfc6c4c0
authored_date: Wed, 06 Aug 2022 06:35:52.000000000 UTC +00:00,
committed_date: Wed, 06 Aug 2022 06:35:52.000000000 UTC +00:00,
merge_request_diff_id: 28,
relative_order: 0,
sha: "bb5206fee213d983da88c47f9cf4cc6caf9c66dc",
message: "Feature conflcit added\n\nSigned-off-by: Sample User <sample.user@example.com>\n",
trailers: {},
commit_author_id: 19,
committer_id: 19>
각 MergeRequestDiffCommit
에는 해당하는 MergeRequest::DiffCommitUser
레코드가 :commit_author
및 :committer
로 있으며 이들 레코드는 별개의 개인일 수 있습니다.
MergeRequest::DiffCommitUser
MergeRequest::DiffCommitUser
은 app/models/merge_request/diff_commit_user.rb
에 정의되어 있습니다.
이는 주어진 커밋의 name
과 email
을 캡처하지만 자체적으로 어떤 User
레코드와도 연결되지 않습니다.
#<MergeRequest::DiffCommitUser:0x00007fd1dff7c930
id: 19,
name: "Sample User",
email: "sample.user@example.com">
MergeRequestDiffFile
MergeRequestDiffFile
은 app/models/merge_request_diff_file.rb
에 정의되어 있습니다. 이 클래스의 레코드는 MergeRequestDiff
에 포함된 단일 파일의 차이를 나타냅니다. 변경과 관련된 파일의 메타 및 구체적인 정보를 보유하고 있으며 다음과 같은 내용을 포함합니다.
- 추가되었는지 또는 이름이 변경되었는지 여부.
- 차이에서의 순서.
- 실제 차이 출력 자체.
외부 차이 저장
기본적으로 MergeRequestDiffFile
의 차이 데이터는 merge_request_diff_files
테이블의 diff
열에 저장됩니다. 일부 설치에서는 테이블이 커져서 공간을 절약하기 위해 diff를 외부 저장소에 저장하도록 구성되어 있습니다. 이를 구성하려면 Merge request diffs storage를 참조하세요.
외부 저장소를 사용하도록 구성된 경우:
- 데이터베이스의
diff
열은 NULL
로 남겨집니다.
- 연결된
MergeRequestDiff
레코드는 MergeRequestDiff
생성 시에 stored_externally
속성을 true
로 설정합니다.
또한 ScheduleMigrateExternalDiffsWorker
라는 cron 작업이 매 시간의 15분에 예약되어 있습니다. 이 작업은 데이터베이스에 아직 저장된 diff
를 외부 저장소로 이관합니다.
MergeRequestDiffDetail
MergeRequestDiffDetail
은 app/models/merge_request_diff_detail.rb
에 정의되어 있습니다. 이 클래스는 Geo 복제의 확인 정보를 제공하지만 그 이외에는 사용자가 볼 수 있는 차이에는 사용되지 않습니다.
플로우
이러한 플로차트는 컨트롤러에서 다양한 기능에 대한 모델로의 플로우를 설명하는 데 도움이 될 것입니다. 이 페이지는 차이에 액세스하고 다루는 옵션을 완전히 문서화하는 것이 아니라 대부분 가장 흔한 경우에 중점을 둡니다.
MergeRequestDiff*
레코드의 생성
위에서 설명한 대로, 우리는 병합 리퀘스트에서 diff를 표시할 때 Gitaly에서 정보를 캐시하기 위해 데이터베이스 테이블을 사용합니다. 활성화되면 차이를 저장할 때 객체 저장소도 사용합니다.
우리에게는 2 종류의 병합 리퀘스트 diff가 있습니다: 기본 diff와 HEAD
diff. 각 유형은 서로 다르게 생성됩니다.
기본 diff
병합 리퀘스트 브랜치로 푸시할 때마다 새로운 병합 리퀘스트 diff 버전을 생성합니다.
이 플로차트는 이 경우 각 구성 요소가 어떻게 사용되는 지에 대한 기본적인 설명을 보여줍니다.
flowchart TD
A[PostReceive worker] --> B[MergeRequests::RefreshService]
B --> C[Reload diff of merge requests]
C --> D[Create merge request diff]
D --> K[(Database)]
D --> E[Ensure commit SHAs]
E --> L[Gitaly]
E --> F[Set patch-id]
F --> L[Gitaly]
F --> G[Save commits]
G --> L[Gitaly]
G --> K[(Database)]
G --> H[Save diffs]
H --> L[Gitaly]
H --> K[(Database)]
H --> M[(Object Storage)]
H --> I[Keep around commits]
I --> L[Gitaly]
I --> J[Clear highlight and stats cache]
J --> N[(Redis)]
이 순서 다이어그램은 이 플로우의 더 자세한 설명을 보여줍니다.
sequenceDiagram
PostReceive-->>+MergeRequests_RefreshService: execute()
Note over MergeRequests_RefreshService: Reload diff of merge requests
MergeRequests_RefreshService-->>+MergeRequest: reload_diff()
Note over MergeRequests_ReloadDiffsService: Create merge request diff
MergeRequest-->>+MergeRequests_ReloadDiffsService: execute()
MergeRequests_ReloadDiffsService-->>+MergeRequest: create_merge_request_diff()
MergeRequest-->>+MergeRequestDiff: create()
Note over MergeRequestDiff: Ensure commit SHAs
MergeRequestDiff-->>+MergeRequest: source_branch_sha()
MergeRequest-->>+Repository: commit()
Repository-->>+Gitaly: FindCommit RPC
Gitaly-->>-Repository: Gitlab::Git::Commit
Repository-->>+Commit: new()
Commit-->>-Repository: Commit
Repository-->>-MergeRequest: Commit
MergeRequest-->>-MergeRequestDiff: Commit SHA
Note over MergeRequestDiff: Set patch-id
MergeRequestDiff-->>+Repository: get_patch_id()
Repository-->>+Gitaly: GetPatchID RPC
Gitaly-->>-Repository: Patch ID
Repository-->>-MergeRequestDiff: Patch ID
Note over MergeRequestDiff: Save commits
MergeRequestDiff-->>+Gitaly: ListCommits RPC
Gitaly-->>-MergeRequestDiff: Commits
MergeRequestDiff-->>+MergeRequestDiffCommit: create_bulk()
Note over MergeRequestDiff: Save diffs
MergeRequestDiff-->>+Gitaly: ListCommits RPC
Gitaly-->>-MergeRequestDiff: Commits
opt When external diffs is enabled
MergeRequestDiff-->>+ObjectStorage: upload diffs
end
MergeRequestDiff-->>+MergeRequestDiffFile: legacy_bulk_insert()
Note over MergeRequestDiff: Keep around commits
MergeRequestDiff-->>+Repository: keep_around()
Repository-->>+Gitaly: WriteRef RPC
Note over MergeRequests_ReloadDiffsService: Clear highlight and stats cache
MergeRequests_ReloadDiffsService->>+Gitlab_Diff_HighlightCache: clear()
MergeRequests_ReloadDiffsService->>+Gitlab_Diff_StatsCache: clear()
Gitlab_Diff_HighlightCache-->>+Redis: cache
Gitlab_Diff_StatsCache-->>+Redis: cache
HEAD
차이
병합 요청의 병합 가능성을 확인하고 병합 요청 merge_status
가 :unchecked
, :cannot_be_merged_recheck
, :checking
, 또는 :cannot_be_merged_rechecking
중 하나인 경우, 소스 브랜치에서 대상 브랜치로 변경 내용을 통합하고 ref에 기록을 시도합니다. 성공하면(즉, 충돌이 없으면) 생성된 커밋을 기반으로 HEAD
차이를 생성하고 표시합니다.
기본적인 차이 생성 방법과는 다른 흐름을 가지고 있으며 다른 진입점이 있습니다.
이 플로차트는 HEAD
차이를 생성할 때 각 구성 요소가 어떻게 사용되는지에 대한 기본적인 설명을 보여줍니다.
flowchart TD
A[MergeRequestMergeabilityCheckWorker] --> B[MergeRequests::MergeabilityCheckService]
B --> C[Merge changes to ref]
C --> L[Gitaly]
C --> D[Recreate merge request HEAD diff]
D --> K[(Database)]
D --> E[Ensure commit SHAs]
E --> L[Gitaly]
E --> F[Set patch-id]
F --> L[Gitaly]
F --> G[Save commits]
G --> L[Gitaly]
G --> K[(Database)]
G --> H[Save diffs]
H --> L[Gitaly]
H --> K[(Database)]
H --> M[(Object Storage)]
H --> I[Keep around commits]
I --> L[Gitaly]
이 시퀀스 다이어그램은 이러한 흐름에 대한 더 자세한 설명을 보여줍니다.
sequenceDiagram
MergeRequestMergeabilityCheckWorker-->>+MergeRequests_MergeabilityCheckService: execute()
Note over MergeRequests_MergeabilityCheckService: Merge changes to ref
MergeRequests_MergeabilityCheckService-->>+MergeRequests_MergeToRefService: execute()
MergeRequests_MergeToRefService-->>+Repository: merge_to_ref()
Repository-->>+Gitaly: UserMergeBranch RPC
Gitaly-->>-Repository: Commit SHA
MergeRequests_MergeToRefService-->>+Repository: commit()
Repository-->>+Gitaly: FindCommit RPC
Gitaly-->>-Repository: Gitlab::Git::Commit
Repository-->>+Commit: new()
Commit-->>-Repository: Commit
Repository-->>-MergeRequests_MergeToRefService: Commit
Note over MergeRequests_MergeabilityCheckService: Recreate merge request HEAD diff
MergeRequests_MergeabilityCheckService-->>+MergeRequests_ReloadMergeHeadDiffService: execute()
MergeRequests_ReloadMergeHeadDiffService-->>+MergeRequest: create_merge_request_diff()
MergeRequest-->>+MergeRequestDiff: create()
Note over MergeRequestDiff: Ensure commit SHAs
MergeRequestDiff-->>+MergeRequest: merge_ref_head()
MergeRequest-->>+Repository: commit()
Repository-->>+Gitaly: FindCommit RPC
Gitaly-->>-Repository: Gitlab::Git::Commit
Repository-->>+Commit: new()
Commit-->>-Repository: Commit
Repository-->>-MergeRequest: Commit
MergeRequest-->>-MergeRequestDiff: Commit SHA
Note over MergeRequestDiff: Set patch-id
MergeRequestDiff-->>+Repository: get_patch_id()
Repository-->>+Gitaly: GetPatchID RPC
Gitaly-->>-Repository: Patch ID
Repository-->>-MergeRequestDiff: Patch ID
Note over MergeRequestDiff: Save commits
MergeRequestDiff-->>+Gitaly: ListCommits RPC
Gitaly-->>-MergeRequestDiff: Commits
MergeRequestDiff-->>+MergeRequestDiffCommit: create_bulk()
Note over MergeRequestDiff: Save diffs
MergeRequestDiff-->>+Gitaly: ListCommits RPC
Gitaly-->>-MergeRequestDiff: Commits
opt 외부 차이를 사용할 경우
MergeRequestDiff-->>+ObjectStorage: upload diffs
end
MergeRequestDiff-->>+MergeRequestDiffFile: legacy_bulk_insert()
Note over MergeRequestDiff: Keep around commits
MergeRequestDiff-->>+Repository: keep_around()
Repository-->>+Gitaly: WriteRef RPC
diffs_batch.json
차이를 보는 가장 일반적인 방법은 GitLab UI에서 병합 요청 페이지 상단의 Changes 탭입니다. 선택하면 차이 자체가 /-/merge_requests/:id/diffs_batch.json
로의 페이지 요청을 통해 로드되며, 이는 Projects::MergeRequests::DiffsController#diffs_batch
에서 제공됩니다.
이 플로차트는 diffs_batch.json
요청 시 각 구성 요소가 어떻게 사용되는지에 대한 기본적인 설명을 보여줍니다.
flowchart TD
A[Frontend] --> B[diffs_batch.json]
B --> C[Preload diffs and ivars]
C -->D[Gitaly]
C -->E[(Database)]
C --> F[Getting diff file collection]
C --> F[Getting diff file collection]
F --> G[Calculate unfoldable diff lines]
G --> E
G --> H{ETag header is not stale}
H --> |Yes| I[Return 304]
H --> |No| J[Serialize diffs]
J --> D
J --> E
J --> K[(Redis)]
J --> L[Return 200 with JSON]
차이를 보는 경우에는 다양한 경우가 있고, 각 경우의 흐름이 다릅니다.
HEAD, 최신 또는 특정한 diff 버전 보기
HEAD diff는 기본적으로 볼 수 있습니다. 사용할 수 없는 경우에는 최신 diff 버전으로 돌아갑니다. 또한 특정한 diff 버전을 볼 수도 있습니다. 이러한 경우들은 동일한 흐름을 가지고 있습니다.
sequenceDiagram
Frontend-->>+.#diffs_batch: API 호출
Note over .#diffs_batch: Diff 및 ivar 사전로드
.#diffs_batch-->>+.#define_diff_vars: before_action
.#define_diff_vars-->>+MergeRequest: merge_request_head_diff() 또는 merge_request_diff()
MergeRequest-->>+MergeRequestDiff: find()
MergeRequestDiff-->>-MergeRequest: MergeRequestDiff
MergeRequest-->>-.#define_diff_vars: MergeRequestDiff
.#define_diff_vars-->>-.#diffs_batch: @compare
Note over .#diffs_batch: diff 파일 컬렉션 가져오기
.#diffs_batch-->>+MergeRequestDiff: diffs_in_batch()
MergeRequestDiff-->>+Gitlab_Diff_FileCollection_MergeRequestDiffBatch: new()
Gitlab_Diff_FileCollection_MergeRequestDiffBatch-->>-MergeRequestDiff: diff 파일 컬렉션
MergeRequestDiff-->>-.#diffs_batch: diff 파일 컬렉션
Note over .#diffs_batch: 펼칠 수 있는 diff 라인 계산
.#diffs_batch-->>+MergeRequest: note_positions_for_paths
MergeRequest-->>+Gitlab_Diff_PositionCollection: new() 그리고 unfoldable()
Gitlab_Diff_PositionCollection-->>-MergeRequest: position 컬렉션
MergeRequest-->>-.#diffs_batch: unfoldable_positions
ETag 헤더가 있고 유효하지 않은 경우 중단
.#diffs_batch-->>+Frontend: 304 HTTP 반환
end
.#diffs_batch->>+Gitlab_Diff_FileCollection_MergeRequestDiffBatch: write_cache()
Gitlab_Diff_FileCollection_MergeRequestDiffBatch->>+Gitlab_Diff_HighlightCache: write_if_empty()
Gitlab_Diff_FileCollection_MergeRequestDiffBatch->>+Gitlab_Diff_StatsCache: write_if_empty()
Gitlab_Diff_HighlightCache-->>+Redis: 캐시
Gitlab_Diff_StatsCache-->>+Redis: 캐시
Note over .#diffs_batch: Diffs 직렬화 및 JSON 렌더링
.#diffs_batch-->>+PaginatedDiffSerializer: represent()
PaginatedDiffSerializer-->>+Gitlab_Diff_FileCollection_MergeRequestDiffBatch: diff_files()
Gitlab_Diff_FileCollection_MergeRequestDiffBatch-->>+MergeRequestDiff: raw_diffs()
MergeRequestDiff-->>-MergeRequestDiffFile: 모든 관련 레코드 가져오기
MergeRequestDiffFile-->>-MergeRequestDiff: Gitlab::Git::DiffCollection
MergeRequestDiff-->>-Gitlab_Diff_FileCollection_MergeRequestDiffBatch: diff 파일
Gitlab_Diff_FileCollection_MergeRequestDiffBatch-->>+Gitlab_Diff_StatsCache: find_by_path()
Gitlab_Diff_StatsCache-->>+Redis: 캐시에서 데이터 읽기
Gitlab_Diff_FileCollection_MergeRequestDiffBatch-->>+Gitlab_Diff_HighlightCache: decorate()
Gitlab_Diff_HighlightCache-->>+Redis: 캐시에서 데이터 읽기
Gitlab_Diff_FileCollection_MergeRequestDiffBatch-->>-PaginatedDiffSerializer: diff 파일
PaginatedDiffSerializer-->>-.#diffs_batch: JSON
.#diffs_batch-->>+Frontend: JSON으로 200 HTTP 반환
그러나 diff를 볼 때 공백 변경 사항 표시가 선택되지 않은 경우:
- 공백 변경 사항은 무시됩니다.
- 흐름이 변경되어, 이제 Gitaly가 관련됩니다.
sequenceDiagram
Frontend-->>+.#diffs_batch: API 호출
Note over .#diffs_batch: Diff 및 ivar 사전로드
.#diffs_batch-->>+.#define_diff_vars: before_action
.#define_diff_vars-->>+MergeRequest: merge_request_head_diff() 또는 merge_request_diff()
MergeRequest-->>+MergeRequestDiff: find()
MergeRequestDiff-->>-MergeRequest: MergeRequestDiff
MergeRequest-->>-.#define_diff_vars: MergeRequestDiff
.#define_diff_vars-->>-.#diffs_batch: @compare
Note over .#diffs_batch: diff 파일 컬렉션 가져오기
.#diffs_batch-->>+MergeRequestDiff: diffs_in_batch()
MergeRequestDiff-->>+Gitlab_Diff_FileCollection_Compare: new()
Gitlab_Diff_FileCollection_Compare-->>-MergeRequestDiff: diff 파일 컬렉션
MergeRequestDiff-->>-.#diffs_batch: diff 파일 컬렉션
Note over .#diffs_batch: 펼칠 수 있는 diff 라인 계산
.#diffs_batch-->>+MergeRequest: note_positions_for_paths
MergeRequest-->>+Gitlab_Diff_PositionCollection: new() 그리고 unfoldable()
Gitlab_Diff_PositionCollection-->>-MergeRequest: position 컬렉션
MergeRequest-->>-.#diffs_batch: unfoldable_positions
ETag 헤더가 있고 유효하지 않은 경우 중단
.#diffs_batch-->>+Frontend: 304 HTTP 반환
end
옵션 HEAD, 최신 또는 특정 버전을 보는 경우에는 하이라이트 및 통계 캐시
.#diffs_batch->>+Gitlab_Diff_FileCollection_MergeRequestDiffBatch: write_cache()
Gitlab_Diff_FileCollection_MergeRequestDiffBatch->>+Gitlab_Diff_HighlightCache: write_if_empty()
Gitlab_Diff_FileCollection_MergeRequestDiffBatch->>+Gitlab_Diff_StatsCache: write_if_empty()
Gitlab_Diff_HighlightCache-->>+Redis: 캐시
Gitlab_Diff_StatsCache-->>+Redis: 캐시
end
Note over .#diffs_batch: Diffs 직렬화 및 JSON 렌더링
.#diffs_batch-->>+PaginatedDiffSerializer: represent()
PaginatedDiffSerializer-->>+Gitlab_Diff_FileCollection_MergeRequestDiffBatch: diff_files()
Gitlab_Diff_FileCollection_MergeRequestDiffBatch-->>+MergeRequestDiff: raw_diffs()
MergeRequestDiff-->>+Repository: diff()
Repository-->>+Gitaly: CommitDiff RPC
Gitaly-->>-Repository: GitalyClient::DiffStitcher
Repository-->>-MergeRequestDiff: Gitlab::Git::DiffCollection
MergeRequestDiff-->>-Gitlab_Diff_FileCollection_MergeRequestDiffBatch: diff 파일
Gitlab_Diff_FileCollection_MergeRequestDiffBatch-->>+Gitlab_Diff_StatsCache: find_by_path()
Gitlab_Diff_StatsCache-->>+Redis: 캐시에서 데이터 읽기
Gitlab_Diff_FileCollection_MergeRequestDiffBatch-->>+Gitlab_Diff_HighlightCache: decorate()
Gitlab_Diff_HighlightCache-->>+Redis: 캐시에서 데이터 읽기
Gitlab_Diff_FileCollection_MergeRequestDiffBatch-->>-PaginatedDiffSerializer: diff 파일
PaginatedDiffSerializer-->>-.#diffs_batch: JSON
.#diffs_batch-->>+Frontend: JSON으로 200 HTTP 반환
병합 요청(diff) 버전 비교하기
차이점을 보는 동안 다른 diff 버전을 비교할 수도 있습니다. 이 흐름은 기본 흐름과 다르며, 두 개의 diff 버전 간의 비교를 생성하기 위해 Gitaly에 요청을 보냅니다. 또한 강조 효과 및 통계 캐시에 대해 Redis를 사용하지 않습니다.
sequenceDiagram
Frontend-->>+.#diffs_batch: API 호출
Note over .#diffs_batch: diff 및 ivars 미리 로드
.#diffs_batch-->>+.#define_diff_vars: before_action
.#define_diff_vars-->>+MergeRequestDiff: compare_with(start_sha)
MergeRequestDiff-->>+Compare: new()
Compare-->>-MergeRequestDiff: 비교
MergeRequestDiff-->>-.#define_diff_vars: 비교
.#define_diff_vars-->>-.#diffs_batch: @비교
Note over .#diffs_batch: diff 파일 컬렉션 가져오기
.#define_diff_vars-->>+Compare: diffs_in_batch()
Compare-->>+Gitlab_Diff_FileCollection_Compare: new()
Gitlab_Diff_FileCollection_Compare-->>-Compare: diff 파일 컬렉션
Compare-->>-.#define_diff_vars: diff 파일 컬렉션
Note over .#diffs_batch: 펼칠 수 있는 diff 라인 계산
.#diffs_batch-->>+MergeRequest: note_positions_for_paths
MergeRequest-->>+Gitlab_Diff_PositionCollection: new() 그리고 unfoldable()
Gitlab_Diff_PositionCollection-->>-MergeRequest: 위치 컬렉션
MergeRequest-->>-.#diffs_batch: 펼칠 수 있는 위치
ETag 헤더가 있고 유효하지 않은 경우에는 중단
.#diffs_batch-->>+Frontend: 304 HTTP 반환
end
Note over .#diffs_batch: diff 직렬화 및 JSON 생성
.#diffs_batch-->>+PaginatedDiffSerializer: represent()
PaginatedDiffSerializer-->>+Gitlab_Diff_FileCollection_Compare: diff_files()
Gitlab_Diff_FileCollection_Compare-->>+Compare: raw_diffs()
Compare-->>+Repository: diff()
Repository-->>+Gitaly: CommitDiff RPC
Gitaly-->>-Repository: GitalyClient::DiffStitcher
Repository-->>-Compare: Gitlab::Git::DiffCollection
Compare-->>-Gitlab_Diff_FileCollection_Compare: diff files
Gitlab_Diff_FileCollection_Compare-->>-PaginatedDiffSerializer: diff files
PaginatedDiffSerializer-->>-.#diffs_batch: JSON
.#diffs_batch-->>+Frontend: JSON으로 200 HTTP 반환
커밋 차이 보기
병합 요청 차이를 보는 또 다른 기능은 특정 커밋의 차이를 보는 것입니다. 기본 흐름과 다르며, 특정 커밋의 diff를 가져오기 위해 Gitaly가 필요합니다. 또한 강조 효과 및 통계 캐시에 대해 Redis를 사용하지 않습니다.
sequenceDiagram
Frontend-->>+.#diffs_batch: API 호출
Note over .#diffs_batch: diff 및 ivars 미리 로드
.#diffs_batch-->>+.#define_diff_vars: before_action
.#define_diff_vars-->>+Repository: commit()
Repository-->>+Gitaly: FindCommit RPC
Gitaly-->>-Repository: Gitlab::Git::Commit
Repository-->>+Commit: new()
Commit-->>-Repository: Commit
Repository-->>-.#define_diff_vars: Commit
.#define_diff_vars-->>-.#diffs_batch: @비교
Note over .#diffs_batch: diff 파일 컬렉션 가져오기
.#define_diff_vars-->>+Commit: diffs_in_batch()
Commit-->>+Gitlab_Diff_FileCollection_Commit: new()
Gitlab_Diff_FileCollection_Commit-->>-Commit: diff 파일 컬렉션
Commit-->>-.#define_diff_vars: diff 파일 컬렉션
Note over .#diffs_batch: 펼칠 수 있는 diff 라인 계산
.#diffs_batch-->>+MergeRequest: note_positions_for_paths
MergeRequest-->>+Gitlab_Diff_PositionCollection: new() 그리고 unfoldable()
Gitlab_Diff_PositionCollection-->>-MergeRequest: 위치 컬렉션
MergeRequest-->>-.#diffs_batch: 펼칠 수 있는 위치
ETag 헤더가 있고 유효하지 않은 경우에는 중단
.#diffs_batch-->>+Frontend: 304 HTTP 반환
end
Note over .#diffs_batch: diff 직렬화 및 JSON 생성
.#diffs_batch-->>+PaginatedDiffSerializer: represent()
PaginatedDiffSerializer-->>+Gitlab_Diff_FileCollection_Commit: diff_files()
Gitlab_Diff_FileCollection_Commit-->>+Commit: raw_diffs()
Commit-->>+Gitaly: CommitDiff RPC
Gitaly-->>-Commit: GitalyClient::DiffStitcher
Commit-->>-Gitlab_Diff_FileCollection_Commit: Gitlab::Git::DiffCollection
Gitlab_Diff_FileCollection_Commit-->>-PaginatedDiffSerializer: diff files
PaginatedDiffSerializer-->>-.#diffs_batch: JSON
.#diffs_batch-->>+Frontend: JSON으로 200 HTTP 반환
diffs.json
병합 요청을 생성하는 동안 변경 사항을 확인할 수도 있습니다. 이를 위해 새로운 병합 요청 페이지 하단으로 스크롤하여 **Changes** 탭을 클릭하면 됩니다. 머지 요청 레코드가 아직 생성되지 않았으므로 `diffs_batch.json` 엔드포인트를 사용하지 않습니다. 대신 `diffs.json`을 사용합니다.
다음 플로차트는 `diffs.json` 요청에서 각 구성 요소가 어떻게 사용되는지 기본적으로 설명합니다.
```mermaid
flowchart TD
A[프론트엔드] --> B[diffs.json]
B --> C[병합 요청 빌드]
C --> D[변경 사항 가져오기]
D --> E[변경 사항이 포함된 뷰 렌더링]
E --> G[Gitaly]
E --> F[변경된 뷰의 JSON 응답]
다음 순서도는 이 흐름에 대한 더 자세한 설명을 보여줍니다.
sequenceDiagram
프론트엔드-->>+.#diffs: API 호출
Note over .#diffs: 병합 요청 빌드
.#diffs-->>+MergeRequests_BuildService: 실행
MergeRequests_BuildService-->>+Compare: new()
Compare-->>-MergeRequests_BuildService: 비교
MergeRequests_BuildService-->>+Compare: commits()
Compare-->>+Gitaly: ListCommits RPC
Gitaly-->-Compare: Commits
Compare-->>-MergeRequests_BuildService: Commits
MergeRequests_BuildService-->>-.#diffs: 병합 요청
Note over .#diffs: 변경 사항 가져오기
.#diffs-->>+MergeRequest: diffs()
MergeRequest-->>+Compare: diffs()
Compare-->>+Gitlab_Diff_FileCollection_Compare: new()
Gitlab_Diff_FileCollection_Compare-->>-Compare: diff 파일 컬렉션
Compare-->>-MergeRequest: diff 파일 컬렉션
MergeRequest-->>-.#diffs: @diffs =
Note over .#diffs: 변경 사항이 포함된 뷰 렌더링
.#diffs-->>+HAML: view_to_html_string('projects/merge_requests/creations/_diffs', diffs: @diffs)
HAML-->>+Gitlab_Diff_FileCollection_Compare: diff_files()
Gitlab_Diff_FileCollection_Compare-->>+Compare: raw_diffs()
Compare-->>+Repository: diff()
Repository-->>+Gitaly: CommitDiff RPC
Gitaly-->>-Repository: GitalyClient::DiffStitcher
Repository-->>-Compare: Gitlab::Git::DiffCollection
Compare-->>-Gitlab_Diff_FileCollection_Compare: diff 파일
Gitlab_Diff_FileCollection_Compare-->>-HAML: diff 파일
HAML-->>-.#diffs: 렌더링된 뷰
.#diffs-->>-프론트엔드: 렌더링된 뷰의 JSON 응답