병합 요청 차이 개발 안내

이 문서는 병합 요청 차이의 백엔드 디자인과 흐름을 설명합니다. 기여자가 다음을 돕는 데 도움이 될 것입니다:

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

구현 세부 정보가 많지 않도록 의도된 바입니다. 왜냐하면 이것들은 자주 변경될 수 있기 때문입니다. 코드가 이러한 세부 사항을 더 잘 설명합니다. 여기서 언급된 구성 요소는 병합 요청 차이가 생성, 저장되고 사용자에게 반환되는 응용 프로그램의 주요 부분입니다.

참고: 이 페이지는 지속적인 문서입니다. 코드베이스의 부분이 변경되거나 제거되거나 새 구성 요소가 추가될 때 해당 내용에 맞게 업데이트하십시오.

데이터 모델

네 개의 주요 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 열에 캐시됩니다. 이 수는 병합 요청 페이지에서 Commits 탭의 카운터로 표시됩니다.

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에 포함된 단일 파일의 차이를 나타냅니다. 파일의 변경과 관련된 메타데이터와 특정 정보를 포함하고 있으며 다음과 같은 사항도 포함합니다:

  • 추가되었는지 또는 이름이 변경되었는지 여부
  • 차이에서의 순서
  • 실제 차이 출력

외부 차이 저장

기본적으로 MergeRequestDiffFile의 차이 데이터는 merge_request_diff_files 테이블의 diff 열에 저장됩니다. 일부 설치에서는 테이블이 너무 커져서 공간을 저장하기 위해 차이 데이터를 외부 저장소에 저장하도록 구성될 수 있습니다. 이를 구성하려면 병합 요청 차이 저장를 참조하십시오.

외부 저장소를 사용하도록 구성된 경우:

  • 데이터베이스의 diff 열은 NULL로 유지됩니다.
  • 연관된 MergeRequestDiff 레코드는 stored_externally 속성을 true로 설정합니다.

ScheduleMigrateExternalDiffsWorker라는 크론 작업이 매 시간 15분에 예약되어 있습니다. 이 작업은 데이터베이스에 아직 저장된 diff를 외부 저장소로 마이그레이션합니다.

MergeRequestDiffDetail

MergeRequestDiffDetailapp/models/merge_request_diff_detail.rb에서 정의됩니다. 이 클래스는 Geo 복제의 검증 정보를 제공하지만 다른 경우에는 사용자가 보는 차이에 사용되지 않습니다.

#<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>

플로우

이 플로우 차트는 컨트롤러에서 모델로 이어지는 여러 기능에 대한 플로우를 설명하는 데 도움이 될 것입니다. 이 페이지는 액세스 및 차이를 사용하여 작업하는 다양한 옵션을 문서화하는 것을 목적으로 하지는 않습니다. 이는 주로 일반적인 기능에 중점을 둡니다.

MergeRequestDiff* 레코드 생성

위에서 설명했듯이 병합 요청에서 차이를 표시할 때 Gitaly에서 정보를 캐시하기 위해 데이터베이스 테이블을 사용합니다. 활성화된 경우 차이를 저장할 때 개체 저장소도 사용합니다.

두 가지 유형의 병합 요청 차이가 있습니다: 기본 차이 및 HEAD 차이. 각 유형은 다르게 생성됩니다.

기본 차이

병합 요청 브랜치로의 모든 푸시마다 새로운 병합 요청 차이 버전을 만듭니다.

이 플로우 차트는 이런 경우 각 구성 요소가 어떻게 사용되는지에 대한 기본적인 설명을 보여줍니다.

