병합 요청 차이점 개발 가이드

이 문서에서는 병합 요청 차이점의 백엔드 설계와 흐름을 설명합니다. 기여자들이 다음을 이해하는 데 도움이 될 것입니다:

  • 코드 디자인을 이해합니다.
  • 개선을 통해 기여할 수 있는 부분을 식별합니다.

구현 세부 정보가 많이 없어서 일부러 고의로 변경되는 것이 일반적입니다. 코드가 이러한 세부 사항을 더 잘 설명합니다. 여기서 언급된 구성 요소는 병합 요청 차이점이 생성되고 저장되며 사용자에게 반환되는 방식에 대한 응용 프로그램의 주요 부분입니다.

참고: 이 페이지는 계속 업데이트되는 문서입니다. 이 문서에서 다루는 코드베이스의 부분이 변경되거나 제거되거나 새로운 구성 요소가 추가될 때 이에 맞게 업데이트하세요.

데이터 모델

네 개의 주요 ActiveRecord 모델은 우리가 _차이_로 통칭하는 것을 나타냅니다. 이러한 데이터베이스 지원 레코드는 프로젝트의 Git 저장소에 포함된 데이터를 복제하고 Gitaly로의 과도한 액세스 요청에 대한 캐시의 역할을 하며 다음과 같은 역할을 하는 논리적인 장소를 제공합니다.

  • 차이의 조각에 대한 계산 및 검색된 메타데이터.
  • 일반적인 클래스 및 인스턴스 기반 로직.
erDiagram 병합 요청 ||--|{ 병합 요청 차이: "" 병합 요청 차이 |{--|{ 병합 요청 차이 커밋: "" 병합 요청 차이 |{--|| 병합 요청 차이 상세: "" 병합 요청 차이 |{--|{ 병합 요청 차이 파일: "" 병합 요청 차이 커밋 |{--|| 병합 요청 차이 커밋 사용자: ""

MergeRequestDiff

MergeRequestDiffapp/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

MergeRequestDiffCommitapp/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::DiffCommitUserapp/models/merge_request/diff_commit_user.rb에 정의되어 있습니다. 이는 주어진 커밋의 nameemail을 캡처하지만 자체적으로 어떤 User 레코드와도 연결되지 않습니다.

#<MergeRequest::DiffCommitUser:0x00007fd1dff7c930
  id: 19,
  name: "Sample User",
  email: "sample.user@example.com">

MergeRequestDiffFile

MergeRequestDiffFileapp/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

MergeRequestDiffDetailapp/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 응답