diff --git a/internal/gitaly/service/diff/find_changed_paths.go b/internal/gitaly/service/diff/find_changed_paths.go index 29f4c8f6d7a4030e1ff2cacf3c65baea79fda2e0..2de0aa9aa5ad258a7c64e483e4fb7482e7de8adb 100644 --- a/internal/gitaly/service/diff/find_changed_paths.go +++ b/internal/gitaly/service/diff/find_changed_paths.go @@ -53,17 +53,34 @@ func (s *server) FindChangedPaths(in *gitalypb.FindChangedPathsRequest, stream g requests[i] = str } + flags := []git.Option{ + git.Flag{Name: "-z"}, + git.Flag{Name: "--stdin"}, + git.Flag{Name: "-r"}, + git.Flag{Name: "--no-renames"}, + git.Flag{Name: "--no-commit-id"}, + git.Flag{Name: "--diff-filter=AMDTC"}, + } + switch in.MergeCommitDiffMode { + case gitalypb.FindChangedPathsRequest_MERGE_COMMIT_DIFF_MODE_INCLUDE_MERGES, gitalypb.FindChangedPathsRequest_MERGE_COMMIT_DIFF_MODE_UNSPECIFIED: + // By default, git diff-tree --stdin does not show differences + // for merge commits. With this flag, it shows differences to + // that commit from all of its parents. + flags = append(flags, git.Flag{Name: "-m"}) + case gitalypb.FindChangedPathsRequest_MERGE_COMMIT_DIFF_MODE_ALL_PARENTS: + // This flag changes the way a merge commit is displayed (which + // means it is useful only when the command is given one + // , or --stdin). It shows the differences from each + // of the parents to the merge result simultaneously instead of + // showing pairwise diff between a parent and the result one at + // a time (which is what the -m option does). Furthermore, it + // lists only files which were modified from all parents. + flags = append(flags, git.Flag{Name: "-c"}) + } + cmd, err := s.gitCmdFactory.New(stream.Context(), in.Repository, git.Command{ - Name: "diff-tree", - Flags: []git.Option{ - git.Flag{Name: "-z"}, - git.Flag{Name: "--stdin"}, - git.Flag{Name: "-m"}, - git.Flag{Name: "-r"}, - git.Flag{Name: "--no-renames"}, - git.Flag{Name: "--no-commit-id"}, - git.Flag{Name: "--diff-filter=AMDTC"}, - }, + Name: "diff-tree", + Flags: flags, }, git.WithStdin(strings.NewReader(strings.Join(requests, "\n")+"\n"))) if err != nil { return structerr.NewInternal("cmd err: %w", err) @@ -82,7 +99,7 @@ func (s *server) FindChangedPaths(in *gitalypb.FindChangedPathsRequest, stream g func parsePaths(reader *bufio.Reader, chunker *chunk.Chunker) error { for { - path, err := nextPath(reader) + paths, err := nextPath(reader) if err != nil { if err == io.EOF { break @@ -91,15 +108,57 @@ func parsePaths(reader *bufio.Reader, chunker *chunk.Chunker) error { return fmt.Errorf("next path err: %w", err) } - if err := chunker.Send(path); err != nil { - return fmt.Errorf("err sending to chunker: %w", err) + for _, path := range paths { + if err := chunker.Send(path); err != nil { + return fmt.Errorf("err sending to chunker: %w", err) + } } } return nil } -func nextPath(reader *bufio.Reader) (*gitalypb.ChangedPaths, error) { +func nextPath(reader *bufio.Reader) ([]*gitalypb.ChangedPaths, error) { + // When using git-diff-tree(1) option '-c' each line will be in the format: + // + // 1. a colon for each source. + // 2. mode for each "src"; 000000 if creation or unmerged. + // 3. a space. + // 4. mode for "dst"; 000000 if deletion or unmerged. + // 5. a space. + // 6. oid for each "src"; 0{40} if creation or unmerged. + // 7. a space. + // 8. oid for "dst"; 0{40} if deletion, unmerged or "work tree out of + // sync with the index". + // 9. a space. + // 10. status is concatenated status characters for each parent + // 11. a tab or a NUL when -z option is used. + // 12. path for "src" + // 13. a tab or a NUL when -z option is used; only exists for C or R. + // 14. path for "dst"; only exists for C or R. + // + // Example output: + // + // ::100644 100644 100644 fabadb8 cc95eb0 4866510 MM desc.c + // ::100755 100755 100755 52b7a2d 6d1ac04 d2ac7d7 RM bar.sh + // ::100644 100644 100644 e07d6c5 9042e82 ee91881 RR phooey.c + // + // This example has 2 sources, the mode and oid represent the values at + // each of the parents. When option '-m' was used this would be shown as: + // + // :100644 100644 fabadb8 4866510 M desc.c + // :100755 100755 52b7a2d d2ac7d7 R bar.sh + // :100644 100644 e07d6c5 ee91881 R phooey.c + // :100644 100644 cc95eb0 4866510 M desc.c + // :100755 100755 6d1ac04 d2ac7d7 M bar.sh + // :100644 100644 9042e82 ee91881 R phooey.c + // + // The number of sources returned depends on the number of parents of + // the commit, so we don't know in advance. First step is to count + // number of colons. + + // Read up to the first colon. If trees were passed to the command, + // git-diff-tree(1) will print them, but are swallowed. _, err := reader.ReadBytes(':') if err != nil { return nil, err @@ -110,26 +169,29 @@ func nextPath(reader *bufio.Reader) (*gitalypb.ChangedPaths, error) { return nil, err } split := bytes.Split(line[:len(line)-1], []byte(" ")) - if len(split) != 5 || len(split[4]) != 1 { - return nil, fmt.Errorf("git diff-tree parsing failed on: %v", line) - } - oldMode, err := strconv.ParseInt(string(split[0]), 8, 32) - if err != nil { - return nil, fmt.Errorf("parsing old mode: %w", err) - } + // Determine the number of sources. + // The first colon was eaten by reader.ReadBytes(':') so we need to add + // one extra to get the total source count. + srcCount := bytes.LastIndexByte(split[0], byte(':')) + 2 + split[0] = split[0][srcCount-1:] - newMode, err := strconv.ParseInt(string(split[1]), 8, 32) - if err != nil { - return nil, fmt.Errorf("parsing new mode: %w", err) - } + pathStatus := split[len(split)-1] - pathStatus := split[4] + // Sanity check on the number of fields. There should be: + // * a mode + hash for each source + // * a mode + hash for the destination + // * a status indicator (might be concatenated for multiple sources) + if len(split) != (2*srcCount)+2+1 || len(pathStatus) != srcCount { + return nil, fmt.Errorf("git diff-tree parsing failed on: %v", line) + } + // Read the path (until the next NUL delimiter) path, err := reader.ReadBytes(numStatDelimiter) if err != nil { return nil, err } + path = path[:len(path)-1] statusTypeMap := map[string]gitalypb.ChangedPaths_Status{ "M": gitalypb.ChangedPaths_MODIFIED, @@ -139,19 +201,33 @@ func nextPath(reader *bufio.Reader) (*gitalypb.ChangedPaths, error) { "A": gitalypb.ChangedPaths_ADDED, } - parsedPath, ok := statusTypeMap[string(pathStatus)] - if !ok { - return nil, structerr.NewInternal("unknown changed paths returned: %v", string(pathStatus)) - } + // Produce a gitalypb.ChangedPaths for each source + changedPaths := make([]*gitalypb.ChangedPaths, srcCount) + for i := range changedPaths { + oldMode, err := strconv.ParseInt(string(split[i]), 8, 32) + if err != nil { + return nil, fmt.Errorf("parsing old mode: %w", err) + } + + newMode, err := strconv.ParseInt(string(split[srcCount]), 8, 32) + if err != nil { + return nil, fmt.Errorf("parsing new mode: %w", err) + } - changedPath := &gitalypb.ChangedPaths{ - Status: parsedPath, - Path: path[:len(path)-1], - OldMode: int32(oldMode), - NewMode: int32(newMode), + parsedPath, ok := statusTypeMap[string(pathStatus[i:i+1])] + if !ok { + return nil, structerr.NewInternal("unknown changed paths returned: %v", string(pathStatus)) + } + + changedPaths[i] = &gitalypb.ChangedPaths{ + Status: parsedPath, + Path: path, + OldMode: int32(oldMode), + NewMode: int32(newMode), + } } - return changedPath, nil + return changedPaths, nil } // This sender implements the interface in the chunker class diff --git a/internal/gitaly/service/diff/find_changed_paths_test.go b/internal/gitaly/service/diff/find_changed_paths_test.go index bbe1a1dfa55b5e3d836760833afbe70e438fe8b4..72081c2dc74cc6e0213a791b5ef03fb5ed03e332 100644 --- a/internal/gitaly/service/diff/find_changed_paths_test.go +++ b/internal/gitaly/service/diff/find_changed_paths_test.go @@ -1,5 +1,3 @@ -//go:build !gitaly_test_sha256 - package diff import ( @@ -9,442 +7,903 @@ import ( "testing" "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" "gitlab.com/gitlab-org/gitaly/v15/internal/structerr" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) func TestFindChangedPathsRequest_success(t *testing.T) { + t.Parallel() + ctx := testhelper.Context(t) - _, repo, _, client := setupDiffService(t, ctx) + cfg, client := setupDiffServiceWithoutRepo(t) - testCases := []struct { - desc string - commits []string - requests []*gitalypb.FindChangedPathsRequest_Request + type commitRequest struct { + commit string + parents []string + } + type treeRequest struct { + left, right string + } + + type setupData struct { + repo *gitalypb.Repository + diffMode gitalypb.FindChangedPathsRequest_MergeCommitDiffMode + commits []commitRequest + trees []treeRequest expectedPaths []*gitalypb.ChangedPaths + } + + testCases := []struct { + desc string + setup func(t *testing.T) setupData }{ { - desc: "Returns the expected results without a merge commit", - commits: []string{"e4003da16c1c2c3fc4567700121b17bf8e591c6c", "57290e673a4c87f51294f5216672cbc58d485d25", "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab", "d59c60028b053793cecfb4022de34602e1a9218e"}, - expectedPaths: []*gitalypb.ChangedPaths{ - { - Status: gitalypb.ChangedPaths_MODIFIED, - Path: []byte("CONTRIBUTING.md"), - OldMode: 0o100644, - NewMode: 0o100644, - }, - { - Status: gitalypb.ChangedPaths_MODIFIED, - Path: []byte("MAINTENANCE.md"), - OldMode: 0o100644, - NewMode: 0o100644, - }, - { - Status: gitalypb.ChangedPaths_ADDED, - Path: []byte("gitaly/ใƒ†ใ‚นใƒˆ.txt"), - OldMode: 0o000000, - NewMode: 0o100755, - }, - { - Status: gitalypb.ChangedPaths_ADDED, - Path: []byte("gitaly/deleted-file"), - OldMode: 0o000000, - NewMode: 0o100644, - }, - { - Status: gitalypb.ChangedPaths_ADDED, - Path: []byte("gitaly/file-with-multiple-chunks"), - OldMode: 0o000000, - NewMode: 0o100644, - }, - { - Status: gitalypb.ChangedPaths_ADDED, - Path: []byte("gitaly/mode-file"), - OldMode: 0o000000, - NewMode: 0o100644, - }, - { - Status: gitalypb.ChangedPaths_ADDED, - Path: []byte("gitaly/mode-file-with-mods"), - OldMode: 0o000000, - NewMode: 0o100644, - }, - { - Status: gitalypb.ChangedPaths_ADDED, - Path: []byte("gitaly/named-file"), - OldMode: 0o000000, - NewMode: 0o100644, - }, - { - Status: gitalypb.ChangedPaths_ADDED, - Path: []byte("gitaly/named-file-with-mods"), - OldMode: 0o000000, - NewMode: 0o100644, - }, - { - Status: gitalypb.ChangedPaths_DELETED, - Path: []byte("files/js/commit.js.coffee"), - OldMode: 0o100644, - NewMode: 0o000000, - }, - }, - }, - { - desc: "Returns the expected results with a merge commit", - commits: []string{"7975be0116940bf2ad4321f79d02a55c5f7779aa", "55bc176024cfa3baaceb71db584c7e5df900ea65"}, - expectedPaths: []*gitalypb.ChangedPaths{ - { - Status: gitalypb.ChangedPaths_ADDED, - Path: []byte("files/images/emoji.png"), - OldMode: 0o000000, - NewMode: 0o100644, - }, - { - Status: gitalypb.ChangedPaths_MODIFIED, - Path: []byte(".gitattributes"), - OldMode: 0o100644, - NewMode: 0o100644, - }, + desc: "Returns the expected results without a merge commit", + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + oldCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "modified.txt", Mode: "100644", Content: "before"}, + ), + ) + newCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(oldCommit), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "added.txt", Mode: "100755", Content: "new"}, + gittest.TreeEntry{Path: "modified.txt", Mode: "100644", Content: "after"}, + ), + ) + + expectedPaths := []*gitalypb.ChangedPaths{ + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("added.txt"), + OldMode: 0o000000, + NewMode: 0o100755, + }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("modified.txt"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + } + return setupData{ + repo: repo, + commits: []commitRequest{{commit: newCommit.String()}}, + expectedPaths: expectedPaths, + } }, }, { - desc: "Commit request without parents uses actual parents", - requests: []*gitalypb.FindChangedPathsRequest_Request{ - { - Type: &gitalypb.FindChangedPathsRequest_Request_CommitRequest_{ - CommitRequest: &gitalypb.FindChangedPathsRequest_Request_CommitRequest{ - CommitRevision: "5b4bb08538b9249995b94aa69121365ba9d28082", - }, + desc: "Returns the expected results with a merge commit", + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + oldCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "modified.txt", Mode: "100644", Content: "before"}, + ), + ) + leftCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(oldCommit), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "left.txt", Mode: "100755", Content: "new"}, + gittest.TreeEntry{Path: "modified.txt", Mode: "100644", Content: "after"}, + ), + ) + rightCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(oldCommit), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "right.txt", Mode: "100755", Content: "new"}, + gittest.TreeEntry{Path: "modified.txt", Mode: "100644", Content: "before"}, + ), + ) + mergeCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(leftCommit, rightCommit), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "right.txt", Mode: "100755", Content: "new"}, + gittest.TreeEntry{Path: "left.txt", Mode: "100755", Content: "new"}, + gittest.TreeEntry{Path: "modified.txt", Mode: "100644", Content: "after"}, + ), + ) + + expectedPaths := []*gitalypb.ChangedPaths{ + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("right.txt"), + OldMode: 0o000000, + NewMode: 0o100755, }, - }, - }, - expectedPaths: []*gitalypb.ChangedPaths{ - { - Status: gitalypb.ChangedPaths_ADDED, - Path: []byte("NEW_FILE.md"), - OldMode: 0o000000, - NewMode: 0o100644, - }, + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("left.txt"), + OldMode: 0o000000, + NewMode: 0o100755, + }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("modified.txt"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + } + + return setupData{ + repo: repo, + commits: []commitRequest{{commit: mergeCommit.String()}}, + expectedPaths: expectedPaths, + } }, }, { desc: "Returns the expected results between distant commits", - requests: []*gitalypb.FindChangedPathsRequest_Request{ - { - Type: &gitalypb.FindChangedPathsRequest_Request_CommitRequest_{ - CommitRequest: &gitalypb.FindChangedPathsRequest_Request_CommitRequest{ - CommitRevision: "5b4bb08538b9249995b94aa69121365ba9d28082", - ParentCommitRevisions: []string{ - "54fcc214b94e78d7a41a9a8fe6d87a5e59500e51", - }, - }, + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + oldCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "first.txt", Mode: "100644", Content: "before"}, + gittest.TreeEntry{Path: "second.txt", Mode: "100644", Content: "before"}, + ), + ) + betweenCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(oldCommit), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "first.txt", Mode: "100644", Content: "after"}, + gittest.TreeEntry{Path: "second.txt", Mode: "100644", Content: "before"}, + ), + ) + lastCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(betweenCommit), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "first.txt", Mode: "100644", Content: "after"}, + gittest.TreeEntry{Path: "second.txt", Mode: "100644", Content: "after"}, + ), + ) + + expectedPaths := []*gitalypb.ChangedPaths{ + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("first.txt"), + OldMode: 0o100644, + NewMode: 0o100644, }, - }, - }, - expectedPaths: []*gitalypb.ChangedPaths{ - { - Status: gitalypb.ChangedPaths_DELETED, - Path: []byte("CONTRIBUTING.md"), - OldMode: 0o100644, - NewMode: 0o000000, - }, - { - Status: gitalypb.ChangedPaths_ADDED, - Path: []byte("NEW_FILE.md"), - OldMode: 0o000000, - NewMode: 0o100644, - }, - { - Status: gitalypb.ChangedPaths_MODIFIED, - Path: []byte("README.md"), - OldMode: 0o100644, - NewMode: 0o100644, - }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("second.txt"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + } + + return setupData{ + repo: repo, + commits: []commitRequest{{commit: lastCommit.String(), parents: []string{oldCommit.String()}}}, + expectedPaths: expectedPaths, + } }, }, { desc: "Returns the expected results when a file is renamed", - requests: []*gitalypb.FindChangedPathsRequest_Request{ - { - Type: &gitalypb.FindChangedPathsRequest_Request_CommitRequest_{ - CommitRequest: &gitalypb.FindChangedPathsRequest_Request_CommitRequest{ - CommitRevision: "94bb47ca1297b7b3731ff2a36923640991e9236f", - ParentCommitRevisions: []string{ - "e63f41fe459e62e1228fcef60d7189127aeba95a", - }, - }, + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + oldCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "rename-me.txt", Mode: "100644", Content: "hello"}, + gittest.TreeEntry{Path: "modified.txt", Mode: "100644", Content: "before"}, + ), + ) + newCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(oldCommit), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "rename-you.txt", Mode: "100644", Content: "hello"}, + gittest.TreeEntry{Path: "modified.txt", Mode: "100644", Content: "after"}, + ), + ) + + expectedPaths := []*gitalypb.ChangedPaths{ + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("modified.txt"), + OldMode: 0o100644, + NewMode: 0o100644, }, - }, - }, - expectedPaths: []*gitalypb.ChangedPaths{ - { - Status: gitalypb.ChangedPaths_DELETED, - Path: []byte("CHANGELOG"), - OldMode: 0o100644, - NewMode: 0o000000, - }, - { - Status: gitalypb.ChangedPaths_ADDED, - Path: []byte("CHANGELOG.md"), - OldMode: 0o000000, - NewMode: 0o100644, - }, + { + Status: gitalypb.ChangedPaths_DELETED, + Path: []byte("rename-me.txt"), + OldMode: 0o100644, + NewMode: 0o000000, + }, + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("rename-you.txt"), + OldMode: 0o000000, + NewMode: 0o100644, + }, + } + + return setupData{ + repo: repo, + commits: []commitRequest{{commit: newCommit.String()}}, + expectedPaths: expectedPaths, + } }, }, { desc: "Returns the expected results with diverging commits", - requests: []*gitalypb.FindChangedPathsRequest_Request{ - { - Type: &gitalypb.FindChangedPathsRequest_Request_CommitRequest_{ - CommitRequest: &gitalypb.FindChangedPathsRequest_Request_CommitRequest{ - CommitRevision: "f0f390655872bb2772c85a0128b2fbc2d88670cb", - ParentCommitRevisions: []string{ - "5b4bb08538b9249995b94aa69121365ba9d28082", - }, - }, + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + oldCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "left.txt", Mode: "100644", Content: "before"}, + gittest.TreeEntry{Path: "right.txt", Mode: "100644", Content: "before"}, + ), + ) + leftCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(oldCommit), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "left.txt", Mode: "100644", Content: "after"}, + gittest.TreeEntry{Path: "right.txt", Mode: "100644", Content: "before"}, + ), + ) + rightCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(oldCommit), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "left.txt", Mode: "100644", Content: "before"}, + gittest.TreeEntry{Path: "right.txt", Mode: "100644", Content: "after"}, + gittest.TreeEntry{Path: "added.txt", Mode: "100644", Content: "new"}, + ), + ) + + expectedPaths := []*gitalypb.ChangedPaths{ + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("added.txt"), + OldMode: 0o000000, + NewMode: 0o100644, }, - }, - }, - expectedPaths: []*gitalypb.ChangedPaths{ - { - Status: gitalypb.ChangedPaths_ADDED, - Path: []byte("CONTRIBUTING.md"), - OldMode: 0o000000, - NewMode: 0o100644, - }, - { - Status: gitalypb.ChangedPaths_MODIFIED, - Path: []byte("NEW_FILE.md"), - OldMode: 0o100644, - NewMode: 0o100644, - }, - { - Status: gitalypb.ChangedPaths_MODIFIED, - Path: []byte("README.md"), - OldMode: 0o100644, - NewMode: 0o100644, - }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("left.txt"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("right.txt"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + } + + return setupData{ + repo: repo, + commits: []commitRequest{{commit: rightCommit.String(), parents: []string{leftCommit.String()}}}, + expectedPaths: expectedPaths, + } }, }, { desc: "Returns the expected results with trees", - requests: []*gitalypb.FindChangedPathsRequest_Request{ - { - Type: &gitalypb.FindChangedPathsRequest_Request_TreeRequest_{ - TreeRequest: &gitalypb.FindChangedPathsRequest_Request_TreeRequest{ - LeftTreeRevision: "05b1cb35ce45609df9de644c62db980a4b6e8814", - RightTreeRevision: "7b06af2882bea3c0433955883bb65217256a634e", - }, + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + firstTree := gittest.WriteTree(t, cfg, repoPath, + []gittest.TreeEntry{ + {Path: "README.md", Mode: "100644", Content: "hello"}, + }) + secondTree := gittest.WriteTree(t, cfg, repoPath, + []gittest.TreeEntry{ + {Path: "README.md", Mode: "100644", Content: "hi"}, + {Path: "CONTRIBUTING.md", Mode: "100644", Content: "welcome"}, + }) + + expectedPaths := []*gitalypb.ChangedPaths{ + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("CONTRIBUTING.md"), + OldMode: 0o000000, + NewMode: 0o100644, }, - }, - }, - expectedPaths: []*gitalypb.ChangedPaths{ - { - Status: gitalypb.ChangedPaths_ADDED, - Path: []byte("CONTRIBUTING.md"), - OldMode: 0o000000, - NewMode: 0o100644, - }, - { - Status: gitalypb.ChangedPaths_MODIFIED, - Path: []byte("README.md"), - OldMode: 0o100644, - NewMode: 0o100644, - }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("README.md"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + } + return setupData{ + repo: repo, + trees: []treeRequest{{left: firstTree.String(), right: secondTree.String()}}, + expectedPaths: expectedPaths, + } }, }, { desc: "Returns the expected results when multiple parent commits are specified", - requests: []*gitalypb.FindChangedPathsRequest_Request{ - { - Type: &gitalypb.FindChangedPathsRequest_Request_CommitRequest_{ - CommitRequest: &gitalypb.FindChangedPathsRequest_Request_CommitRequest{ - CommitRevision: "5b4bb08538b9249995b94aa69121365ba9d28082", - ParentCommitRevisions: []string{ - "5d03ab53225e8d8fe4f0597c70fc21c6542a7a10", - "f0f390655872bb2772c85a0128b2fbc2d88670cb", - }, - }, + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + oldCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "README.md", Mode: "100644", Content: "old README.md"}, + gittest.TreeEntry{Path: "CONTRIBUTING.md", Mode: "100644", Content: "old CONTRIBUTING.md"}, + ), + ) + leftCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(oldCommit), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "README.md", Mode: "100644", Content: "old README.md"}, + gittest.TreeEntry{Path: "NEW_FILE.md", Mode: "100644", Content: "left NEW_FILE.md"}, + ), + ) + betweenCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(oldCommit), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "README.md", Mode: "100644", Content: "old README.md"}, + ), + ) + rightCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(betweenCommit), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "README.md", Mode: "100644", Content: "right README.md"}, + gittest.TreeEntry{Path: "CONTRIBUTING.md", Mode: "100644", Content: "left CONTRIBUTING.md"}, + gittest.TreeEntry{Path: "NEW_FILE.md", Mode: "100644", Content: "right NEW_FILE.md"}, + ), + ) + + expectedPaths := []*gitalypb.ChangedPaths{ + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("NEW_FILE.md"), + OldMode: 0o000000, + NewMode: 0o100644, }, - }, - }, - expectedPaths: []*gitalypb.ChangedPaths{ - { - Status: gitalypb.ChangedPaths_ADDED, - Path: []byte("NEW_FILE.md"), - OldMode: 0o000000, - NewMode: 0o100644, - }, - { - Status: gitalypb.ChangedPaths_DELETED, - Path: []byte("CONTRIBUTING.md"), - OldMode: 0o100644, - NewMode: 0o000000, - }, - { - Status: gitalypb.ChangedPaths_MODIFIED, - Path: []byte("NEW_FILE.md"), - OldMode: 0o100644, - NewMode: 0o100644, - }, - { - Status: gitalypb.ChangedPaths_MODIFIED, - Path: []byte("README.md"), - OldMode: 0o100644, - NewMode: 0o100644, - }, + { + Status: gitalypb.ChangedPaths_DELETED, + Path: []byte("CONTRIBUTING.md"), + OldMode: 0o100644, + NewMode: 0o000000, + }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("NEW_FILE.md"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("README.md"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + } + + return setupData{ + repo: repo, + commits: []commitRequest{{commit: leftCommit.String(), parents: []string{betweenCommit.String(), rightCommit.String()}}}, + expectedPaths: expectedPaths, + } }, }, + { desc: "Returns the expected results with multiple requests", - requests: []*gitalypb.FindChangedPathsRequest_Request{ - { - Type: &gitalypb.FindChangedPathsRequest_Request_TreeRequest_{ - TreeRequest: &gitalypb.FindChangedPathsRequest_Request_TreeRequest{ - LeftTreeRevision: "05b1cb35ce45609df9de644c62db980a4b6e8814", - RightTreeRevision: "7b06af2882bea3c0433955883bb65217256a634e", - }, + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + oldCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "modified.txt", Mode: "100644", Content: "before"}, + ), + ) + newCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(oldCommit), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "added.txt", Mode: "100755", Content: "new"}, + gittest.TreeEntry{Path: "modified.txt", Mode: "100644", Content: "after"}, + ), + ) + + firstTree := gittest.WriteTree(t, cfg, repoPath, + []gittest.TreeEntry{ + {Path: "README.md", Mode: "100644", Content: "hello"}, + }) + secondTree := gittest.WriteTree(t, cfg, repoPath, + []gittest.TreeEntry{ + {Path: "README.md", Mode: "100644", Content: "hi"}, + {Path: "CONTRIBUTING.md", Mode: "100644", Content: "welcome"}, + }) + + expectedPaths := []*gitalypb.ChangedPaths{ + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("added.txt"), + OldMode: 0o000000, + NewMode: 0o100755, }, - }, - { - Type: &gitalypb.FindChangedPathsRequest_Request_CommitRequest_{ - CommitRequest: &gitalypb.FindChangedPathsRequest_Request_CommitRequest{ - CommitRevision: "5b4bb08538b9249995b94aa69121365ba9d28082", - ParentCommitRevisions: []string{ - "5d03ab53225e8d8fe4f0597c70fc21c6542a7a10", - "f0f390655872bb2772c85a0128b2fbc2d88670cb", - }, - }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("modified.txt"), + OldMode: 0o100644, + NewMode: 0o100644, }, - }, - { - Type: &gitalypb.FindChangedPathsRequest_Request_TreeRequest_{ - TreeRequest: &gitalypb.FindChangedPathsRequest_Request_TreeRequest{ - LeftTreeRevision: "05b1cb35ce45609df9de644c62db980a4b6e8814", - RightTreeRevision: "7b06af2882bea3c0433955883bb65217256a634e", - }, + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("CONTRIBUTING.md"), + OldMode: 0o000000, + NewMode: 0o100644, }, - }, - }, - expectedPaths: []*gitalypb.ChangedPaths{ - { - Status: gitalypb.ChangedPaths_ADDED, - Path: []byte("CONTRIBUTING.md"), - OldMode: 0o000000, - NewMode: 0o100644, - }, - { - Status: gitalypb.ChangedPaths_MODIFIED, - Path: []byte("README.md"), - OldMode: 0o100644, - NewMode: 0o100644, - }, - { - Status: gitalypb.ChangedPaths_ADDED, - Path: []byte("NEW_FILE.md"), - OldMode: 0o000000, - NewMode: 0o100644, - }, - { - Status: gitalypb.ChangedPaths_DELETED, - Path: []byte("CONTRIBUTING.md"), - OldMode: 0o100644, - NewMode: 0o000000, - }, - { - Status: gitalypb.ChangedPaths_MODIFIED, - Path: []byte("NEW_FILE.md"), - OldMode: 0o100644, - NewMode: 0o100644, - }, - { - Status: gitalypb.ChangedPaths_MODIFIED, - Path: []byte("README.md"), - OldMode: 0o100644, - NewMode: 0o100644, - }, - { - Status: gitalypb.ChangedPaths_ADDED, - Path: []byte("CONTRIBUTING.md"), - OldMode: 0o000000, - NewMode: 0o100644, - }, - { - Status: gitalypb.ChangedPaths_MODIFIED, - Path: []byte("README.md"), - OldMode: 0o100644, - NewMode: 0o100644, - }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("README.md"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + } + return setupData{ + repo: repo, + commits: []commitRequest{{commit: newCommit.String()}}, + trees: []treeRequest{{left: firstTree.String(), right: secondTree.String()}}, + expectedPaths: expectedPaths, + } }, }, { desc: "Returns the expected results with refs and tags as commits", - requests: []*gitalypb.FindChangedPathsRequest_Request{ - { - Type: &gitalypb.FindChangedPathsRequest_Request_CommitRequest_{ - CommitRequest: &gitalypb.FindChangedPathsRequest_Request_CommitRequest{ - CommitRevision: "v1.0.0", - ParentCommitRevisions: []string{ - "v1.0.0^^", - }, - }, + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + oldCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "modified.txt", Mode: "100644", Content: "before"}, + ), + ) + betweenCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(oldCommit), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "added.txt", Mode: "100755", Content: "new"}, + gittest.TreeEntry{Path: "modified.txt", Mode: "100644", Content: "before"}, + ), + ) + newCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(betweenCommit), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "added.txt", Mode: "100755", Content: "new"}, + gittest.TreeEntry{Path: "modified.txt", Mode: "100644", Content: "after"}, + ), + ) + gittest.WriteTag(t, cfg, repoPath, "v1.0.0", newCommit.Revision()) + + expectedPaths := []*gitalypb.ChangedPaths{ + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("added.txt"), + OldMode: 0o000000, + NewMode: 0o100755, }, - }, - }, - expectedPaths: []*gitalypb.ChangedPaths{ - { - Status: gitalypb.ChangedPaths_DELETED, - Path: []byte(".DS_Store"), - OldMode: 0o100644, - NewMode: 0o000000, - }, - { - Status: gitalypb.ChangedPaths_MODIFIED, - Path: []byte(".gitmodules"), - OldMode: 0o100644, - NewMode: 0o100644, - }, - { - Status: gitalypb.ChangedPaths_DELETED, - Path: []byte("files/.DS_Store"), - OldMode: 0o100644, - NewMode: 0o000000, - }, - { - Status: gitalypb.ChangedPaths_ADDED, - Path: []byte("gitlab-shell"), - OldMode: 0o000000, - NewMode: 0o160000, - }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("modified.txt"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + } + return setupData{ + repo: repo, + commits: []commitRequest{{commit: "v1.0.0", parents: []string{"v1.0.0^^"}}}, + expectedPaths: expectedPaths, + } }, }, { desc: "Returns the expected results with commits as trees", - requests: []*gitalypb.FindChangedPathsRequest_Request{ - { + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + oldCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "modified.txt", Mode: "100644", Content: "before"}, + ), + ) + newCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(oldCommit), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "added.txt", Mode: "100755", Content: "new"}, + gittest.TreeEntry{Path: "modified.txt", Mode: "100644", Content: "after"}, + ), + ) + + expectedPaths := []*gitalypb.ChangedPaths{ + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("added.txt"), + OldMode: 0o000000, + NewMode: 0o100755, + }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("modified.txt"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + } + return setupData{ + repo: repo, + trees: []treeRequest{{left: oldCommit.String(), right: newCommit.String()}}, + expectedPaths: expectedPaths, + } + }, + }, + { + desc: "Returns the expected results when using ALL_PARENTS diff mode", + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + oldCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "common.txt", Mode: "100644", Content: "before"}, + ), + ) + leftCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(oldCommit), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "common.txt", Mode: "100644", Content: "before"}, + gittest.TreeEntry{Path: "conflicted.txt", Mode: "100644", Content: "left"}, + ), + ) + rightCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(oldCommit), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "common.txt", Mode: "100644", Content: "after"}, + gittest.TreeEntry{Path: "conflicted.txt", Mode: "100644", Content: "right"}, + ), + ) + mergeCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(leftCommit, rightCommit), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "common.txt", Mode: "100644", Content: "after"}, + gittest.TreeEntry{Path: "conflicted.txt", Mode: "100644", Content: "left\nright"}, + ), + ) + + expectedPaths := []*gitalypb.ChangedPaths{ + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("conflicted.txt"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("conflicted.txt"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + } + + return setupData{ + repo: repo, + diffMode: gitalypb.FindChangedPathsRequest_MERGE_COMMIT_DIFF_MODE_ALL_PARENTS, + commits: []commitRequest{{commit: mergeCommit.String()}}, + expectedPaths: expectedPaths, + } + }, + }, + { + desc: "Returns the expected results on octopus merge when using diff mode ALL_PARENTS", + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + oldCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "README.md", Mode: "100644", Content: "# Hello"}, + ), + ) + commit1 := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(oldCommit), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "README.md", Mode: "100644", Content: "# Hello\nWelcome"}, + ), + ) + commit2 := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(oldCommit), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "README.md", Mode: "100644", Content: "# Hello\nto"}, + ), + ) + commit3 := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(oldCommit), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "README.md", Mode: "100644", Content: "# Hello\nthis"}, + ), + ) + commit4 := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(oldCommit), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "README.md", Mode: "100644", Content: "# Hello\nproject"}, + ), + ) + mergeCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(oldCommit, commit1, commit2, commit3, commit4), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "README.md", Mode: "100644", Content: "# Hello\nWelcome to this project"}, + ), + ) + + expectedPaths := []*gitalypb.ChangedPaths{ + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("README.md"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("README.md"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("README.md"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("README.md"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("README.md"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + } + + return setupData{ + repo: repo, + diffMode: gitalypb.FindChangedPathsRequest_MERGE_COMMIT_DIFF_MODE_ALL_PARENTS, + commits: []commitRequest{{commit: mergeCommit.String()}}, + expectedPaths: expectedPaths, + } + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + setupData := tc.setup(t) + + rpcRequest := &gitalypb.FindChangedPathsRequest{ + Repository: setupData.repo, + MergeCommitDiffMode: setupData.diffMode, + } + + for _, commitReq := range setupData.commits { + req := &gitalypb.FindChangedPathsRequest_Request{ + Type: &gitalypb.FindChangedPathsRequest_Request_CommitRequest_{ + CommitRequest: &gitalypb.FindChangedPathsRequest_Request_CommitRequest{ + CommitRevision: commitReq.commit, + ParentCommitRevisions: commitReq.parents, + }, + }, + } + rpcRequest.Requests = append(rpcRequest.Requests, req) + } + for _, treeReq := range setupData.trees { + req := &gitalypb.FindChangedPathsRequest_Request{ Type: &gitalypb.FindChangedPathsRequest_Request_TreeRequest_{ TreeRequest: &gitalypb.FindChangedPathsRequest_Request_TreeRequest{ - LeftTreeRevision: "54fcc214b94e78d7a41a9a8fe6d87a5e59500e51", - RightTreeRevision: "be93687618e4b132087f430a4d8fc3a609c9b77c", + LeftTreeRevision: treeReq.left, + RightTreeRevision: treeReq.right, }, }, - }, + } + rpcRequest.Requests = append(rpcRequest.Requests, req) + } + + stream, err := client.FindChangedPaths(ctx, rpcRequest) + require.NoError(t, err) + + var paths []*gitalypb.ChangedPaths + for { + fetchedPaths, err := stream.Recv() + if err == io.EOF { + break + } + + require.NoError(t, err) + + paths = append(paths, fetchedPaths.GetPaths()...) + } + require.Equal(t, setupData.expectedPaths, paths) + }) + } +} + +func TestFindChangedPathsRequest_deprecated(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + cfg, client := setupDiffServiceWithoutRepo(t) + + type setupData struct { + repo *gitalypb.Repository + commits []string + expectedPaths []*gitalypb.ChangedPaths + } + + testCases := []struct { + desc string + setup func(t *testing.T) setupData + }{ + { + desc: "Returns the expected results without a merge commit", + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + oldCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "modified.txt", Mode: "100644", Content: "before"}, + ), + ) + newCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(oldCommit), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "added.txt", Mode: "100755", Content: "new"}, + gittest.TreeEntry{Path: "modified.txt", Mode: "100644", Content: "after"}, + ), + ) + + expectedPaths := []*gitalypb.ChangedPaths{ + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("added.txt"), + OldMode: 0o000000, + NewMode: 0o100755, + }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("modified.txt"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + } + return setupData{ + repo: repo, + commits: []string{newCommit.String()}, + expectedPaths: expectedPaths, + } }, - expectedPaths: []*gitalypb.ChangedPaths{ - { - Status: gitalypb.ChangedPaths_DELETED, - Path: []byte("README"), - OldMode: 0o100644, - NewMode: 0o000000, - }, + }, + { + desc: "Returns the expected results with a merge commit", + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + oldCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "modified.txt", Mode: "100644", Content: "before"}, + ), + ) + leftCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(oldCommit), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "left.txt", Mode: "100755", Content: "new"}, + gittest.TreeEntry{Path: "modified.txt", Mode: "100644", Content: "after"}, + ), + ) + rightCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(oldCommit), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "right.txt", Mode: "100755", Content: "new"}, + gittest.TreeEntry{Path: "modified.txt", Mode: "100644", Content: "before"}, + ), + ) + mergeCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(leftCommit, rightCommit), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "right.txt", Mode: "100755", Content: "new"}, + gittest.TreeEntry{Path: "left.txt", Mode: "100755", Content: "new"}, + gittest.TreeEntry{Path: "modified.txt", Mode: "100644", Content: "after"}, + ), + ) + + expectedPaths := []*gitalypb.ChangedPaths{ + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("right.txt"), + OldMode: 0o000000, + NewMode: 0o100755, + }, + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("left.txt"), + OldMode: 0o000000, + NewMode: 0o100755, + }, + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("modified.txt"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + } + + return setupData{ + repo: repo, + commits: []string{mergeCommit.String()}, + expectedPaths: expectedPaths, + } + }, + }, + { + desc: "Returns the expected results when a file is renamed", + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + oldCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "rename-me.txt", Mode: "100644", Content: "hello"}, + gittest.TreeEntry{Path: "modified.txt", Mode: "100644", Content: "before"}, + ), + ) + newCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(oldCommit), + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "rename-you.txt", Mode: "100644", Content: "hello"}, + gittest.TreeEntry{Path: "modified.txt", Mode: "100644", Content: "after"}, + ), + ) + + expectedPaths := []*gitalypb.ChangedPaths{ + { + Status: gitalypb.ChangedPaths_MODIFIED, + Path: []byte("modified.txt"), + OldMode: 0o100644, + NewMode: 0o100644, + }, + { + Status: gitalypb.ChangedPaths_DELETED, + Path: []byte("rename-me.txt"), + OldMode: 0o100644, + NewMode: 0o000000, + }, + { + Status: gitalypb.ChangedPaths_ADDED, + Path: []byte("rename-you.txt"), + OldMode: 0o000000, + NewMode: 0o100644, + }, + } + + return setupData{ + repo: repo, + commits: []string{newCommit.String()}, + expectedPaths: expectedPaths, + } }, }, } for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - rpcRequest := &gitalypb.FindChangedPathsRequest{Repository: repo, Commits: tc.commits, Requests: tc.requests} + setupData := tc.setup(t) + + rpcRequest := &gitalypb.FindChangedPathsRequest{ + Repository: setupData.repo, + Commits: setupData.commits, + } stream, err := client.FindChangedPaths(ctx, rpcRequest) require.NoError(t, err) @@ -460,15 +919,36 @@ func TestFindChangedPathsRequest_success(t *testing.T) { paths = append(paths, fetchedPaths.GetPaths()...) } - - require.Equal(t, tc.expectedPaths, paths) + require.Equal(t, setupData.expectedPaths, paths) }) } } func TestFindChangedPathsRequest_failing(t *testing.T) { + t.Parallel() + ctx := testhelper.Context(t) - cfg, repo, _, client := setupDiffService(t, ctx) + cfg, client := setupDiffServiceWithoutRepo(t) + + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + oldCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithTreeEntries( + gittest.TreeEntry{Path: "modified.txt", Mode: "100644", Content: "before"}, + ), + ) + addedBlob := gittest.WriteBlob(t, cfg, repoPath, []byte("new")) + modifiedBlob := gittest.WriteBlob(t, cfg, repoPath, []byte("after")) + newTree := gittest.WriteTree(t, cfg, repoPath, + []gittest.TreeEntry{ + {Path: "added.txt", Mode: "100755", OID: addedBlob}, + {Path: "modified.txt", Mode: "100644", OID: modifiedBlob}, + }, + ) + newCommit := gittest.WriteCommit(t, cfg, repoPath, + gittest.WithParents(oldCommit), + gittest.WithTree(newTree), + ) tests := []struct { desc string @@ -480,7 +960,7 @@ func TestFindChangedPathsRequest_failing(t *testing.T) { { desc: "Repository not provided", repo: nil, - commits: []string{"e4003da16c1c2c3fc4567700121b17bf8e591c6c", "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab"}, + commits: []string{newCommit.String(), oldCommit.String()}, err: structerr.NewInvalidArgument(testhelper.GitalyOrPraefect( "empty Repository", "repo scoped: empty Repository", @@ -488,8 +968,8 @@ func TestFindChangedPathsRequest_failing(t *testing.T) { }, { desc: "Repo not found", - repo: &gitalypb.Repository{StorageName: repo.GetStorageName(), RelativePath: "bar.git"}, - commits: []string{"e4003da16c1c2c3fc4567700121b17bf8e591c6c", "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab"}, + repo: &gitalypb.Repository{StorageName: cfg.Storages[0].Name, RelativePath: "bar.git"}, + commits: []string{newCommit.String(), oldCommit.String()}, err: structerr.NewNotFound(testhelper.GitalyOrPraefect( fmt.Sprintf("GetRepoPath: not a git repository: %q", filepath.Join(cfg.Storages[0].Path, "bar.git")), `accessor call: route repository accessor: consistent storages: repository "default"/"bar.git" not found`, @@ -498,7 +978,7 @@ func TestFindChangedPathsRequest_failing(t *testing.T) { { desc: "Storage not found", repo: &gitalypb.Repository{StorageName: "foo", RelativePath: "bar.git"}, - commits: []string{"e4003da16c1c2c3fc4567700121b17bf8e591c6c", "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab"}, + commits: []string{newCommit.String(), oldCommit.String()}, err: structerr.NewInvalidArgument(testhelper.GitalyOrPraefect( `GetStorageByName: no such storage: "foo"`, "repo scoped: invalid Repository", @@ -513,29 +993,23 @@ func TestFindChangedPathsRequest_failing(t *testing.T) { { desc: "Specifying both commits and requests", repo: repo, - commits: []string{"8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab"}, + commits: []string{newCommit.String()}, requests: []*gitalypb.FindChangedPathsRequest_Request{ { Type: &gitalypb.FindChangedPathsRequest_Request_CommitRequest_{ CommitRequest: &gitalypb.FindChangedPathsRequest_Request_CommitRequest{ - CommitRevision: "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab", + CommitRevision: newCommit.String(), }, }, }, }, err: structerr.NewInvalidArgument("cannot specify both commits and requests"), }, - { - desc: "Invalid commit", - repo: repo, - commits: []string{"invalidinvalidinvalid", "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab"}, - err: structerr.NewNotFound(`resolving commit: revision can not be found: "invalidinvalidinvalid"`), - }, { desc: "Commit not found", repo: repo, - commits: []string{"z4003da16c1c2c3fc4567700121b17bf8e591c6c", "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab"}, - err: structerr.NewNotFound(`resolving commit: revision can not be found: "z4003da16c1c2c3fc4567700121b17bf8e591c6c"`), + commits: []string{"notfound", oldCommit.String()}, + err: structerr.NewNotFound(`resolving commit: revision can not be found: "notfound"`), }, { desc: "Tree object as commit", @@ -544,12 +1018,12 @@ func TestFindChangedPathsRequest_failing(t *testing.T) { { Type: &gitalypb.FindChangedPathsRequest_Request_CommitRequest_{ CommitRequest: &gitalypb.FindChangedPathsRequest_Request_CommitRequest{ - CommitRevision: "07f8147e8e73aab6c935c296e8cdc5194dee729b", + CommitRevision: newTree.String(), }, }, }, }, - err: structerr.NewNotFound(`resolving commit: revision can not be found: "07f8147e8e73aab6c935c296e8cdc5194dee729b"`), + err: structerr.NewNotFound("resolving commit: revision can not be found: %q", newTree), }, { desc: "Tree object as parent commit", @@ -558,15 +1032,15 @@ func TestFindChangedPathsRequest_failing(t *testing.T) { { Type: &gitalypb.FindChangedPathsRequest_Request_CommitRequest_{ CommitRequest: &gitalypb.FindChangedPathsRequest_Request_CommitRequest{ - CommitRevision: "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab", + CommitRevision: newCommit.String(), ParentCommitRevisions: []string{ - "07f8147e8e73aab6c935c296e8cdc5194dee729b", + newTree.String(), }, }, }, }, }, - err: structerr.NewNotFound(`resolving commit parent: revision can not be found: "07f8147e8e73aab6c935c296e8cdc5194dee729b"`), + err: structerr.NewNotFound("resolving commit parent: revision can not be found: %q", newTree), }, { desc: "Blob object as left tree", @@ -575,13 +1049,13 @@ func TestFindChangedPathsRequest_failing(t *testing.T) { { Type: &gitalypb.FindChangedPathsRequest_Request_TreeRequest_{ TreeRequest: &gitalypb.FindChangedPathsRequest_Request_TreeRequest{ - LeftTreeRevision: "50b27c6518be44c42c4d87966ae2481ce895624c", - RightTreeRevision: "07f8147e8e73aab6c935c296e8cdc5194dee729b", + LeftTreeRevision: addedBlob.String(), + RightTreeRevision: newTree.String(), }, }, }, }, - err: structerr.NewNotFound(`resolving left tree: revision can not be found: "50b27c6518be44c42c4d87966ae2481ce895624c"`), + err: structerr.NewNotFound("resolving left tree: revision can not be found: %q", addedBlob), }, { desc: "Blob object as right tree", @@ -590,13 +1064,13 @@ func TestFindChangedPathsRequest_failing(t *testing.T) { { Type: &gitalypb.FindChangedPathsRequest_Request_TreeRequest_{ TreeRequest: &gitalypb.FindChangedPathsRequest_Request_TreeRequest{ - LeftTreeRevision: "07f8147e8e73aab6c935c296e8cdc5194dee729b", - RightTreeRevision: "50b27c6518be44c42c4d87966ae2481ce895624c", + LeftTreeRevision: newTree.String(), + RightTreeRevision: addedBlob.String(), }, }, }, }, - err: structerr.NewNotFound(`resolving right tree: revision can not be found: "50b27c6518be44c42c4d87966ae2481ce895624c"`), + err: structerr.NewNotFound("resolving right tree: revision can not be found: %q", addedBlob), }, } diff --git a/proto/diff.proto b/proto/diff.proto index bda865fa955fb55112799e70ad762068eeafc19a..5f6b4759d09bcad78f65ad2dd5cac29c6021b45f 100644 --- a/proto/diff.proto +++ b/proto/diff.proto @@ -265,6 +265,20 @@ message DiffStatsResponse { // to its parent. Merge commits will show files which are different to all of // its parents. message FindChangedPathsRequest { + // MergeCommitDiffMode controls which mode to use to produce diff output for merge commits + enum MergeCommitDiffMode { + // MERGE_COMMIT_DIFF_MODE_UNSPECIFIED is the default value. + // It is equivalent to DIFF_MODE_INCLUDE_MERGES. + MERGE_COMMIT_DIFF_MODE_UNSPECIFIED = 0; + // MERGE_COMMIT_DIFF_MODE_INCLUDE_MERGES tells git to also show differences for merge commits. + // Please refer to the documentation of the `-m` flag of git-diff-tree(1). + MERGE_COMMIT_DIFF_MODE_INCLUDE_MERGES = 1; + // MERGE_COMMIT_DIFF_MODE_ALL_PARENTS tells git to only show differences for + // files which were modified from all parents. + // Please refer to the documentation of the `-c` flag of git-diff-tree(1). + MERGE_COMMIT_DIFF_MODE_ALL_PARENTS = 2; + } + // Request is a single request to pass to git diff-tree. message Request { // TreeRequest compares two trees. @@ -305,11 +319,16 @@ message FindChangedPathsRequest { repeated string commits = 2 [deprecated=true]; // requests specifies the requests of what to compare. repeated Request requests = 3; + + // MergeCommitDiffMode controls how merge commits are treated. + MergeCommitDiffMode merge_commit_diff_mode = 4; } // Returns a list of files that have been changed in the commits given message FindChangedPathsResponse { - // This comment is left unintentionally blank. + // paths contains the attributes for one changed file. In case of merge + // commits, or when comparing three or more commits, a file might be included + // more than once if it was changed between multiple commits. repeated ChangedPaths paths = 1; } diff --git a/proto/go/gitalypb/diff.pb.go b/proto/go/gitalypb/diff.pb.go index b1a4f34972fd684014d229819715b505c6b28dcf..0f4111399fa273c62017f4497c4ea15c5f537e6f 100644 --- a/proto/go/gitalypb/diff.pb.go +++ b/proto/go/gitalypb/diff.pb.go @@ -126,6 +126,63 @@ func (CommitDiffRequest_WhitespaceChanges) EnumDescriptor() ([]byte, []int) { return file_diff_proto_rawDescGZIP(), []int{0, 1} } +// MergeCommitDiffMode controls which mode to use to produce diff output for merge commits +type FindChangedPathsRequest_MergeCommitDiffMode int32 + +const ( + // MERGE_COMMIT_DIFF_MODE_UNSPECIFIED is the default value. + // It is equivalent to DIFF_MODE_INCLUDE_MERGES. + FindChangedPathsRequest_MERGE_COMMIT_DIFF_MODE_UNSPECIFIED FindChangedPathsRequest_MergeCommitDiffMode = 0 + // MERGE_COMMIT_DIFF_MODE_INCLUDE_MERGES tells git to also show differences for merge commits. + // Please refer to the documentation of the `-m` flag of git-diff-tree(1). + FindChangedPathsRequest_MERGE_COMMIT_DIFF_MODE_INCLUDE_MERGES FindChangedPathsRequest_MergeCommitDiffMode = 1 + // MERGE_COMMIT_DIFF_MODE_ALL_PARENTS tells git to only show differences for + // files which were modified from all parents. + // Please refer to the documentation of the `-c` flag of git-diff-tree(1). + FindChangedPathsRequest_MERGE_COMMIT_DIFF_MODE_ALL_PARENTS FindChangedPathsRequest_MergeCommitDiffMode = 2 +) + +// Enum value maps for FindChangedPathsRequest_MergeCommitDiffMode. +var ( + FindChangedPathsRequest_MergeCommitDiffMode_name = map[int32]string{ + 0: "MERGE_COMMIT_DIFF_MODE_UNSPECIFIED", + 1: "MERGE_COMMIT_DIFF_MODE_INCLUDE_MERGES", + 2: "MERGE_COMMIT_DIFF_MODE_ALL_PARENTS", + } + FindChangedPathsRequest_MergeCommitDiffMode_value = map[string]int32{ + "MERGE_COMMIT_DIFF_MODE_UNSPECIFIED": 0, + "MERGE_COMMIT_DIFF_MODE_INCLUDE_MERGES": 1, + "MERGE_COMMIT_DIFF_MODE_ALL_PARENTS": 2, + } +) + +func (x FindChangedPathsRequest_MergeCommitDiffMode) Enum() *FindChangedPathsRequest_MergeCommitDiffMode { + p := new(FindChangedPathsRequest_MergeCommitDiffMode) + *p = x + return p +} + +func (x FindChangedPathsRequest_MergeCommitDiffMode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (FindChangedPathsRequest_MergeCommitDiffMode) Descriptor() protoreflect.EnumDescriptor { + return file_diff_proto_enumTypes[2].Descriptor() +} + +func (FindChangedPathsRequest_MergeCommitDiffMode) Type() protoreflect.EnumType { + return &file_diff_proto_enumTypes[2] +} + +func (x FindChangedPathsRequest_MergeCommitDiffMode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use FindChangedPathsRequest_MergeCommitDiffMode.Descriptor instead. +func (FindChangedPathsRequest_MergeCommitDiffMode) EnumDescriptor() ([]byte, []int) { + return file_diff_proto_rawDescGZIP(), []int{12, 0} +} + // This comment is left unintentionally blank. type ChangedPaths_Status int32 @@ -171,11 +228,11 @@ func (x ChangedPaths_Status) String() string { } func (ChangedPaths_Status) Descriptor() protoreflect.EnumDescriptor { - return file_diff_proto_enumTypes[2].Descriptor() + return file_diff_proto_enumTypes[3].Descriptor() } func (ChangedPaths_Status) Type() protoreflect.EnumType { - return &file_diff_proto_enumTypes[2] + return &file_diff_proto_enumTypes[3] } func (x ChangedPaths_Status) Number() protoreflect.EnumNumber { @@ -1200,6 +1257,8 @@ type FindChangedPathsRequest struct { Commits []string `protobuf:"bytes,2,rep,name=commits,proto3" json:"commits,omitempty"` // requests specifies the requests of what to compare. Requests []*FindChangedPathsRequest_Request `protobuf:"bytes,3,rep,name=requests,proto3" json:"requests,omitempty"` + // MergeCommitDiffMode controls how merge commits are treated. + MergeCommitDiffMode FindChangedPathsRequest_MergeCommitDiffMode `protobuf:"varint,4,opt,name=merge_commit_diff_mode,json=mergeCommitDiffMode,proto3,enum=gitaly.FindChangedPathsRequest_MergeCommitDiffMode" json:"merge_commit_diff_mode,omitempty"` } func (x *FindChangedPathsRequest) Reset() { @@ -1256,13 +1315,22 @@ func (x *FindChangedPathsRequest) GetRequests() []*FindChangedPathsRequest_Reque return nil } +func (x *FindChangedPathsRequest) GetMergeCommitDiffMode() FindChangedPathsRequest_MergeCommitDiffMode { + if x != nil { + return x.MergeCommitDiffMode + } + return FindChangedPathsRequest_MERGE_COMMIT_DIFF_MODE_UNSPECIFIED +} + // Returns a list of files that have been changed in the commits given type FindChangedPathsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // This comment is left unintentionally blank. + // paths contains the attributes for one changed file. In case of merge + // commits, or when comparing three or more commits, a file might be included + // more than once if it was changed between multiple commits. Paths []*ChangedPaths `protobuf:"bytes,1,rep,name=paths,proto3" json:"paths,omitempty"` } @@ -1884,7 +1952,7 @@ var file_diff_proto_rawDesc = []byte{ 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x44, 0x69, 0x66, 0x66, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, - 0x73, 0x22, 0xe3, 0x04, 0x0a, 0x17, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x73, 0x22, 0xe0, 0x06, 0x0a, 0x17, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, @@ -1895,104 +1963,120 @@ var file_diff_proto_rawDesc = []byte{ 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x1a, 0xaa, 0x03, 0x0a, 0x07, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x58, 0x0a, 0x0c, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x72, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x67, - 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, - 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x72, 0x65, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x48, 0x00, 0x52, 0x0b, 0x74, 0x72, 0x65, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x5e, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, - 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, - 0x68, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, - 0x00, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x6b, 0x0a, 0x0b, 0x54, 0x72, 0x65, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x2c, 0x0a, 0x12, 0x6c, 0x65, 0x66, 0x74, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x72, 0x65, 0x76, - 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x6c, 0x65, 0x66, - 0x74, 0x54, 0x72, 0x65, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, - 0x13, 0x72, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x72, 0x65, 0x76, 0x69, - 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x72, 0x69, 0x67, 0x68, - 0x74, 0x54, 0x72, 0x65, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x70, 0x0a, - 0x0d, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, - 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, - 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, - 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x0a, 0x17, 0x70, 0x61, 0x72, 0x65, 0x6e, - 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, - 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x15, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x42, - 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x46, 0x0a, 0x18, 0x46, 0x69, 0x6e, 0x64, 0x43, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, 0x52, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x22, - 0xda, 0x01, 0x0a, 0x0c, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, - 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, - 0x70, 0x61, 0x74, 0x68, 0x12, 0x33, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x68, - 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x6c, 0x64, - 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x6f, 0x6c, 0x64, - 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x65, 0x77, 0x5f, 0x6d, 0x6f, 0x64, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x6e, 0x65, 0x77, 0x4d, 0x6f, 0x64, 0x65, 0x22, - 0x4b, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x44, 0x44, - 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x4d, 0x4f, 0x44, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, - 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x03, - 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4f, 0x50, 0x49, 0x45, 0x44, 0x10, 0x04, 0x22, 0x93, 0x01, 0x0a, - 0x11, 0x47, 0x65, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, - 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, - 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x21, 0x0a, 0x0c, - 0x6f, 0x6c, 0x64, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x0b, 0x6f, 0x6c, 0x64, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, - 0x21, 0x0a, 0x0c, 0x6e, 0x65, 0x77, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x6e, 0x65, 0x77, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, - 0x6f, 0x6e, 0x22, 0x2f, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x49, 0x44, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x70, 0x61, 0x74, 0x63, - 0x68, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x74, 0x63, - 0x68, 0x49, 0x64, 0x32, 0xb7, 0x04, 0x0a, 0x0b, 0x44, 0x69, 0x66, 0x66, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x44, 0x69, 0x66, - 0x66, 0x12, 0x19, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x67, - 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x44, 0x69, 0x66, 0x66, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, - 0x30, 0x01, 0x12, 0x50, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x44, 0x65, 0x6c, 0x74, - 0x61, 0x12, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x44, 0x65, 0x6c, - 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, - 0x08, 0x02, 0x30, 0x01, 0x12, 0x44, 0x0a, 0x07, 0x52, 0x61, 0x77, 0x44, 0x69, 0x66, 0x66, 0x12, - 0x16, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x61, 0x77, 0x44, 0x69, 0x66, 0x66, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, - 0x2e, 0x52, 0x61, 0x77, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x47, 0x0a, 0x08, 0x52, 0x61, - 0x77, 0x50, 0x61, 0x74, 0x63, 0x68, 0x12, 0x17, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, - 0x52, 0x61, 0x77, 0x50, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x18, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x61, 0x77, 0x50, 0x61, 0x74, 0x63, - 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, - 0x02, 0x30, 0x01, 0x12, 0x4a, 0x0a, 0x09, 0x44, 0x69, 0x66, 0x66, 0x53, 0x74, 0x61, 0x74, 0x73, - 0x12, 0x18, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x44, 0x69, 0x66, 0x66, 0x53, 0x74, - 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x67, 0x69, 0x74, - 0x61, 0x6c, 0x79, 0x2e, 0x44, 0x69, 0x66, 0x66, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, + 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x68, 0x0a, 0x16, 0x6d, 0x65, + 0x72, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x64, 0x69, 0x66, 0x66, 0x5f, + 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x33, 0x2e, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, + 0x61, 0x74, 0x68, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x72, 0x67, + 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x44, 0x69, 0x66, 0x66, 0x4d, 0x6f, 0x64, 0x65, 0x52, + 0x13, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x44, 0x69, 0x66, 0x66, + 0x4d, 0x6f, 0x64, 0x65, 0x1a, 0xaa, 0x03, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x58, 0x0a, 0x0c, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, + 0x46, 0x69, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, + 0x54, 0x72, 0x65, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x74, + 0x72, 0x65, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x5e, 0x0a, 0x0e, 0x63, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, + 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0d, 0x63, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x6b, 0x0a, 0x0b, 0x54, 0x72, + 0x65, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x6c, 0x65, 0x66, + 0x74, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x6c, 0x65, 0x66, 0x74, 0x54, 0x72, 0x65, 0x65, 0x52, + 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x13, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x72, 0x69, 0x67, 0x68, 0x74, 0x54, 0x72, 0x65, 0x65, 0x52, + 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x70, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x36, 0x0a, 0x17, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x15, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x22, 0x90, 0x01, 0x0a, 0x13, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x44, 0x69, 0x66, 0x66, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x26, 0x0a, 0x22, 0x4d, 0x45, 0x52, + 0x47, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x5f, 0x44, 0x49, 0x46, 0x46, 0x5f, 0x4d, + 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x29, 0x0a, 0x25, 0x4d, 0x45, 0x52, 0x47, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x49, + 0x54, 0x5f, 0x44, 0x49, 0x46, 0x46, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x49, 0x4e, 0x43, 0x4c, + 0x55, 0x44, 0x45, 0x5f, 0x4d, 0x45, 0x52, 0x47, 0x45, 0x53, 0x10, 0x01, 0x12, 0x26, 0x0a, 0x22, + 0x4d, 0x45, 0x52, 0x47, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x5f, 0x44, 0x49, 0x46, + 0x46, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x41, 0x4c, 0x4c, 0x5f, 0x50, 0x41, 0x52, 0x45, 0x4e, + 0x54, 0x53, 0x10, 0x02, 0x22, 0x46, 0x0a, 0x18, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x2a, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x14, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, + 0x50, 0x61, 0x74, 0x68, 0x73, 0x52, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x22, 0xda, 0x01, 0x0a, + 0x0c, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, 0x12, 0x12, 0x0a, + 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x70, 0x61, 0x74, + 0x68, 0x12, 0x33, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x1b, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x6c, 0x64, 0x5f, 0x6d, 0x6f, + 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x6f, 0x6c, 0x64, 0x4d, 0x6f, 0x64, + 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x65, 0x77, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x07, 0x6e, 0x65, 0x77, 0x4d, 0x6f, 0x64, 0x65, 0x22, 0x4b, 0x0a, 0x06, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x44, 0x44, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x4d, 0x4f, 0x44, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x01, 0x12, + 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x03, 0x12, 0x0a, 0x0a, + 0x06, 0x43, 0x4f, 0x50, 0x49, 0x45, 0x44, 0x10, 0x04, 0x22, 0x93, 0x01, 0x0a, 0x11, 0x47, 0x65, + 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x98, 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x6f, 0x6c, 0x64, + 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0b, 0x6f, 0x6c, 0x64, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, + 0x6e, 0x65, 0x77, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x0b, 0x6e, 0x65, 0x77, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x22, + 0x2f, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x49, 0x44, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x74, 0x63, 0x68, 0x49, 0x64, + 0x32, 0xb7, 0x04, 0x0a, 0x0b, 0x44, 0x69, 0x66, 0x66, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x4d, 0x0a, 0x0a, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x44, 0x69, 0x66, 0x66, 0x12, 0x19, + 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x44, 0x69, + 0x66, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, - 0x5f, 0x0a, 0x10, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, - 0x74, 0x68, 0x73, 0x12, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, - 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, - 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, 0x52, 0x65, + 0x50, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x12, 0x1a, + 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x44, 0x65, + 0x6c, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, + 0x01, 0x12, 0x44, 0x0a, 0x07, 0x52, 0x61, 0x77, 0x44, 0x69, 0x66, 0x66, 0x12, 0x16, 0x2e, 0x67, + 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x61, 0x77, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x61, + 0x77, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, + 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x47, 0x0a, 0x08, 0x52, 0x61, 0x77, 0x50, 0x61, + 0x74, 0x63, 0x68, 0x12, 0x17, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x61, 0x77, + 0x50, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x67, + 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x61, 0x77, 0x50, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, - 0x12, 0x4b, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x49, 0x44, 0x12, 0x19, - 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, - 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, - 0x6c, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x49, 0x44, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x42, 0x34, 0x5a, - 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, - 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, - 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, - 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x12, 0x4a, 0x0a, 0x09, 0x44, 0x69, 0x66, 0x66, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x18, 0x2e, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x44, 0x69, 0x66, 0x66, 0x53, 0x74, 0x61, 0x74, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, + 0x2e, 0x44, 0x69, 0x66, 0x66, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x5f, 0x0a, 0x10, + 0x46, 0x69, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, + 0x12, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x20, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x43, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x30, 0x01, 0x12, 0x4b, 0x0a, + 0x0a, 0x47, 0x65, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x49, 0x44, 0x12, 0x19, 0x2e, 0x67, 0x69, + 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x49, 0x44, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, + 0x47, 0x65, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x06, 0xfa, 0x97, 0x28, 0x02, 0x08, 0x02, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, + 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, + 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x35, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x70, 0x62, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2007,72 +2091,74 @@ func file_diff_proto_rawDescGZIP() []byte { return file_diff_proto_rawDescData } -var file_diff_proto_enumTypes = make([]protoimpl.EnumInfo, 3) +var file_diff_proto_enumTypes = make([]protoimpl.EnumInfo, 4) var file_diff_proto_msgTypes = make([]protoimpl.MessageInfo, 21) var file_diff_proto_goTypes = []interface{}{ (CommitDiffRequest_DiffMode)(0), // 0: gitaly.CommitDiffRequest.DiffMode (CommitDiffRequest_WhitespaceChanges)(0), // 1: gitaly.CommitDiffRequest.WhitespaceChanges - (ChangedPaths_Status)(0), // 2: gitaly.ChangedPaths.Status - (*CommitDiffRequest)(nil), // 3: gitaly.CommitDiffRequest - (*CommitDiffResponse)(nil), // 4: gitaly.CommitDiffResponse - (*CommitDeltaRequest)(nil), // 5: gitaly.CommitDeltaRequest - (*CommitDelta)(nil), // 6: gitaly.CommitDelta - (*CommitDeltaResponse)(nil), // 7: gitaly.CommitDeltaResponse - (*RawDiffRequest)(nil), // 8: gitaly.RawDiffRequest - (*RawDiffResponse)(nil), // 9: gitaly.RawDiffResponse - (*RawPatchRequest)(nil), // 10: gitaly.RawPatchRequest - (*RawPatchResponse)(nil), // 11: gitaly.RawPatchResponse - (*DiffStatsRequest)(nil), // 12: gitaly.DiffStatsRequest - (*DiffStats)(nil), // 13: gitaly.DiffStats - (*DiffStatsResponse)(nil), // 14: gitaly.DiffStatsResponse - (*FindChangedPathsRequest)(nil), // 15: gitaly.FindChangedPathsRequest - (*FindChangedPathsResponse)(nil), // 16: gitaly.FindChangedPathsResponse - (*ChangedPaths)(nil), // 17: gitaly.ChangedPaths - (*GetPatchIDRequest)(nil), // 18: gitaly.GetPatchIDRequest - (*GetPatchIDResponse)(nil), // 19: gitaly.GetPatchIDResponse - nil, // 20: gitaly.CommitDiffRequest.MaxPatchBytesForFileExtensionEntry - (*FindChangedPathsRequest_Request)(nil), // 21: gitaly.FindChangedPathsRequest.Request - (*FindChangedPathsRequest_Request_TreeRequest)(nil), // 22: gitaly.FindChangedPathsRequest.Request.TreeRequest - (*FindChangedPathsRequest_Request_CommitRequest)(nil), // 23: gitaly.FindChangedPathsRequest.Request.CommitRequest - (*Repository)(nil), // 24: gitaly.Repository + (FindChangedPathsRequest_MergeCommitDiffMode)(0), // 2: gitaly.FindChangedPathsRequest.MergeCommitDiffMode + (ChangedPaths_Status)(0), // 3: gitaly.ChangedPaths.Status + (*CommitDiffRequest)(nil), // 4: gitaly.CommitDiffRequest + (*CommitDiffResponse)(nil), // 5: gitaly.CommitDiffResponse + (*CommitDeltaRequest)(nil), // 6: gitaly.CommitDeltaRequest + (*CommitDelta)(nil), // 7: gitaly.CommitDelta + (*CommitDeltaResponse)(nil), // 8: gitaly.CommitDeltaResponse + (*RawDiffRequest)(nil), // 9: gitaly.RawDiffRequest + (*RawDiffResponse)(nil), // 10: gitaly.RawDiffResponse + (*RawPatchRequest)(nil), // 11: gitaly.RawPatchRequest + (*RawPatchResponse)(nil), // 12: gitaly.RawPatchResponse + (*DiffStatsRequest)(nil), // 13: gitaly.DiffStatsRequest + (*DiffStats)(nil), // 14: gitaly.DiffStats + (*DiffStatsResponse)(nil), // 15: gitaly.DiffStatsResponse + (*FindChangedPathsRequest)(nil), // 16: gitaly.FindChangedPathsRequest + (*FindChangedPathsResponse)(nil), // 17: gitaly.FindChangedPathsResponse + (*ChangedPaths)(nil), // 18: gitaly.ChangedPaths + (*GetPatchIDRequest)(nil), // 19: gitaly.GetPatchIDRequest + (*GetPatchIDResponse)(nil), // 20: gitaly.GetPatchIDResponse + nil, // 21: gitaly.CommitDiffRequest.MaxPatchBytesForFileExtensionEntry + (*FindChangedPathsRequest_Request)(nil), // 22: gitaly.FindChangedPathsRequest.Request + (*FindChangedPathsRequest_Request_TreeRequest)(nil), // 23: gitaly.FindChangedPathsRequest.Request.TreeRequest + (*FindChangedPathsRequest_Request_CommitRequest)(nil), // 24: gitaly.FindChangedPathsRequest.Request.CommitRequest + (*Repository)(nil), // 25: gitaly.Repository } var file_diff_proto_depIdxs = []int32{ - 24, // 0: gitaly.CommitDiffRequest.repository:type_name -> gitaly.Repository + 25, // 0: gitaly.CommitDiffRequest.repository:type_name -> gitaly.Repository 0, // 1: gitaly.CommitDiffRequest.diff_mode:type_name -> gitaly.CommitDiffRequest.DiffMode - 20, // 2: gitaly.CommitDiffRequest.max_patch_bytes_for_file_extension:type_name -> gitaly.CommitDiffRequest.MaxPatchBytesForFileExtensionEntry + 21, // 2: gitaly.CommitDiffRequest.max_patch_bytes_for_file_extension:type_name -> gitaly.CommitDiffRequest.MaxPatchBytesForFileExtensionEntry 1, // 3: gitaly.CommitDiffRequest.whitespace_changes:type_name -> gitaly.CommitDiffRequest.WhitespaceChanges - 24, // 4: gitaly.CommitDeltaRequest.repository:type_name -> gitaly.Repository - 6, // 5: gitaly.CommitDeltaResponse.deltas:type_name -> gitaly.CommitDelta - 24, // 6: gitaly.RawDiffRequest.repository:type_name -> gitaly.Repository - 24, // 7: gitaly.RawPatchRequest.repository:type_name -> gitaly.Repository - 24, // 8: gitaly.DiffStatsRequest.repository:type_name -> gitaly.Repository - 13, // 9: gitaly.DiffStatsResponse.stats:type_name -> gitaly.DiffStats - 24, // 10: gitaly.FindChangedPathsRequest.repository:type_name -> gitaly.Repository - 21, // 11: gitaly.FindChangedPathsRequest.requests:type_name -> gitaly.FindChangedPathsRequest.Request - 17, // 12: gitaly.FindChangedPathsResponse.paths:type_name -> gitaly.ChangedPaths - 2, // 13: gitaly.ChangedPaths.status:type_name -> gitaly.ChangedPaths.Status - 24, // 14: gitaly.GetPatchIDRequest.repository:type_name -> gitaly.Repository - 22, // 15: gitaly.FindChangedPathsRequest.Request.tree_request:type_name -> gitaly.FindChangedPathsRequest.Request.TreeRequest - 23, // 16: gitaly.FindChangedPathsRequest.Request.commit_request:type_name -> gitaly.FindChangedPathsRequest.Request.CommitRequest - 3, // 17: gitaly.DiffService.CommitDiff:input_type -> gitaly.CommitDiffRequest - 5, // 18: gitaly.DiffService.CommitDelta:input_type -> gitaly.CommitDeltaRequest - 8, // 19: gitaly.DiffService.RawDiff:input_type -> gitaly.RawDiffRequest - 10, // 20: gitaly.DiffService.RawPatch:input_type -> gitaly.RawPatchRequest - 12, // 21: gitaly.DiffService.DiffStats:input_type -> gitaly.DiffStatsRequest - 15, // 22: gitaly.DiffService.FindChangedPaths:input_type -> gitaly.FindChangedPathsRequest - 18, // 23: gitaly.DiffService.GetPatchID:input_type -> gitaly.GetPatchIDRequest - 4, // 24: gitaly.DiffService.CommitDiff:output_type -> gitaly.CommitDiffResponse - 7, // 25: gitaly.DiffService.CommitDelta:output_type -> gitaly.CommitDeltaResponse - 9, // 26: gitaly.DiffService.RawDiff:output_type -> gitaly.RawDiffResponse - 11, // 27: gitaly.DiffService.RawPatch:output_type -> gitaly.RawPatchResponse - 14, // 28: gitaly.DiffService.DiffStats:output_type -> gitaly.DiffStatsResponse - 16, // 29: gitaly.DiffService.FindChangedPaths:output_type -> gitaly.FindChangedPathsResponse - 19, // 30: gitaly.DiffService.GetPatchID:output_type -> gitaly.GetPatchIDResponse - 24, // [24:31] is the sub-list for method output_type - 17, // [17:24] is the sub-list for method input_type - 17, // [17:17] is the sub-list for extension type_name - 17, // [17:17] is the sub-list for extension extendee - 0, // [0:17] is the sub-list for field type_name + 25, // 4: gitaly.CommitDeltaRequest.repository:type_name -> gitaly.Repository + 7, // 5: gitaly.CommitDeltaResponse.deltas:type_name -> gitaly.CommitDelta + 25, // 6: gitaly.RawDiffRequest.repository:type_name -> gitaly.Repository + 25, // 7: gitaly.RawPatchRequest.repository:type_name -> gitaly.Repository + 25, // 8: gitaly.DiffStatsRequest.repository:type_name -> gitaly.Repository + 14, // 9: gitaly.DiffStatsResponse.stats:type_name -> gitaly.DiffStats + 25, // 10: gitaly.FindChangedPathsRequest.repository:type_name -> gitaly.Repository + 22, // 11: gitaly.FindChangedPathsRequest.requests:type_name -> gitaly.FindChangedPathsRequest.Request + 2, // 12: gitaly.FindChangedPathsRequest.merge_commit_diff_mode:type_name -> gitaly.FindChangedPathsRequest.MergeCommitDiffMode + 18, // 13: gitaly.FindChangedPathsResponse.paths:type_name -> gitaly.ChangedPaths + 3, // 14: gitaly.ChangedPaths.status:type_name -> gitaly.ChangedPaths.Status + 25, // 15: gitaly.GetPatchIDRequest.repository:type_name -> gitaly.Repository + 23, // 16: gitaly.FindChangedPathsRequest.Request.tree_request:type_name -> gitaly.FindChangedPathsRequest.Request.TreeRequest + 24, // 17: gitaly.FindChangedPathsRequest.Request.commit_request:type_name -> gitaly.FindChangedPathsRequest.Request.CommitRequest + 4, // 18: gitaly.DiffService.CommitDiff:input_type -> gitaly.CommitDiffRequest + 6, // 19: gitaly.DiffService.CommitDelta:input_type -> gitaly.CommitDeltaRequest + 9, // 20: gitaly.DiffService.RawDiff:input_type -> gitaly.RawDiffRequest + 11, // 21: gitaly.DiffService.RawPatch:input_type -> gitaly.RawPatchRequest + 13, // 22: gitaly.DiffService.DiffStats:input_type -> gitaly.DiffStatsRequest + 16, // 23: gitaly.DiffService.FindChangedPaths:input_type -> gitaly.FindChangedPathsRequest + 19, // 24: gitaly.DiffService.GetPatchID:input_type -> gitaly.GetPatchIDRequest + 5, // 25: gitaly.DiffService.CommitDiff:output_type -> gitaly.CommitDiffResponse + 8, // 26: gitaly.DiffService.CommitDelta:output_type -> gitaly.CommitDeltaResponse + 10, // 27: gitaly.DiffService.RawDiff:output_type -> gitaly.RawDiffResponse + 12, // 28: gitaly.DiffService.RawPatch:output_type -> gitaly.RawPatchResponse + 15, // 29: gitaly.DiffService.DiffStats:output_type -> gitaly.DiffStatsResponse + 17, // 30: gitaly.DiffService.FindChangedPaths:output_type -> gitaly.FindChangedPathsResponse + 20, // 31: gitaly.DiffService.GetPatchID:output_type -> gitaly.GetPatchIDResponse + 25, // [25:32] is the sub-list for method output_type + 18, // [18:25] is the sub-list for method input_type + 18, // [18:18] is the sub-list for extension type_name + 18, // [18:18] is the sub-list for extension extendee + 0, // [0:18] is the sub-list for field type_name } func init() { file_diff_proto_init() } @@ -2333,7 +2419,7 @@ func file_diff_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_diff_proto_rawDesc, - NumEnums: 3, + NumEnums: 4, NumMessages: 21, NumExtensions: 0, NumServices: 1,