%%{init: { "fontFamily": "GitLab Sans" }}%% flowchart TD accTitle: 새로운 차이 버전 생성의 플로우 차트 accDescr: 브랜치로의 Git 푸시를 기반으로 새로운 차이 버전을 생성할 때 사용되는 구성 요소의 고수준 플로우 차트 A[PostReceive worker] --> B[MergeRequests::RefreshService] B --> C[병합 요청의 차이 다시로드] C --> D[병합 요청 차이 생성] D --> K[(데이터베이스)] D --> E[커밋 SHA 보장] E --> L[Gitaly] E --> F[패치 ID 설정] F --> L[Gitaly] F --> G[커밋 저장] G --> L[Gitaly] G --> K[(데이터베이스)] G --> H[차이 저장] H --> L[Gitaly] H --> K[(데이터베이스)] H --> M[(개체 저장소)] H --> I[커밋 유지] I --> L[Gitaly] I --> J[하이라이트 및 통계 캐시 지우기] J --> N[(Redis)]

이 순서도는 이러한 플로우에 대한 더 자세한 설명을 보여줍니다.

%%{init: { "fontFamily": "GitLab Sans" }}%% sequenceDiagram accTitle: 새로운 차이 빌드의 데이터 플로우 accDescr: 새로운 차이 버전을 구성하는 구성 요소를 통한 데이터 플로우의 자세한 모델 PostReceive-->>+MergeRequests_RefreshService: 실행() Note over MergeRequests_RefreshService: 병합 요청의 차이 다시로드 MergeRequests_RefreshService-->>+MergeRequest: reload_diff() Note over MergeRequests_ReloadDiffsService: 병합 요청 차이 생성 MergeRequest-->>+MergeRequests_ReloadDiffsService: 실행() MergeRequests_ReloadDiffsService-->>+MergeRequest: create_merge_request_diff() MergeRequest-->>+MergeRequestDiff: 생성() Note over MergeRequestDiff: 커밋 SHA 보장 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: 커밋 SHA Note over MergeRequestDiff: 패치 ID 설정 MergeRequestDiff-->>+Repository: get_patch_id() Repository-->>+Gitaly: GetPatchID RPC Gitaly-->>-Repository: 패치 ID Repository-->>-MergeRequestDiff: 패치 ID Note over MergeRequestDiff: 커밋 저장 MergeRequestDiff-->>+Gitaly: ListCommits RPC Gitaly-->>-MergeRequestDiff: 커밋 MergeRequestDiff-->>+MergeRequestDiffCommit: create_bulk() Note over MergeRequestDiff: 차이 저장 MergeRequestDiff-->>+Gitaly: ListCommits RPC Gitaly-->>-MergeRequestDiff: 커밋 opt 외부 차이가 활성화된 경우 MergeRequestDiff-->>+ObjectStorage: 차이 업로드 end MergeRequestDiff-->>+MergeRequestDiffFile: legacy_bulk_insert() Note over MergeRequestDiff: 커밋 유지 MergeRequestDiff-->>+Repository: keep_around() Repository-->>+Gitaly: WriteRef RPC Note over MergeRequests_ReloadDiffsService: 하이라이트 및 통계 캐시 지우기 MergeRequests_ReloadDiffsService->>+Gitlab_Diff_HighlightCache: 지우기() MergeRequests_ReloadDiffsService->>+Gitlab_Diff_StatsCache: 지우기() Gitlab_Diff_HighlightCache-->>+Redis: 캐시 Gitlab_Diff_StatsCache-->>+Redis: 캐시

HEAD 차이

병합 요청의 병합 가능성을 확인하고 병합 요청 merge_status:unchecked, :cannot_be_merged_recheck, :checking, 또는 :cannot_be_merged_rechecking 중일 때, 소스 브랜치에서 대상 브랜치로 변경 사항을 병합하고 참조에 쓰려고 시도합니다. 성공하면(즉, 충돌이없는 경우) 생성된 커밋을 기반으로 차이를 생성하고 HEAD 차이로 표시합니다.

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

이 플로우 차트는 HEAD 차이를 생성할 때 각 구성 요소가 어떻게 사용되는지에 대한 기본적인 설명을 보여줍니다.

