diff options
Diffstat (limited to 'modules/git/diff.go')
-rw-r--r-- | modules/git/diff.go | 47 |
1 files changed, 32 insertions, 15 deletions
diff --git a/modules/git/diff.go b/modules/git/diff.go index 833f6220f9..35d115be0e 100644 --- a/modules/git/diff.go +++ b/modules/git/diff.go @@ -34,8 +34,8 @@ func GetRawDiff(repo *Repository, commitID string, diffType RawDiffType, writer // GetReverseRawDiff dumps the reverse diff results of repository in given commit ID to io.Writer. func GetReverseRawDiff(ctx context.Context, repoPath, commitID string, writer io.Writer) error { stderr := new(bytes.Buffer) - cmd := NewCommand(ctx, "show", "--pretty=format:revert %H%n", "-R").AddDynamicArguments(commitID) - if err := cmd.Run(&RunOpts{ + cmd := NewCommand("show", "--pretty=format:revert %H%n", "-R").AddDynamicArguments(commitID) + if err := cmd.Run(ctx, &RunOpts{ Dir: repoPath, Stdout: writer, Stderr: stderr, @@ -56,7 +56,7 @@ func GetRepoRawDiffForFile(repo *Repository, startCommit, endCommit string, diff files = append(files, file) } - cmd := NewCommand(repo.Ctx) + cmd := NewCommand() switch diffType { case RawDiffNormal: if len(startCommit) != 0 { @@ -64,7 +64,10 @@ func GetRepoRawDiffForFile(repo *Repository, startCommit, endCommit string, diff } else if commit.ParentCount() == 0 { cmd.AddArguments("show").AddDynamicArguments(endCommit).AddDashesAndList(files...) } else { - c, _ := commit.Parent(0) + c, err := commit.Parent(0) + if err != nil { + return err + } cmd.AddArguments("diff", "-M").AddDynamicArguments(c.ID.String(), endCommit).AddDashesAndList(files...) } case RawDiffPatch: @@ -74,7 +77,10 @@ func GetRepoRawDiffForFile(repo *Repository, startCommit, endCommit string, diff } else if commit.ParentCount() == 0 { cmd.AddArguments("format-patch", "--no-signature", "--stdout", "--root").AddDynamicArguments(endCommit).AddDashesAndList(files...) } else { - c, _ := commit.Parent(0) + c, err := commit.Parent(0) + if err != nil { + return err + } query := fmt.Sprintf("%s...%s", endCommit, c.ID.String()) cmd.AddArguments("format-patch", "--no-signature", "--stdout").AddDynamicArguments(query).AddDashesAndList(files...) } @@ -83,7 +89,7 @@ func GetRepoRawDiffForFile(repo *Repository, startCommit, endCommit string, diff } stderr := new(bytes.Buffer) - if err = cmd.Run(&RunOpts{ + if err = cmd.Run(repo.Ctx, &RunOpts{ Dir: repo.Path, Stdout: writer, Stderr: stderr, @@ -93,9 +99,9 @@ func GetRepoRawDiffForFile(repo *Repository, startCommit, endCommit string, diff return nil } -// ParseDiffHunkString parse the diffhunk content and return -func ParseDiffHunkString(diffhunk string) (leftLine, leftHunk, rightLine, righHunk int) { - ss := strings.Split(diffhunk, "@@") +// ParseDiffHunkString parse the diff hunk content and return +func ParseDiffHunkString(diffHunk string) (leftLine, leftHunk, rightLine, rightHunk int) { + ss := strings.Split(diffHunk, "@@") ranges := strings.Split(ss[1][1:], " ") leftRange := strings.Split(ranges[0], ",") leftLine, _ = strconv.Atoi(leftRange[0][1:]) @@ -106,14 +112,19 @@ func ParseDiffHunkString(diffhunk string) (leftLine, leftHunk, rightLine, righHu rightRange := strings.Split(ranges[1], ",") rightLine, _ = strconv.Atoi(rightRange[0]) if len(rightRange) > 1 { - righHunk, _ = strconv.Atoi(rightRange[1]) + rightHunk, _ = strconv.Atoi(rightRange[1]) } } else { - log.Debug("Parse line number failed: %v", diffhunk) + log.Debug("Parse line number failed: %v", diffHunk) rightLine = leftLine - righHunk = leftHunk + rightHunk = leftHunk + } + if rightLine == 0 { + // FIXME: GIT-DIFF-CUT-BUG search this tag to see details + // this is only a hacky patch, the rightLine&rightHunk might still be incorrect in some cases. + rightLine++ } - return leftLine, leftHunk, rightLine, righHunk + return leftLine, leftHunk, rightLine, rightHunk } // Example: @@ -1,8 +1,9 @@ => [..., 1, 8, 1, 9] @@ -264,6 +275,12 @@ func CutDiffAroundLine(originalDiff io.Reader, line int64, old bool, numbersOfLi oldNumOfLines++ } } + + // "git diff" outputs "@@ -1 +1,3 @@" for "OLD" => "A\nB\nC" + // FIXME: GIT-DIFF-CUT-BUG But there is a bug in CutDiffAroundLine, then the "Patch" stored in the comment model becomes "@@ -1,1 +0,4 @@" + // It may generate incorrect results for difference cases, for example: delete 2 line add 1 line, delete 2 line add 2 line etc, need to double check. + // For example: "L1\nL2" => "A\nB", then the patch shows "L2" as line 1 on the left (deleted part) + // construct the new hunk header newHunk[headerLines] = fmt.Sprintf("@@ -%d,%d +%d,%d @@", oldBegin, oldNumOfLines, newBegin, newNumOfLines) @@ -295,8 +312,8 @@ func GetAffectedFiles(repo *Repository, branchName, oldCommitID, newCommitID str affectedFiles := make([]string, 0, 32) // Run `git diff --name-only` to get the names of the changed files - err = NewCommand(repo.Ctx, "diff", "--name-only").AddDynamicArguments(oldCommitID, newCommitID). - Run(&RunOpts{ + err = NewCommand("diff", "--name-only").AddDynamicArguments(oldCommitID, newCommitID). + Run(repo.Ctx, &RunOpts{ Env: env, Dir: repo.Path, Stdout: stdoutWriter, |