diff options
author | Jacob Vosmaer (GitLab) <jacob@gitlab.com> | 2017-05-03 16:36:01 +0300 |
---|---|---|
committer | Jacob Vosmaer (GitLab) <jacob@gitlab.com> | 2017-05-03 16:36:01 +0300 |
commit | e86e6d13c4aa40f548043b667d51ab4a4ec74201 (patch) | |
tree | bdd6e13cf799ae11091a1dd4f493a7091da3ec20 | |
parent | ee0823a9607fcbfa81ec09e111832c783853eeab (diff) | |
parent | 368ef05444564b5486c3781136b44ec4a0191c4c (diff) |
Merge branch 'fix/parsing-typechange-diff' into 'master'
Parse a typechange diff correctly
Closes #205
See merge request !136
4 files changed, 81 insertions, 1 deletions
diff --git a/internal/diff/diff.go b/internal/diff/diff.go index 3c60e2d4f..8dd2e80f1 100644 --- a/internal/diff/diff.go +++ b/internal/diff/diff.go @@ -11,6 +11,8 @@ import ( "gitlab.com/gitlab-org/gitaly/internal/helper" ) +const blankID = "0000000000000000000000000000000000000000" + // Diff represents a single parsed diff entry type Diff struct { FromID string @@ -20,6 +22,7 @@ type Diff struct { FromPath []byte ToPath []byte Binary bool + Status byte RawChunks [][]byte } @@ -172,6 +175,9 @@ func (parser *Parser) initializeCurrentDiff() error { parser.err = err return err } + if parser.currentDiff.Status == 'T' { + parser.handleTypeChangeDiff() + } return nil } @@ -200,6 +206,25 @@ func (parser *Parser) findNextPatchFromPath() error { return parser.err } +func (parser *Parser) handleTypeChangeDiff() { + // GitLab wants to display the type change in the current diff as a removal followed by an addition. + // To make this happen we add a new raw line, which will become the addition on the next iteration of the parser. + // We change the current diff in-place so that it becomes a deletion. + newRawLine := fmt.Sprintf( + ":%o %o %s %s A\t%s\n", + 0, + parser.currentDiff.NewMode, + blankID, + parser.currentDiff.ToID, + parser.currentDiff.FromPath, + ) + + parser.currentDiff.NewMode = 0 + parser.currentDiff.ToID = blankID + + parser.rawLines = append([][]byte{[]byte(newRawLine)}, parser.rawLines...) +} + func parseRawLine(line []byte, diff *Diff) error { matches := rawLineRegexp.FindSubmatch(line) if len(matches) == 0 { @@ -220,9 +245,10 @@ func parseRawLine(line []byte, diff *Diff) error { diff.FromID = string(matches[3]) diff.ToID = string(matches[4]) + diff.Status = matches[5][0] diff.FromPath = unescape(helper.UnquoteBytes(matches[6])) - if matches[5][0] == 'C' || matches[5][0] == 'R' { + if diff.Status == 'C' || diff.Status == 'R' { diff.ToPath = unescape(helper.UnquoteBytes(matches[7])) } else { diff.ToPath = diff.FromPath diff --git a/internal/service/diff/commit_test.go b/internal/service/diff/commit_test.go index 9b68a6723..bc1c36922 100644 --- a/internal/service/diff/commit_test.go +++ b/internal/service/diff/commit_test.go @@ -266,6 +266,55 @@ func TestSuccessfulCommitDiffRequestWithPaths(t *testing.T) { assertExactReceivedDiffs(t, c, expectedDiffs) } +func TestSuccessfulCommitDiffRequestWithTypeChangeDiff(t *testing.T) { + server := runDiffServer(t) + defer server.Stop() + + client := newDiffClient(t) + repo := &pb.Repository{Path: testRepoPath} + rightCommit := "184a47d38677e2e439964859b877ae9bc424ab11" + leftCommit := "80d56eb72ba5d77fd8af857eced17a7d0640cb82" + rpcRequest := &pb.CommitDiffRequest{ + Repository: repo, + RightCommitId: rightCommit, + LeftCommitId: leftCommit, + } + + c, err := client.CommitDiff(context.Background(), rpcRequest) + if err != nil { + t.Fatal(err) + } + + expectedDiffs := []expectedDiff{ + { + Diff: diff.Diff{ + FromID: "349cd0f6b1aba8538861d95783cbce6d49d747f8", + ToID: "0000000000000000000000000000000000000000", + OldMode: 0120000, + NewMode: 0, + FromPath: []byte("gitaly/symlink-to-be-regular"), + ToPath: []byte("gitaly/symlink-to-be-regular"), + Binary: false, + }, + ChunksCombined: testhelper.MustReadFile(t, "testdata/symlink-to-be-regular-deleted-chunks.txt"), + }, + { + Diff: diff.Diff{ + FromID: "0000000000000000000000000000000000000000", + ToID: "f9e5cc857610185e6feeb494a26bf27551a4f02b", + OldMode: 0, + NewMode: 0100644, + FromPath: []byte("gitaly/symlink-to-be-regular"), + ToPath: []byte("gitaly/symlink-to-be-regular"), + Binary: false, + }, + ChunksCombined: testhelper.MustReadFile(t, "testdata/symlink-to-be-regular-added-chunks.txt"), + }, + } + + assertExactReceivedDiffs(t, c, expectedDiffs) +} + func TestSuccessfulCommitDiffRequestWithIgnoreWhitespaceChange(t *testing.T) { server := runDiffServer(t) defer server.Stop() diff --git a/internal/service/diff/testdata/symlink-to-be-regular-added-chunks.txt b/internal/service/diff/testdata/symlink-to-be-regular-added-chunks.txt new file mode 100644 index 000000000..5d0743717 --- /dev/null +++ b/internal/service/diff/testdata/symlink-to-be-regular-added-chunks.txt @@ -0,0 +1,2 @@ +@@ -0,0 +1 @@ ++This was symlink, not anymore diff --git a/internal/service/diff/testdata/symlink-to-be-regular-deleted-chunks.txt b/internal/service/diff/testdata/symlink-to-be-regular-deleted-chunks.txt new file mode 100644 index 000000000..0037104bb --- /dev/null +++ b/internal/service/diff/testdata/symlink-to-be-regular-deleted-chunks.txt @@ -0,0 +1,3 @@ +@@ -1 +0,0 @@ +-renamed-file +\ No newline at end of file |