%%{init: { "fontFamily": "GitLab Sans" }}%% flowchart TD accTitle: HEAD 차이 생성(고수준 뷰) accDescr: HEAD 차이를 생성할 때 사용되는 구성 요소의 고수준 플로우 차트 A[병합 요청 병합 가능성 확인 worker] --> B[MergeRequests::MergeabilityCheckService] B --> C[참조에 변경 사항 병합] C --> L[Gitaly] C --> D[병합 요청 HEAD 차이 재생성] D --> K[(데이터베이스)] D --> E[커밋 SHA 보장] E --> L[Gitaly] E --> F[패치 ID 설정] F --> L[Gitaly] F --> G[커밋 저장] G --> L[Gitaly] G --> K[(데이터베이스)] G --> H[차이 저장] H --> L[Gitaly] H --> K[(데이터베이스)] H --> M[(개체 저장소)] H --> I[커밋 유지] I --> L[Gitaly]

이 순서도는 이 플로우에 대한 더 자세한 설명을 보여줍니다.

%%{init: { "fontFamily": "GitLab Sans" }}%% sequenceDiagram accTitle: HEAD 차이 생성(상세 뷰) accDescr: 새로운 HEAD 차이 생성의 자세한 시퀀스 다이어그램 병합 요청 병합 가능성 확인 worker-->>+MergeRequests_MergeabilityCheckService: 실행() Note over MergeRequests_MergeabilityCheckService: 참조에 변경 사항 병합 MergeRequests_MergeabilityCheckService-->>+MergeRequests_MergeToRefService: 실행() MergeRequests_MergeToRefService-->>+Repository: merge_to_ref() Repository-->>+Gitaly: UserMergeBranch RPC Gitaly-->>-Repository: 커밋 SHA MergeRequests_MergeToRefService-->>+Repository: 커밋() Repository-->>+Gitaly: FindCommit RPC Gitaly-->>-Repository: Gitlab::Git::Commit Repository-->>+Commit: new() Commit-->>-Repository: Commit Repository-->>-MergeRequests_MergeToRefService: Commit Note over MergeRequests_MergeabilityCheckService: 병합 요청 HEAD 차이 재생성 MergeRequests_MergeabilityCheckService-->>+MergeRequests_ReloadMergeHeadDiffService: 실행() MergeRequests_ReloadMergeHeadDiffService-->>+MergeRequest: create_merge_request_diff() MergeRequest-->>+MergeRequestDiff: 생성() Note over MergeRequestDiff: 커밋 SHA 보장 MergeRequestDiff-->>+MergeRequest: merge_ref_head() MergeRequest-->>+Repository: 커밋() Repository-->>+Gitaly: FindCommit RPC Gitaly-->>-Repository: Gitlab::Git::Commit Repository-->>+Commit: new() Commit-->>-Repository: Commit Repository-->>-MergeRequestDiff: Commit MergeRequest-->>-MergeRequestDiff: 커밋 SHA Note over MergeRequestDiff: 패치 ID 설정 MergeRequestDiff-->>+Repository: get_patch_id() Repository-->>+Gitaly: GetPatchID RPC Gitaly-->>-Repository: 패치 ID Repository-->>-MergeRequestDiff: 패치 ID Note over MergeRequestDiff: 커밋 저장 MergeRequestDiff-->>+Gitaly: ListCommits RPC Gitaly-->>-MergeRequestDiff: 커밋 MergeRequestDiff-->>+MergeRequestDiffCommit: create_bulk() Note over MergeRequestDiff: 차이 저장 MergeRequestDiff-->>+Gitaly: ListCommits RPC Gitaly-->>-MergeRequestDiff: 커밋 opt 외부 차이가 활성화된 경우 MergeRequestDiff-->>+ObjectStorage: 차이 업로드 end MergeRequestDiff-->>+MergeRequestDiffFile: legacy_bulk_insert() Note over MergeRequestDiff: 커밋 유지 MergeRequestDiff-->>+Repository: keep_around() Repository-->>+Gitaly: WriteRef RPC

diffs_batch.json

