mirror of https://github.com/gogits/gogs.git
Unknwon
10 years ago
20 changed files with 781 additions and 300 deletions
File diff suppressed because one or more lines are too long
@ -0,0 +1,86 @@ |
|||||||
|
// Copyright 2015 The Gogs Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package git |
||||||
|
|
||||||
|
import ( |
||||||
|
"container/list" |
||||||
|
"fmt" |
||||||
|
"strings" |
||||||
|
"time" |
||||||
|
|
||||||
|
"github.com/Unknwon/com" |
||||||
|
) |
||||||
|
|
||||||
|
type PullRequestInfo struct { |
||||||
|
MergeBase string |
||||||
|
Commits *list.List |
||||||
|
// Diff *Diff
|
||||||
|
NumFiles int |
||||||
|
} |
||||||
|
|
||||||
|
// GetPullRequestInfo generates and returns pull request information
|
||||||
|
// between base and head branches of repositories.
|
||||||
|
func (repo *Repository) GetPullRequestInfo(basePath, baseBranch, headBranch string) (*PullRequestInfo, error) { |
||||||
|
// Add a temporary remote.
|
||||||
|
tmpRemote := com.ToStr(time.Now().UnixNano()) |
||||||
|
_, stderr, err := com.ExecCmdDir(repo.Path, "git", "remote", "add", "-f", tmpRemote, basePath) |
||||||
|
if err != nil { |
||||||
|
return nil, fmt.Errorf("add base as remote: %v", concatenateError(err, stderr)) |
||||||
|
} |
||||||
|
defer func() { |
||||||
|
com.ExecCmdDir(repo.Path, "git", "remote", "remove", tmpRemote) |
||||||
|
}() |
||||||
|
|
||||||
|
prInfo := new(PullRequestInfo) |
||||||
|
|
||||||
|
var stdout string |
||||||
|
remoteBranch := "remotes/" + tmpRemote + "/" + baseBranch |
||||||
|
// Get merge base commit.
|
||||||
|
stdout, stderr, err = com.ExecCmdDir(repo.Path, "git", "merge-base", remoteBranch, headBranch) |
||||||
|
if err != nil { |
||||||
|
return nil, fmt.Errorf("get merge base: %v", concatenateError(err, stderr)) |
||||||
|
} |
||||||
|
prInfo.MergeBase = strings.TrimSpace(stdout) |
||||||
|
|
||||||
|
stdout, stderr, err = com.ExecCmdDir(repo.Path, "git", "log", remoteBranch+"..."+headBranch, prettyLogFormat) |
||||||
|
if err != nil { |
||||||
|
return nil, fmt.Errorf("list diff logs: %v", concatenateError(err, stderr)) |
||||||
|
} |
||||||
|
prInfo.Commits, err = parsePrettyFormatLog(repo, []byte(stdout)) |
||||||
|
if err != nil { |
||||||
|
return nil, fmt.Errorf("parsePrettyFormatLog: %v", err) |
||||||
|
} |
||||||
|
|
||||||
|
// Count number of changed files.
|
||||||
|
stdout, stderr, err = com.ExecCmdDir(repo.Path, "git", "diff", "--name-only", remoteBranch+"..."+headBranch) |
||||||
|
if err != nil { |
||||||
|
return nil, fmt.Errorf("list changed files: %v", concatenateError(err, stderr)) |
||||||
|
} |
||||||
|
prInfo.NumFiles = len(strings.Split(stdout, "\n")) - 1 |
||||||
|
|
||||||
|
return prInfo, nil |
||||||
|
} |
||||||
|
|
||||||
|
// GetPatch generates and returns patch data between given branches.
|
||||||
|
func (repo *Repository) GetPatch(basePath, baseBranch, headBranch string) ([]byte, error) { |
||||||
|
// Add a temporary remote.
|
||||||
|
tmpRemote := com.ToStr(time.Now().UnixNano()) |
||||||
|
_, stderr, err := com.ExecCmdDirBytes(repo.Path, "git", "remote", "add", "-f", tmpRemote, basePath) |
||||||
|
if err != nil { |
||||||
|
return nil, fmt.Errorf("add base as remote: %v", concatenateError(err, string(stderr))) |
||||||
|
} |
||||||
|
defer func() { |
||||||
|
com.ExecCmdDir(repo.Path, "git", "remote", "remove", tmpRemote) |
||||||
|
}() |
||||||
|
|
||||||
|
var stdout []byte |
||||||
|
remoteBranch := "remotes/" + tmpRemote + "/" + baseBranch |
||||||
|
stdout, stderr, err = com.ExecCmdDirBytes(repo.Path, "git", "diff", "-p", remoteBranch, headBranch) |
||||||
|
if err != nil { |
||||||
|
return nil, concatenateError(err, string(stderr)) |
||||||
|
} |
||||||
|
|
||||||
|
return stdout, nil |
||||||
|
} |
File diff suppressed because one or more lines are too long
@ -0,0 +1,92 @@ |
|||||||
|
{{if .DiffNotAvailable}} |
||||||
|
<h4>{{.i18n.Tr "repo.diff.data_not_available"}}</h4> |
||||||
|
{{else}} |
||||||
|
<div class="diff-detail-box diff-box"> |
||||||
|
<div> |
||||||
|
<i class="fa fa-retweet"></i> |
||||||
|
{{.i18n.Tr "repo.diff.stats_desc" .Diff.NumFiles .Diff.TotalAddition .Diff.TotalDeletion | Str2html}} |
||||||
|
<div class="ui right"> |
||||||
|
<a class="ui tiny basic black toggle button" data-target="#diff-files">{{.i18n.Tr "repo.diff.show_diff_stats"}}</a> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<ol class="detail-files hide" id="diff-files"> |
||||||
|
{{range .Diff.Files}} |
||||||
|
<li> |
||||||
|
<div class="diff-counter count pull-right"> |
||||||
|
{{if not .IsBin}} |
||||||
|
<span class="add" data-line="{{.Addition}}">{{.Addition}}</span> |
||||||
|
<span class="bar"> |
||||||
|
<span class="pull-left add"></span> |
||||||
|
<span class="pull-left del"></span> |
||||||
|
</span> |
||||||
|
<span class="del" data-line="{{.Deletion}}">{{.Deletion}}</span> |
||||||
|
{{else}} |
||||||
|
<span>{{$.i18n.Tr "repo.diff.bin"}}</span> |
||||||
|
{{end}} |
||||||
|
</div> |
||||||
|
<!-- todo finish all file status, now modify, add, delete and rename --> |
||||||
|
<span class="status {{DiffTypeToStr .Type}} poping up" data-content="{{DiffTypeToStr .Type}}" data-variation="inverted tiny" data-position="right center"> </span> |
||||||
|
<a class="file" href="#diff-{{.Index}}">{{.Name}}</a> |
||||||
|
</li> |
||||||
|
{{end}} |
||||||
|
</ol> |
||||||
|
</div> |
||||||
|
|
||||||
|
{{range $i, $file := .Diff.Files}} |
||||||
|
<div class="diff-file-box diff-box file-content" id="diff-{{.Index}}"> |
||||||
|
<h4 class="ui top attached normal header"> |
||||||
|
<div class="diff-counter count ui left"> |
||||||
|
{{if not $file.IsBin}} |
||||||
|
<span class="add" data-line="{{.Addition}}">+ {{.Addition}}</span> |
||||||
|
<span class="bar"> |
||||||
|
<span class="pull-left add"></span> |
||||||
|
<span class="pull-left del"></span> |
||||||
|
</span> |
||||||
|
<span class="del" data-line="{{.Deletion}}">- {{.Deletion}}</span> |
||||||
|
{{else}} |
||||||
|
{{$.i18n.Tr "repo.diff.bin"}} |
||||||
|
{{end}} |
||||||
|
</div> |
||||||
|
<span class="file">{{$file.Name}}</span> |
||||||
|
<div class="ui right"> |
||||||
|
{{if $file.IsDeleted}} |
||||||
|
<a class="ui basic tiny button" rel="nofollow" href="{{EscapePound $.BeforeSourcePath}}/{{EscapePound .Name}}">{{$.i18n.Tr "repo.diff.view_file"}}</a> |
||||||
|
{{else}} |
||||||
|
<a class="ui basic tiny button" rel="nofollow" href="{{EscapePound $.SourcePath}}/{{EscapePound .Name}}">{{$.i18n.Tr "repo.diff.view_file"}}</a> |
||||||
|
{{end}} |
||||||
|
</div> |
||||||
|
</h4> |
||||||
|
<div class="ui attached table segment"> |
||||||
|
{{$isImage := (call $.IsImageFile $file.Name)}} |
||||||
|
{{if $isImage}} |
||||||
|
<div class="center"> |
||||||
|
<img src="{{$.RawPath}}/{{EscapePound .Name}}"> |
||||||
|
</div> |
||||||
|
{{else}} |
||||||
|
<div class="file-body file-code code-view code-diff"> |
||||||
|
<table> |
||||||
|
<tbody> |
||||||
|
{{range .Sections}} |
||||||
|
{{range $k, $line := .Lines}} |
||||||
|
<tr class="{{DiffLineTypeToStr .Type}}-code nl-{{$k}} ol-{{$k}}"> |
||||||
|
<td class="lines-num lines-num-old"> |
||||||
|
<span rel="{{if $line.LeftIdx}}diff-{{Sha1 $file.Name}}L{{$line.LeftIdx}}{{end}}">{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}</span> |
||||||
|
</td> |
||||||
|
<td class="lines-num lines-num-new"> |
||||||
|
<span rel="{{if $line.RightIdx}}diff-{{Sha1 $file.Name}}R{{$line.RightIdx}}{{end}}">{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}</span> |
||||||
|
</td> |
||||||
|
<td class="lines-code"> |
||||||
|
<pre>{{$line.Content}}</pre> |
||||||
|
</td> |
||||||
|
</tr> |
||||||
|
{{end}} |
||||||
|
{{end}} |
||||||
|
</tbody> |
||||||
|
</table> |
||||||
|
</div> |
||||||
|
{{end}} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<br> |
||||||
|
{{end}} |
||||||
|
{{end}} |
@ -0,0 +1,35 @@ |
|||||||
|
<div class="sixteen wide column title"> |
||||||
|
<div class="ui grid"> |
||||||
|
<h1 class="twelve wide column"> |
||||||
|
<span class="index">#{{.Issue.Index}}</span> <span id="issue-title">{{.Issue.Name}}</span> |
||||||
|
<div id="edit-title-input" class="ui input" style="display: none"> |
||||||
|
<input value="{{.Issue.Name}}"> |
||||||
|
</div> |
||||||
|
</h1> |
||||||
|
{{if .IsIssueOwner}} |
||||||
|
<div class="four wide column"> |
||||||
|
<div class="edit-zone text right"> |
||||||
|
<div id="edit-title" class="ui basic green not-in-edit button">{{.i18n.Tr "repo.issues.edit"}}</div> |
||||||
|
<div id="cancel-edit-title" class="ui basic blue in-edit button" style="display: none">{{.i18n.Tr "repo.issues.cancel"}}</div> |
||||||
|
<div id="save-edit-title" class="ui green in-edit button" style="display: none" data-update-url="{{$.RepoLink}}/issues/{{.Issue.Index}}/title">{{.i18n.Tr "repo.issues.save"}}</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
{{end}} |
||||||
|
</div> |
||||||
|
{{if .Issue.IsClosed}} |
||||||
|
<div class="ui red large label"><i class="octicon octicon-issue-closed"></i> {{.i18n.Tr "repo.issues.closed_title"}}</div> |
||||||
|
{{else}} |
||||||
|
<div class="ui green large label"><i class="octicon octicon-issue-opened"></i> {{.i18n.Tr "repo.issues.open_title"}}</div> |
||||||
|
{{end}} |
||||||
|
{{ $createdStr:= TimeSince .Issue.Created $.Lang }} |
||||||
|
<span class="time-desc"> |
||||||
|
{{if gt .Issue.Poster.Id 0}} |
||||||
|
{{$.i18n.Tr "repo.issues.opened_by" $createdStr .Issue.Poster.HomeLink .Issue.Poster.Name | Safe}} |
||||||
|
{{else}} |
||||||
|
{{$.i18n.Tr "repo.issues.opened_by_fake" $createdStr .Issue.Poster.Name | Safe}} |
||||||
|
{{end}} |
||||||
|
· |
||||||
|
{{$.i18n.Tr "repo.issues.num_comments" .Issue.NumComments}} |
||||||
|
</span> |
||||||
|
<div class="ui divider"></div> |
||||||
|
</div> |
Loading…
Reference in new issue