Merge Request 차이점 개발 가이드

이 문서는 Merge Request 차이점의 백엔드 디자인과 흐름을 설명합니다. 기여자들이 다음을 도와줄 것입니다:

  • 코드 디자인을 이해하는 데 도움을 줍니다.
  • 기여를 통해 개선할 수 있는 영역을 식별하는 데 도움이 됩니다.

코드가 자주 변경될 수 있으므로 구현 세부 정보를 너무 많이 포함하지 않도록 의도적입니다. 여기서 언급된 컴포넌트는 Merge Request 차이점이 생성되고 저장되며 사용자에게 반환되는 주요 응용 프로그램 부분이라고 볼 수 있습니다.

note
이 페이지는 생동적인 문서입니다. 이 문서에서 다루는 코드 기반의 부분이 변경되거나 제거되거나, 새로운 컴포넌트가 추가될 때 해당 내용을 업데이트하세요.

데이터 모델

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

  • 차이 조각에 대한 계산된 및 검색된 메타데이터
  • 일반 클래스 및 인스턴스 기반 로직
%%{init: { "fontFamily": "GitLab Sans" }}%% erDiagram accTitle: 차이의 데이터 모델 accDescr: 차이에서 사용되는 네 개의 ActiveRecord 모델의 데이터 모델 MergeRequest ||--|{ MergeRequestDiff: "" MergeRequestDiff |{--|{ MergeRequestDiffCommit: "" MergeRequestDiff |{--|| MergeRequestDiffDetail: "" MergeRequestDiff |{--|{ MergeRequestDiffFile: "" MergeRequestDiffCommit |{--|| MergeRequestDiffCommitUser: ""

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 열에 캐시됩니다. 이 숫자는 커밋 탭의 카운터로 Merge Request 페이지에 표시됩니다.

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로서 :belongs_to 관계로 관련되어 있습니다. 이러한 레코드는 서로 다른 사람일 수 있습니다.

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에 포함된 단일 파일의 차이를 나타냅니다. 파일의 변경과 관련된 메타데이터와 구체적인 정보를 포함하고 있습니다.

  • 추가되었는지 또는 이름이 변경되었는지
  • 차이에서의 순서
  • 원시 차이 출력 자체

외부 diff 저장

기본적으로 MergeRequestDiffFile의 diff 데이터는 merge_request_diff_files 테이블의 diff 열에 저장됩니다. 일부 설치에서 테이블이 너무 커져서 공간을 절약하기 위해 diff 데이터를 외부 리포지터리에 저장하도록 구성할 수도 있습니다. 이를 구성하려면 Merge Request diffs 저장을 참조하세요.

외부 리포지터리 사용으로 구성된 경우:

  • 데이터베이스의 diff 열은 NULL로 남겨집니다.
  • 연결된 MergeRequestDiff 레코드는 MergeRequestDiff가 생성될 때 stored_externally 속성을 true로 설정합니다.

또한 매 시간 15분에 스케줄된 ScheduleMigrateExternalDiffsWorker 크론 작업이 데이터베이스에 아직 저장된 diff를 외부 리포지터리로 이전합니다.

MergeRequestDiffDetail

MergeRequestDiffDetailapp/models/merge_request_diff_detail.rb에서 정의됩니다. 이 클래스는 Geo 복제에 대한 검증 정보를 제공하지만 그 외에는 사용자에게 노출되는 diff에 대해 사용되지 않습니다.

#<MergeRequestDiffFile:0x00007fd1ef7c9048
  merge_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+# This file was changed in feature branch\n+# We put different code here to make merge conflict\n+class Conflict\n+end\n",
  binary: false,
  external_diff_offset: nil,
  external_diff_size: nil>

흐름

이러한 플로우 차트는 컨트롤러에서 모델로의 플로우를 설명하는 데 도움이 됩니다. 이 페이지는 diffs에 대한 액세스 및 작업의 옵션 전부를 문서화하는 것을 의도하지 않으며 가장 일반적인 옵션에만 초점을 맞춥니다.

MergeRequestDiff* 레코드 생성

위에서 설명한대로, 우리는 Merge Request의 차이를 표시할 때 Gitaly에서 정보를 캐시하기 위해 데이터베이스 테이블을 사용합니다. 사용 가능한 경우 차이를 저장할 때는 객체 리포지터리도 사용합니다.

우리는 2 종류의 Merge Request 차이를 가지고 있습니다: 기본 차이와 HEAD 차이. 각 유형은 다르게 생성됩니다.

기본 차이

Merge Request 브랜치로의 푸시마다 새로운 Merge Request 차이 버전을 생성합니다.

이 플로우차트는 새로운 차이 버전을 생성할 때 각 컴포넌트가 사용되는 기본적인 설명을 보여줍니다.

%%{init: { "fontFamily": "GitLab Sans" }}%% flowchart TD accTitle: 새로운 차이 버전 생성의 플로우차트 accDescr: 브랜치로 Git 푸시를 기반으로 새로운 차이 버전을 생성할 때 사용되는 컴포넌트의 고수준 플로우차트 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 --> 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 --> N[(Redis)]

이 시퀀스 다이어그램은 이 플로우의 더 자세한 설명을 보여줍니다.

%%{init: { "fontFamily": "GitLab Sans" }}%% sequenceDiagram accTitle: 새로운 차이 빌드의 데이터 흐름 accDescr: 새로운 차이 버전을 구성하는 컴포넌트를 통한 데이터 흐름의 자세한 모델 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 외부 차이가 활성화된 경우 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 Request의 Merge 가능성을 확인하고 Merge Request merge_status:unchecked, :cannot_be_merged_recheck, :checking, 또는 :cannot_be_merged_rechecking 중 하나인 경우, 소스 브랜치에서 대상 브랜치로의 변경을 시도하고 참조에 기록합니다. 성공하는 경우 (즉, 충돌이 없는 경우), 생성된 커밋을 기반으로 차이를 생성하고 HEAD 차이로 표시합니다.

이 플로우는 기본 차이 생성과 다르며 다른 진입점을 갖습니다.

%%{init: { "fontFamily": "GitLab Sans" }}%% flowchart TD accTitle: `HEAD` 차이 생성 (고수준 뷰) accDescr: `HEAD` 차이 생성 시 사용되는 컴포넌트의 고수준 플로우차트 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 --> 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]

이 시퀀스 다이어그램은 이 플로우의 더 자세한 설명을 보여줍니다.

%%{init: { "fontFamily": "GitLab Sans" }}%% sequenceDiagram accTitle: `HEAD` 차이 생성 (세부 뷰) accDescr: 새로운 `HEAD` 차이 생성의 자세한 시퀀스 다이어그램 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의 Merge Request 페이지 상단의 **Changes** 탭에서 차이점을 볼 수 있습니다. 선택하면 실제 차이점은 `/-/merge_requests/:id/diffs_batch.json`로의 페이지네이션된 요청을 통해 로드되며, 이는 [`Projects::MergeRequests::DiffsController#diffs_batch`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/merge_requests/diffs_controller.rb)에서 제공됩니다.

이 플로차트는 `diffs_batch.json` 요청에서 각 컴포넌트가 사용되는 기본적인 설명을 보여줍니다.

```mermaid
%%{init: { "fontFamily": "GitLab Sans" }}%%
flowchart TD
    accTitle: 차이점 보기
    accDescr: 브라우저 디스플레이를 위해 차이점을 렌더링하는 diffs_batch 요청의 고수준 플로차트
    A[프론트엔드] --> B[diffs_batch.json]
    B --> C[사전로드 차이점 및 ivars]
    C -->D[Gitaly]
    C -->E[(데이터베이스)]
    C --> F[차이 파일 컬렉션 가져오기]
    C --> F[차이 파일 컬렉션 가져오기]
    F --> G[펼칠 수 있는 차이점 라인 계산]
    G --> E
    G --> H{ETag 헤더가 오래되지 않음}
    H --> |Yes| I[304 반환]
    H --> |No| J[차이점 직렬화]
    J --> D
    J --> E
    J --> K[(Redis)]
    J --> L[JSON으로 200 반환]

차이점을 보는 경우에는 다양한 경우가 존재하며, 각 경우의 플로우가 다릅니다.

HEAD, 최신 또는 특정 차이점 버전 보기

HEAD 차이점은 사용 가능한 경우 기본적으로 보여지며, 그렇지 않으면 최신 차이점으로 이동합니다. 또한 특정 차이점 버전을 볼 수도 있습니다. 이러한 경우는 동일한 플로우를 갖습니다.

%%{init: { "fontFamily": "GitLab Sans" }}%% sequenceDiagram accTitle: 가장 최근 차이점 보기 accDescr: 특정 차이점이 선택되는 방법을 보여주는 시퀀스 다이어그램 - 먼저 HEAD 차이점으로, 그 다음 최신 차이점으로, 요청 시 특정 버전으로 이어짐 Frontend-->>+.#diffs_batch: API 호출 Note over .#diffs_batch: 사전로드 차이점 및 ivars .#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: 차이 파일 컬렉션 가져오기 .#diffs_batch-->>+MergeRequestDiff: diffs_in_batch() MergeRequestDiff-->>+Gitlab_Diff_FileCollection_MergeRequestDiffBatch: new() Gitlab_Diff_FileCollection_MergeRequestDiffBatch-->>-MergeRequestDiff: 차이 파일 컬렉션 MergeRequestDiff-->>-.#diffs_batch: 차이 파일 컬렉션 Note over .#diffs_batch: 펼칠 수 있는 차이점 라인 계산 .#diffs_batch-->>+MergeRequest: note_positions_for_paths MergeRequest-->>+Gitlab_Diff_PositionCollection: new() 그런 다음 unfoldable() Gitlab_Diff_PositionCollection-->>-MergeRequest: 위치 컬렉션 MergeRequest-->>-.#diffs_batch: unfoldable_positions ETag 헤더가 존재하고 오래되지 않을 때 .#diffs_batch-->>+Frontend: 304 HTTP 반환 .#diffs_batch->>+Gitlab_Diff_FileCollection_MergeRequestDiffBatch: cache 작성() Gitlab_Diff_FileCollection_MergeRequestDiffBatch->>+Gitlab_Diff_HighlightCache: 빈 경우 작성() Gitlab_Diff_FileCollection_MergeRequestDiffBatch->>+Gitlab_Diff_StatsCache: 빈 경우 작성() Gitlab_Diff_HighlightCache-->>+Redis: 캐시 Gitlab_Diff_StatsCache-->>+Redis: 캐시 Note over .#diffs_batch: 차이를 직렬화하고 JSON으로 렌더링 .#diffs_batch-->>+PaginatedDiffSerializer: represent() PaginatedDiffSerializer-->>+Gitlab_Diff_FileCollection_MergeRequestDiffBatch: diff_files() Gitlab_Diff_FileCollection_MergeRequestDiffBatch-->>+MergeRequestDiff: raw_diffs() MergeRequestDiff-->>-MergeRequestDiff: 모든 관련 레코드 가져오기 MergeRequestDiff-->>-MergeRequestDiff: Gitlab::Git::DiffCollection 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_files PaginatedDiffSerializer-->>-.#diffs_batch: JSON .#diffs_batch-->>+Frontend: 200 HTTP로 JSON 반환

하지만 차이점 보기 시 화이트스페이스 변경 표시가 선택되지 않은 경우:

  • 화이트스페이스 변경은 무시됩니다.
  • 플로우가 변경되며, 이제 Gitaly가 관련됩니다.
%%{init: { "fontFamily": "GitLab Sans" }}%% sequenceDiagram accTitle: 화이트스페이스 변경을 하지 않고 차이점 보기 accDescr: 화이트스페이스 변경이 요청되지 않은 경우에 특정 차이점이 디스플레이되는 방법을 보여주는 시퀀스 다이어그램 - 먼저 HEAD 차이점으로, 그 다음 최신 차이점으로, 요청 시 특정 버전으로 이어짐 Frontend-->>+.#diffs_batch: API 호출 Note over .#diffs_batch: 사전로드 차이점 및 ivars .#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: 차이 파일 컬렉션 가져오기 .#diffs_batch-->>+MergeRequestDiff: diffs_in_batch() MergeRequestDiff-->>+Gitlab_Diff_FileCollection_Compare: new() Gitlab_Diff_FileCollection_Compare-->>-MergeRequestDiff: 차이 파일 컬렉션 MergeRequestDiff-->>-.#diffs_batch: 차이 파일 컬렉션 Note over .#diffs_batch: 펼칠 수 있는 차이점 라인 계산 .#diffs_batch-->>+MergeRequest: note_positions_for_paths MergeRequest-->>+Gitlab_Diff_PositionCollection: new() 그런 다음 unfoldable() Gitlab_Diff_PositionCollection-->>-MergeRequest: 위치 컬렉션 MergeRequest-->>-.#diffs_batch: unfoldable_positions ETag 헤더가 존재하고 오래되지 않을 때 .#diffs_batch-->>+Frontend: 304 HTTP 반환 opt HEAD, 최신 또는 특정 버전을 볼 때 하이라이트 및 통계 캐시 .#diffs_batch->>+Gitlab_Diff_FileCollection_MergeRequestDiffBatch: cache 작성() Gitlab_Diff_FileCollection_MergeRequestDiffBatch->>+Gitlab_Diff_HighlightCache: 빈 경우 작성() Gitlab_Diff_FileCollection_MergeRequestDiffBatch->>+Gitlab_Diff_StatsCache: 빈 경우 작성() Gitlab_Diff_HighlightCache-->>+Redis: 캐시 Gitlab_Diff_StatsCache-->>+Redis: 캐시 end Note over .#diffs_batch: 차이를 직렬화하고 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 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_files PaginatedDiffSerializer-->>-.#diffs_batch: JSON .#diffs_batch-->>+Frontend: 200 HTTP로 JSON 반환

Merge Request 차이 버전 비교

여러분은 diff를 보는 동안 다른 diff 버전을 비교할 수도 있습니다. 이 흐름은 기본 흐름과 다릅니다. 기본 흐름과는 다르게, 두 개의 diff 버전 간에 비교를 생성하기 위해 Gitaly에 요청을 보냅니다. 또한 하이라이트 및 통계 캐시에 대해 Redis를 사용하지 않습니다.

%%{init: { "fontFamily": "GitLab Sans" }}%% sequenceDiagram accTitle: Diff 비교 accDescr: 다른 diff가 어떻게 서로 비교되는지 보여주는 순서 다이어그램 Frontend-->>+.#diffs_batch: API 호출 Note over .#diffs_batch: diffs와 ivars 프리로드 .#diffs_batch-->>+.#define_diff_vars: before_action .#define_diff_vars-->>+MergeRequestDiff: compare_with(start_sha) MergeRequestDiff-->>+Compare: new() Compare-->>-MergeRequestDiff: Compare MergeRequestDiff-->>-.#define_diff_vars: Compare .#define_diff_vars-->>-.#diffs_batch: @compare 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() then unfoldable() Gitlab_Diff_PositionCollection-->>-MergeRequest: position 컬렉션 MergeRequest-->>-.#diffs_batch: 펼칠 수 있는 positions ETag 헤더가 있는 경우 및 유효하지 않은 경우 중지 .#diffs_batch-->>+Frontend: 304 HTTP 반환 end Note over .#diffs_batch: diffs 직렬화 및 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 보기

Merge Request diff를 보는 또 다른 기능은 특정 커밋의 diffs를 보는 것입니다. 이것은 기본 흐름과 다릅니다. 특정 커밋의 diffs를 얻기 위해 Gitaly이 필요하고, 하이라이트 및 통계 캐시에 대해 Redis를 사용하지 않습니다.

%%{init: { "fontFamily": "GitLab Sans" }}%% sequenceDiagram accTitle: 커밋 diff 보기 accDescr: 특정 커밋의 diffs를 보는 것이 기본 diff 보기 흐름과 다른 방식을 보여주는 순서 다이어그램 Frontend-->>+.#diffs_batch: API 호출 Note over .#diffs_batch: diffs와 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: @compare 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() then unfoldable() Gitlab_Diff_PositionCollection-->>-MergeRequest: position 컬렉션 MergeRequest-->>-.#diffs_batch: 펼칠 수 있는 positions ETag 헤더가 있는 경우 및 유효하지 않은 경우 중지 .#diffs_batch-->>+Frontend: 304 HTTP 반환 end Note over .#diffs_batch: diffs 직렬화 및 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

Merge Request을 생성하는 동안 diffs를 보는 것도 가능합니다. 이를 위해 새 Merge Request 페이지 하단으로 스크롤하고 Changes 탭을 클릭합니다. Merge Request 레코드가 아직 생성되지 않았기 때문에 diffs_batch.json 엔드포인트를 사용하지 않습니다. 대신에 diffs.json을 사용합니다.

이 flowchart는 diffs.json 요청에 사용되는 각 컴포넌트의 기본적인 설명을 보여줍니다.

%%{init: { "fontFamily": "GitLab Sans" }}%% flowchart TD accTitle: Diff 요청 플로우 (상위 수준) accDescr: diffs 요청에 사용되는 컴포넌트의 상위 수준 flowchart A[Frontend] --> B[diffs.json] B --> C[Merge Request 빌드] C --> D[diffs 얻기] D --> F[diffs로 view 렌더링] D --> G[Gitaly] F --> E[JSON으로 렌더링된 view와 함께 응답]

이 sequence 다이어그램은 이 플로우의 더 자세한 설명을 보여줍니다.

%%{init: { "fontFamily": "GitLab Sans" }}%% sequenceDiagram accTitle: Diff 요청 플로우 (하위 수준) accDescr: diffs 요청에 사용되는 컴포넌트의 깊은 수준 시퀀스 다이어그램 Frontend-->>+.#diffs: API 호출 Note over .#diffs: Merge Request 빌드 .#diffs-->>+MergeRequests_BuildService: execute MergeRequests_BuildService-->>+Compare: new() Compare-->>-MergeRequests_BuildService: Compare MergeRequests_BuildService-->>+Compare: commits() Compare-->>+Gitaly: ListCommits RPC Gitaly-->-Compare: Commits Compare-->>-MergeRequests_BuildService: Commits MergeRequests_BuildService-->>-.#diffs: MergeRequest Note over .#diffs: diffs 얻기 .#diffs-->>+MergeRequest: diffs() MergeRequest-->>+Compare: diffs() Compare-->>+Gitlab_Diff_FileCollection_Compare: new() Gitlab_Diff_FileCollection_Compare-->>-Compare: diff 파일 컬렉션 Compare-->>-MergeRequest: diff 파일 컬렉션 Note over .#diffs: diffs로 view 렌더링 .#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 files Gitlab_Diff_FileCollection_Compare-->>-HAML: diff files HAML-->>-.#diffs: 렌더링된 view .#diffs-->>-Frontend: JSON으로 렌더링된 view와 함께 응답