가장 일반적인 차이를 볼 수 있는 경로는 GitLab UI의 병합 요청 페이지 상단에 있는 Changes 탭입니다. 선택하면 diffs는 실제로 /-/merge_requests/:id/diffs_batch.json로의 페이징된 요청을 통해 로드되며, 이는 Projects::MergeRequests::DiffsController#diffs_batch에서 제공됩니다.

이 플로우차트는 각 구성 요소가 diffs_batch.json 요청에서 사용되는 기본적인 설명을 보여줍니다.

%%{init: { "fontFamily": "GitLab Sans" }}%% flowchart TD accTitle: 차이 보기 accDescr: 브라우저 표시를 위해 diffs_batch 요청을 그리는 고수위 플로우차트 A[프론트엔드] --> B[diffs_batch.json] B --> C[diffs 사전로드와 ivars] C -->D[Gitaly] C -->E[(데이터베이스)] C --> F[차이 파일 컬렉션 가져오기] F --> G[펼칠 수 있는 차이 행 계산] G --> E G --> H{ETag 헤더가 낡지 않은 경우} H --> |예| I[304 반환] H --> |아니요| 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: diffs 사전로드와 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 break ETag 헤더가 있고 낡지 않은 경우 .#diffs_batch-->>+프론트엔드: 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: 차이 직렬화 및 JSON 렌더링 .#diffs_batch-->>+PaginatedDiffSerializer: represent() PaginatedDiffSerializer-->>+Gitlab_Diff_FileCollection_MergeRequestDiffBatch: diff_files() Gitlab_Diff_FileCollection_MergeRequestDiffBatch-->>+MergeRequestDiff: raw_diffs() MergeRequestDiff-->>-MergeRequestDiff: Gitlab::Git::DiffCollection MergeRequestDiff-->>-MergeRequestDiff: diff files 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-->>+프론트엔드: 200 HTTP와 JSON 반환

그러나 차이를 보는 중 화이트스페이스 변경 보기가 선택되지 않은 경우:

  • 화이트스페이스 변경은 무시됩니다.
  • 플로우가 변경되며 이제 Gitaly가 관련됩니다.
%%{init: { "fontFamily": "GitLab Sans" }}%% sequenceDiagram accTitle: 화이트스페이스 변경 없이 차이 보기 accDescr: 특정 차이가 표시되는 시퀀스 다이어그램을 나타내는 것. 먼저 HEAD 차이로 시작하여, 그 다음에는 최신 차이로, 그 다음에는 요청된 경우에 특정 버전으로 Frontend-->>+.#diffs_batch: API 호출 Note over .#diffs_batch: diffs 사전로드와 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: diff file collection MergeRequestDiff-->>-.#diffs_batch: diff file collection Note over .#diffs_batch: 펼칼 수 있는 차이 행 계산 .#diffs_batch-->>+MergeRequest: note_positions_for_paths MergeRequest-->>+Gitlab_Diff_PositionCollection: new() 그런 다음 unfoldable() Gitlab_Diff_PositionCollection-->>-MergeRequest: position collection MergeRequest-->>-.#diffs_batch: unfoldable_positions ETag 헤더가 있고 낡지 않은 경우 .#diffs_batch-->>+프론트엔드: 304 HTTP 반환 end opt 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: 차이 직렬화 및 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 files 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-->>+프론트엔드: 200 HTTP와 JSON 반환

병합 요청 차이 버전 비교

파일들을 보는 동안 다른 차이 버전도 비교할 수 있습니다. 이 흐름은 기본 흐름과 다르며 두 개의 차이 버전을 비교하기 위해 Gitaly에 요청을 생성합니다. 하이라이트 및 통계 캐시에 대해 Redis를 사용하지 않습니다.

