diff options
author | Christopher Brickley <brickley@gmail.com> | 2014-08-26 08:20:18 -0400 |
---|---|---|
committer | Christopher Brickley <brickley@gmail.com> | 2014-09-01 14:56:19 -0400 |
commit | 00a864e693434bce687f3f5145d8369583197b78 (patch) | |
tree | df25bf583ec2a0070c159bcb3d0d161d931f6801 | |
parent | d55c5b9e289c0c97aa51ffe5cb5b77f703cc2a47 (diff) | |
download | gitea-00a864e693434bce687f3f5145d8369583197b78.tar.gz gitea-00a864e693434bce687f3f5145d8369583197b78.zip |
add commit compare functionality
-rw-r--r-- | cmd/web.go | 1 | ||||
-rw-r--r-- | models/action.go | 6 | ||||
-rw-r--r-- | models/git_diff.go | 25 | ||||
-rw-r--r-- | models/slack.go | 14 | ||||
-rw-r--r-- | models/update.go | 4 | ||||
-rw-r--r-- | models/webhook.go | 13 | ||||
-rwxr-xr-x | public/css/gogs.css | 7 | ||||
-rw-r--r-- | routers/repo/commit.go | 65 | ||||
-rw-r--r-- | templates/repo/commits.tmpl | 43 | ||||
-rw-r--r-- | templates/repo/commits_table.tmpl | 42 | ||||
-rw-r--r-- | templates/repo/diff.tmpl | 15 |
11 files changed, 169 insertions, 66 deletions
diff --git a/cmd/web.go b/cmd/web.go index 275d3fb90e..2199d4ca1e 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -342,6 +342,7 @@ func runWeb(*cli.Context) { r.Get("/commit/:branchname/*", repo.Diff) r.Get("/releases", repo.Releases) r.Get("/archive/*.*", repo.Download) + r.Get("/compare/:before([a-z0-9]+)...:after([a-z0-9]+)", repo.CompareDiff) }, ignSignIn, middleware.RepoAssignment(true, true)) m.Group("/:username", func(r *macaron.Router) { diff --git a/models/action.go b/models/action.go index d536c84dd0..5a8c31697c 100644 --- a/models/action.go +++ b/models/action.go @@ -172,7 +172,7 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com // CommitRepoAction adds new action for committing repository. func CommitRepoAction(userId, repoUserId int64, userName, actEmail string, - repoId int64, repoUserName, repoName string, refFullName string, commit *base.PushCommits) error { + repoId int64, repoUserName, repoName string, refFullName string, commit *base.PushCommits, oldCommitId string, newCommitId string) error { opType := COMMIT_REPO // Check it's tag push or branch. @@ -226,6 +226,7 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string, } repoLink := fmt.Sprintf("%s%s/%s", setting.AppUrl, repoUserName, repoName) + compareUrl := fmt.Sprintf("%s/compare/%s...%s", repoLink, oldCommitId, newCommitId) commits := make([]*PayloadCommit, len(commit.Commits)) for i, cmt := range commit.Commits { commits[i] = &PayloadCommit{ @@ -258,6 +259,9 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string, Name: repo.Owner.LowerName, Email: repo.Owner.Email, }, + Before: oldCommitId, + After: newCommitId, + CompareUrl: compareUrl, } for _, w := range ws { diff --git a/models/git_diff.go b/models/git_diff.go index 4b4d1234dd..21a624de5f 100644 --- a/models/git_diff.go +++ b/models/git_diff.go @@ -175,25 +175,30 @@ func ParsePatch(pid int64, cmd *exec.Cmd, reader io.Reader) (*Diff, error) { return diff, nil } -func GetDiff(repoPath, commitid string) (*Diff, error) { +func GetDiffRange(repoPath, beforeCommitId string, afterCommitId string) (*Diff, error) { repo, err := git.OpenRepository(repoPath) if err != nil { return nil, err } - commit, err := repo.GetCommit(commitid) + commit, err := repo.GetCommit(afterCommitId) if err != nil { return nil, err } rd, wr := io.Pipe() var cmd *exec.Cmd - // First commit of repository. - if commit.ParentCount() == 0 { - cmd = exec.Command("git", "show", commitid) + // if "after" commit given + if beforeCommitId == "" { + // First commit of repository. + if commit.ParentCount() == 0 { + cmd = exec.Command("git", "show", afterCommitId) + } else { + c, _ := commit.Parent(0) + cmd = exec.Command("git", "diff", c.Id.String(), afterCommitId) + } } else { - c, _ := commit.Parent(0) - cmd = exec.Command("git", "diff", c.Id.String(), commitid) + cmd = exec.Command("git", "diff", beforeCommitId, afterCommitId) } cmd.Dir = repoPath cmd.Stdout = wr @@ -208,7 +213,7 @@ func GetDiff(repoPath, commitid string) (*Diff, error) { }() defer rd.Close() - desc := fmt.Sprintf("GetDiff(%s)", repoPath) + desc := fmt.Sprintf("GetDiffRange(%s)", repoPath) pid := process.Add(desc, cmd) go func() { // In case process became zombie. @@ -226,3 +231,7 @@ func GetDiff(repoPath, commitid string) (*Diff, error) { return ParsePatch(pid, cmd, rd) } + +func GetDiffCommit(repoPath, commitId string) (*Diff, error) { + return GetDiffRange(repoPath, "", commitId) +} diff --git a/models/slack.go b/models/slack.go index 0a55740947..714b2f6ca2 100644 --- a/models/slack.go +++ b/models/slack.go @@ -70,19 +70,21 @@ func getSlackPushPayload(p *Payload, slack *Slack) (*SlackPayload, error) { branchName := refSplit[len(refSplit)-1] var commitString string - // TODO: add commit compare before/after link when gogs adds it if len(p.Commits) == 1 { commitString = "1 new commit" } else { commitString = fmt.Sprintf("%d new commits", len(p.Commits)) + commitString = SlackLinkFormatter(p.CompareUrl, commitString) } - text := fmt.Sprintf("[%s:%s] %s pushed by %s", p.Repo.Name, branchName, commitString, p.Pusher.Name) + repoLink := SlackLinkFormatter(p.Repo.Url, p.Repo.Name) + branchLink := SlackLinkFormatter(p.Repo.Url+"/src/"+branchName, branchName) + text := fmt.Sprintf("[%s:%s] %s pushed by %s", repoLink, branchLink, commitString, p.Pusher.Name) var attachmentText string // for each commit, generate attachment text for i, commit := range p.Commits { - attachmentText += fmt.Sprintf("<%s|%s>: %s - %s", commit.Url, commit.Id[:7], SlackFormatter(commit.Message), commit.Author.Name) + attachmentText += fmt.Sprintf("%s: %s - %s", SlackLinkFormatter(commit.Url, commit.Id[:7]), SlackTextFormatter(commit.Message), SlackTextFormatter(commit.Author.Name)) // add linebreak to each commit but the last if i < len(p.Commits)-1 { attachmentText += "\n" @@ -103,7 +105,7 @@ func getSlackPushPayload(p *Payload, slack *Slack) (*SlackPayload, error) { } // see: https://api.slack.com/docs/formatting -func SlackFormatter(s string) string { +func SlackTextFormatter(s string) string { // take only first line of commit first := strings.Split(s, "\n")[0] // replace & < > @@ -112,3 +114,7 @@ func SlackFormatter(s string) string { first = strings.Replace(first, ">", ">", -1) return first } + +func SlackLinkFormatter(url string, text string) string { + return fmt.Sprintf("<%s|%s>", url, SlackTextFormatter(text)) +} diff --git a/models/update.go b/models/update.go index 68a92ada1d..ec6a979016 100644 --- a/models/update.go +++ b/models/update.go @@ -101,7 +101,7 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName commit := &base.PushCommits{} if err = CommitRepoAction(userId, ru.Id, userName, actEmail, - repos.Id, repoUserName, repoName, refName, commit); err != nil { + repos.Id, repoUserName, repoName, refName, commit, oldCommitId, newCommitId); err != nil { log.GitLogger.Fatal(4, "runUpdate.models.CommitRepoAction: %s/%s:%v", repoUserName, repoName, err) } return err @@ -152,7 +152,7 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName //commits = append(commits, []string{lastCommit.Id().String(), lastCommit.Message()}) if err = CommitRepoAction(userId, ru.Id, userName, actEmail, - repos.Id, repoUserName, repoName, refName, &base.PushCommits{l.Len(), commits}); err != nil { + repos.Id, repoUserName, repoName, refName, &base.PushCommits{l.Len(), commits}, oldCommitId, newCommitId); err != nil { return fmt.Errorf("runUpdate.models.CommitRepoAction: %s/%s:%v", repoUserName, repoName, err) } return nil diff --git a/models/webhook.go b/models/webhook.go index 55ed4844ed..0b7b3a9948 100644 --- a/models/webhook.go +++ b/models/webhook.go @@ -169,11 +169,14 @@ type BasePayload interface { // Payload represents a payload information of hook. type Payload struct { - Secret string `json:"secret"` - Ref string `json:"ref"` - Commits []*PayloadCommit `json:"commits"` - Repo *PayloadRepo `json:"repository"` - Pusher *PayloadAuthor `json:"pusher"` + Secret string `json:"secret"` + Ref string `json:"ref"` + Commits []*PayloadCommit `json:"commits"` + Repo *PayloadRepo `json:"repository"` + Pusher *PayloadAuthor `json:"pusher"` + Before string `json:"before"` + After string `json:"after"` + CompareUrl string `json:"compare_url"` } func (p Payload) GetJSONPayload() ([]byte, error) { diff --git a/public/css/gogs.css b/public/css/gogs.css index 2d30d06284..0af09a3ecc 100755 --- a/public/css/gogs.css +++ b/public/css/gogs.css @@ -968,6 +968,13 @@ body { .guide-box .zclip { left: auto !important; } +div.compare div#commits { + margin-top: 5px; +} +div.compare div#commits h4 { + margin: 10px 0; + line-height: 1.1; +} .diff-head-box h4 { margin-top: 0; margin-bottom: 0; diff --git a/routers/repo/commit.go b/routers/repo/commit.go index 6320123b40..54acc85b3e 100644 --- a/routers/repo/commit.go +++ b/routers/repo/commit.go @@ -114,9 +114,9 @@ func Diff(ctx *middleware.Context) { commit := ctx.Repo.Commit - diff, err := models.GetDiff(models.RepoPath(userName, repoName), commitId) + diff, err := models.GetDiffCommit(models.RepoPath(userName, repoName), commitId) if err != nil { - ctx.Handle(404, "GetDiff", err) + ctx.Handle(404, "GetDiffCommit", err) return } @@ -162,6 +162,67 @@ func Diff(ctx *middleware.Context) { ctx.HTML(200, DIFF) } +func CompareDiff(ctx *middleware.Context) { + ctx.Data["IsRepoToolbarCommits"] = true + ctx.Data["IsDiffCompare"] = true + userName := ctx.Repo.Owner.Name + repoName := ctx.Repo.Repository.Name + beforeCommitId := ctx.Params(":before") + afterCommitId := ctx.Params(":after") + + commit, err := ctx.Repo.GitRepo.GetCommit(afterCommitId) + if err != nil { + ctx.Handle(404, "GetCommit", err) + return + } + + diff, err := models.GetDiffRange(models.RepoPath(userName, repoName), beforeCommitId, afterCommitId) + if err != nil { + ctx.Handle(404, "GetDiffRange", err) + return + } + + isImageFile := func(name string) bool { + blob, err := commit.GetBlobByPath(name) + if err != nil { + return false + } + + dataRc, err := blob.Data() + if err != nil { + return false + } + buf := make([]byte, 1024) + n, _ := dataRc.Read(buf) + if n > 0 { + buf = buf[:n] + } + _, isImage := base.IsImageFile(buf) + return isImage + } + + commits, err := commit.CommitsBeforeUntil(beforeCommitId) + if err != nil { + ctx.Handle(500, "CommitsBeforeUntil", err) + return + } + + ctx.Data["Commits"] = commits + ctx.Data["CommitCount"] = commits.Len() + ctx.Data["BeforeCommitId"] = beforeCommitId + ctx.Data["AfterCommitId"] = afterCommitId + ctx.Data["Username"] = userName + ctx.Data["Reponame"] = repoName + ctx.Data["IsImageFile"] = isImageFile + ctx.Data["Title"] = "Comparing " + base.ShortSha(beforeCommitId) + "..." + base.ShortSha(afterCommitId) + " ยท " + userName + "/" + repoName + ctx.Data["Commit"] = commit + ctx.Data["Diff"] = diff + ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0 + ctx.Data["SourcePath"] = "/" + path.Join(userName, repoName, "src", afterCommitId) + ctx.Data["RawPath"] = "/" + path.Join(userName, repoName, "raw", afterCommitId) + ctx.HTML(200, DIFF) +} + func FileHistory(ctx *middleware.Context) { ctx.Data["IsRepoToolbarCommits"] = true diff --git a/templates/repo/commits.tmpl b/templates/repo/commits.tmpl index 420e973a50..e7518e9835 100644 --- a/templates/repo/commits.tmpl +++ b/templates/repo/commits.tmpl @@ -3,47 +3,6 @@ {{template "repo/nav" .}} {{template "repo/toolbar" .}} <div id="body" class="container"> - <div id="commits"> - <div class="panel panel-default commit-box info-box"> - <div class="panel-heading info-head"> - <form class="search pull-right col-md-3" action="{{.RepoLink}}/commits/{{.BranchName}}/search" method="get" id="commits-search-form"> - <div class="input-group"> - <input class="form-control search" type="search" placeholder="search commit" name="q" value="{{.Keyword}}" /> - <div class="input-group-btn"> - <button type="submit" class="btn btn-default">Find</button> - </div> - </div> - </form> - <h4>{{.CommitCount}} Commits</h4> - </div> - <table class="panel-footer table commit-list table table-striped"> - <thead> - <tr> - <th class="author">Author</th> - <th class="sha">SHA1</th> - <th class="message">Message</th> - <th class="date">Date</th> - </tr> - </thead> - <tbody> - {{ $username := .Username}} - {{ $reponame := .Reponame}} - {{$r := List .Commits}} - {{range $r}} - <tr> - <td class="author"><img class="avatar" src="{{AvatarLink .Author.Email}}" alt=""/><a href="/user/email2user?email={{.Author.Email}}">{{.Author.Name}}</a></td> - <td class="sha"><a rel="nofollow" class="label label-success" href="/{{$username}}/{{$reponame}}/commit/{{.Id}} ">{{SubStr .Id.String 0 10}} </a></td> - <td class="message">{{.Summary}} </td> - <td class="date">{{TimeSince .Author.When $.Lang}}</td> - </tr> - {{end}} - </tbody> - </table> - </div> - {{if not .IsSearchPage}}<ul class="pagination" id="commits-pager"> - {{if .LastPageNum}}<li><a href="{{.RepoLink}}/commits/{{.BranchName}}{{if .FileName}}/{{.FileName}}{{end}}?p={{.LastPageNum}}" rel="nofollow">« Newer</a></li>{{end}} - {{if .NextPageNum}}<li><a href="{{.RepoLink}}/commits/{{.BranchName}}{{if .FileName}}/{{.FileName}}{{end}}?p={{.NextPageNum}}" rel="nofollow">» Older</a></li>{{end}} - </ul>{{end}} - </div> + {{template "repo/commits_table" .}} </div> {{template "base/footer" .}} diff --git a/templates/repo/commits_table.tmpl b/templates/repo/commits_table.tmpl new file mode 100644 index 0000000000..4612398a53 --- /dev/null +++ b/templates/repo/commits_table.tmpl @@ -0,0 +1,42 @@ +<div id="commits"> + <div class="panel panel-default commit-box info-box"> + <div class="panel-heading info-head"> + <form class="search pull-right col-md-3" action="{{.RepoLink}}/commits/{{.BranchName}}/search" method="get" id="commits-search-form"> + <div class="input-group"> + <input class="form-control search" type="search" placeholder="search commit" name="q" value="{{.Keyword}}" /> + <div class="input-group-btn"> + <button type="submit" class="btn btn-default">Find</button> + </div> + </div> + </form> + <h4>{{.CommitCount}} Commits</h4> + </div> + <table class="panel-footer table commit-list table table-striped"> + <thead> + <tr> + <th class="author">Author</th> + <th class="sha">SHA1</th> + <th class="message">Message</th> + <th class="date">Date</th> + </tr> + </thead> + <tbody> + {{ $username := .Username}} + {{ $reponame := .Reponame}} + {{$r := List .Commits}} + {{range $r}} + <tr> + <td class="author"><img class="avatar" src="{{AvatarLink .Author.Email}}" alt=""/><a href="/user/email2user?email={{.Author.Email}}">{{.Author.Name}}</a></td> + <td class="sha"><a rel="nofollow" class="label label-success" href="/{{$username}}/{{$reponame}}/commit/{{.Id}} ">{{SubStr .Id.String 0 10}} </a></td> + <td class="message">{{.Summary}} </td> + <td class="date">{{TimeSince .Author.When $.Lang}}</td> + </tr> + {{end}} + </tbody> + </table> + </div> + {{if not .IsSearchPage}}<ul class="pagination" id="commits-pager"> + {{if .LastPageNum}}<li><a href="{{.RepoLink}}/commits/{{.BranchName}}{{if .FileName}}/{{.FileName}}{{end}}?p={{.LastPageNum}}" rel="nofollow">« Newer</a></li>{{end}} + {{if .NextPageNum}}<li><a href="{{.RepoLink}}/commits/{{.BranchName}}{{if .FileName}}/{{.FileName}}{{end}}?p={{.NextPageNum}}" rel="nofollow">» Older</a></li>{{end}} + </ul>{{end}} +</div> diff --git a/templates/repo/diff.tmpl b/templates/repo/diff.tmpl index 6adea04593..7873345083 100644 --- a/templates/repo/diff.tmpl +++ b/templates/repo/diff.tmpl @@ -3,9 +3,20 @@ {{template "repo/nav" .}} <div id="body" class="container" data-page="repo"> <div id="source"> + {{if .IsDiffCompare }} <div class="panel panel-info diff-box diff-head-box"> <div class="panel-heading"> <a class="pull-right btn btn-primary btn-sm" rel="nofollow" href="{{.SourcePath}}">Browse Source</a> + <h4><a href="{{$.RepoLink}}/commit/{{.BeforeCommitId}}" class="label label-success">{{ShortSha .BeforeCommitId}}</a> ... <a href="{{$.RepoLink}}/commit/{{.AfterCommitId}}" class="label label-success">{{ShortSha .AfterCommitId}}</a></h4> + </div> + <div class="panel-body compare"> + {{template "repo/commits_table" .}} + </div> + </div> + {{else}} + <div class="panel panel-info diff-box diff-head-box"> + <div class="panel-heading"> + <a class="pull-right btn btn-primary btn-sm" rel="nofollow" href="{{.SourcePath}}">Browse Source</a> <h4>{{.Commit.Message}}</h4> </div> <div class="panel-body"> @@ -22,9 +33,9 @@ <a class="name" href="/user/email2user?email={{.Commit.Author.Email}}"><strong>{{.Commit.Author.Name}}</strong></a> <span class="time">{{TimeSince .Commit.Author.When $.Lang}}</span> </p> - </div> + </div> </div> - + {{end}} {{if .DiffNotAvailable}} <h4>Diff Data Not Available.</h4> {{else}} |