diff --git a/models/git_diff.go b/models/git_diff.go index 006238cd0..d288ea50b 100644 --- a/models/git_diff.go +++ b/models/git_diff.go @@ -633,6 +633,13 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D // passing the empty string as beforeCommitID returns a diff from the // parent commit. func GetDiffRange(repoPath, beforeCommitID, afterCommitID string, maxLines, maxLineCharacters, maxFiles int) (*Diff, error) { + return GetDiffRangeWithWhitespaceBehavior(repoPath, beforeCommitID, afterCommitID, maxLines, maxLineCharacters, maxFiles, "") +} + +// GetDiffRangeWithWhitespaceBehavior builds a Diff between two commits of a repository. +// Passing the empty string as beforeCommitID returns a diff from the parent commit. +// The whitespaceBehavior is either an empty string or a git flag +func GetDiffRangeWithWhitespaceBehavior(repoPath, beforeCommitID, afterCommitID string, maxLines, maxLineCharacters, maxFiles int, whitespaceBehavior string) (*Diff, error) { gitRepo, err := git.OpenRepository(repoPath) if err != nil { return nil, err @@ -644,17 +651,21 @@ func GetDiffRange(repoPath, beforeCommitID, afterCommitID string, maxLines, maxL } var cmd *exec.Cmd - // if "after" commit given - if len(beforeCommitID) == 0 { - // First commit of repository. - if commit.ParentCount() == 0 { - cmd = exec.Command("git", "show", afterCommitID) - } else { - c, _ := commit.Parent(0) - cmd = exec.Command("git", "diff", "-M", c.ID.String(), afterCommitID) - } + if len(beforeCommitID) == 0 && commit.ParentCount() == 0 { + cmd = exec.Command("git", "show", afterCommitID) } else { - cmd = exec.Command("git", "diff", "-M", beforeCommitID, afterCommitID) + actualBeforeCommitID := beforeCommitID + if len(actualBeforeCommitID) == 0 { + parentCommit, _ := commit.Parent(0) + actualBeforeCommitID = parentCommit.ID.String() + } + diffArgs := []string{"diff", "-M"} + if len(whitespaceBehavior) != 0 { + diffArgs = append(diffArgs, whitespaceBehavior) + } + diffArgs = append(diffArgs, actualBeforeCommitID) + diffArgs = append(diffArgs, afterCommitID) + cmd = exec.Command("git", diffArgs...) } cmd.Dir = repoPath cmd.Stderr = os.Stderr diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 2b0478748..635ddd66b 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1152,6 +1152,11 @@ diff.data_not_available = Diff Content Not Available diff.show_diff_stats = Show Diff Stats diff.show_split_view = Split View diff.show_unified_view = Unified View +diff.whitespace_button = Whitespace +diff.whitespace_show_everything = Show all changes +diff.whitespace_ignore_all_whitespace = Ignore whitespace when comparing lines +diff.whitespace_ignore_amount_changes = Ignore changes in amount of whitespace +diff.whitespace_ignore_at_eol = Ignore changes in whitespace at EOL diff.stats_desc = %d changed files with %d additions and %d deletions diff.bin = BIN diff.view_file = View File diff --git a/routers/repo/middlewares.go b/routers/repo/middlewares.go index 8afad5be6..4dee272ed 100644 --- a/routers/repo/middlewares.go +++ b/routers/repo/middlewares.go @@ -50,3 +50,14 @@ func SetDiffViewStyle(ctx *context.Context) { ctx.ServerError("ErrUpdateDiffViewStyle", err) } } + +// SetWhitespaceBehavior set whitespace behavior as render variable +func SetWhitespaceBehavior(ctx *context.Context) { + whitespaceBehavior := ctx.Query("whitespace") + switch whitespaceBehavior { + case "ignore-all", "ignore-eol", "ignore-change": + ctx.Data["WhitespaceBehavior"] = whitespaceBehavior + default: + ctx.Data["WhitespaceBehavior"] = "" + } +} diff --git a/routers/repo/pull.go b/routers/repo/pull.go index 6a1aaf314..57fe33f85 100644 --- a/routers/repo/pull.go +++ b/routers/repo/pull.go @@ -390,6 +390,12 @@ func ViewPullFiles(ctx *context.Context) { } pull := issue.PullRequest + whitespaceFlags := map[string]string{ + "ignore-all": "-w", + "ignore-change": "-b", + "ignore-eol": "--ignore-space-at-eol", + "": ""} + var ( diffRepoPath string startCommitID string @@ -455,11 +461,12 @@ func ViewPullFiles(ctx *context.Context) { ctx.Data["Reponame"] = pull.HeadRepo.Name } - diff, err := models.GetDiffRange(diffRepoPath, + diff, err := models.GetDiffRangeWithWhitespaceBehavior(diffRepoPath, startCommitID, endCommitID, setting.Git.MaxGitDiffLines, - setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles) + setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, + whitespaceFlags[ctx.Data["WhitespaceBehavior"].(string)]) if err != nil { - ctx.ServerError("GetDiffRange", err) + ctx.ServerError("GetDiffRangeWithWhitespaceBehavior", err) return } diff --git a/routers/routes/routes.go b/routers/routes/routes.go index cc36829ef..e2448a744 100644 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -674,7 +674,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/merge", reqRepoWriter, bindIgnErr(auth.MergePullRequestForm{}), repo.MergePullRequest) m.Post("/cleanup", context.RepoRef(), repo.CleanUpPullRequest) m.Group("/files", func() { - m.Get("", context.RepoRef(), repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.ViewPullFiles) + m.Get("", context.RepoRef(), repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.ViewPullFiles) m.Group("/reviews", func() { m.Post("/comments", bindIgnErr(auth.CodeCommentForm{}), repo.CreateCodeComment) m.Post("/submit", bindIgnErr(auth.SubmitReviewForm{}), repo.SubmitReview) diff --git a/templates/repo/diff/box.tmpl b/templates/repo/diff/box.tmpl index 0a9552acc..382442fe3 100644 --- a/templates/repo/diff/box.tmpl +++ b/templates/repo/diff/box.tmpl @@ -1,4 +1,19 @@ {{if .DiffNotAvailable}} +