%%{init: { "fontFamily": "GitLab Sans" }}%% sequenceDiagram accTitle: 차이 비교 accDescr: 서로 다른 차이를 비교하는 순서도 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: Compare MergeRequestDiff-->>-.#define_diff_vars: Compare .#define_diff_vars-->>-.#diffs_batch: @compare Note over .#diffs_batch: 차이 파일 컬렉션 가져오기 .#define_diff_vars-->>+Compare: diffs_in_batch() Compare-->>+Gitlab_Diff_FileCollection_Compare: new() Gitlab_Diff_FileCollection_Compare-->>-Compare: diff file collection Compare-->>-.#define_diff_vars: diff file collection Note over .#diffs_batch: 접을 수 있는 차이 행 계산 .#diffs_batch-->>+MergeRequest: note_positions_for_paths MergeRequest-->>+Gitlab_Diff_PositionCollection: new() then unfoldable() Gitlab_Diff_PositionCollection-->>-MergeRequest: position collection MergeRequest-->>-.#diffs_batch: unfoldable_positions ETag 헤더가 존재하고 빠르지 않을 때까지 중단 .#diffs_batch-->>+Frontend: 304 HTTP 반환 end Note over .#diffs_batch: 차이 직렬화 및 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 반환

커밋 차이 보기

병합 요청 차이를 보는 또 다른 기능은 특정 커밋의 차이를 볼 수 있습니다. 기본 흐름과 다르며 특정 커밋의 차이를 가져 오기 위해 Gitaly가 필요합니다. 하이라이트 및 통계 캐시에 대해 Redis를 사용하지 않습니다.

%%{init: { "fontFamily": "GitLab Sans" }}%% sequenceDiagram accTitle: 커밋 차이 보기 accDescr: 특정 커밋의 차이를 보는 방식에 대한 순서도 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: @compare Note over .#diffs_batch: 차이 파일 컬렉션 가져오기 .#define_diff_vars-->>+Commit: diffs_in_batch() Commit-->>+Gitlab_Diff_FileCollection_Commit: new() Gitlab_Diff_FileCollection_Commit-->>-Commit: diff file collection Commit-->>-.#define_diff_vars: diff file collection Note over .#diffs_batch: 접을 수 있는 차이 행 계산 .#diffs_batch-->>+MergeRequest: note_positions_for_paths MergeRequest-->>+Gitlab_Diff_PositionCollection: new() then unfoldable() Gitlab_Diff_PositionCollection-->>-MergeRequest: position collection MergeRequest-->>-.#diffs_batch: unfoldable_positions ETag 헤더가 존재하고 빠르지 않을 때까지 중단 .#diffs_batch-->>+Frontend: 304 HTTP 반환 end Note over .#diffs_batch: 차이 직렬화 및 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 요청에 사용되는 각 구성 요소에 대한 기본 설명을 보여줍니다.

%%{init: { "fontFamily": "GitLab Sans" }}%% flowchart TD accTitle: 차이 요청 플로우 (상위 수준) accDescr: 차이 요청에 사용되는 구성 요소의 고수준 플로우차트 A[Frontend] --> B[diffs.json] B --> C[병합 요청 작성] C --> D[차이 얻기] D --> E[차이가 포함된 뷰 렌더링] E --> G[Gitaly] E --> F[렌더된 뷰와 함께 JSON 응답]

다음의 순서도는 이 흐름에 대한 보다 자세한 설명을 보여줍니다.

%%{init: { "fontFamily": "GitLab Sans" }}%% sequenceDiagram accTitle: 차이 요청 플로우 (하위 수준) accDescr: 차이 요청에 사용되는 구성 요소를 보다 자세히 보여주는 순서도 Frontend-->>+.#diffs: API 호출 Note over .#diffs: 병합 요청 작성 .#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: 병합 요청 Note over .#diffs: 차이 얻기 .#diffs-->>+MergeRequest: diffs() MergeRequest-->>+Compare: diffs() Compare-->>+Gitlab_Diff_FileCollection_Compare: new() Gitlab_Diff_FileCollection_Compare-->>-Compare: diff file collection Compare-->>-MergeRequest: diff file collection 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 files Gitlab_Diff_FileCollection_Compare-->>-HAML: diff files HAML-->>-.#diffs: 렌더링된 뷰 .#diffs-->>-Frontend: 렌더된 뷰와 함께 JSON 응답