Support direct comparison (git diff a..b) as well merge comparison (a...b) (#16635)
This PR changes the compare page to make the "..." in the between branches a clickable link. This changes the comparison type from "..." to "..". Similarly it makes the initial compare icon clickable to switch the head and base branches. Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: Lauris BH <lauris@nix.lv> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
parent
123f0aea00
commit
920608e592
10 changed files with 198 additions and 148 deletions
|
@ -46,7 +46,7 @@ func (repo *Repository) GetMergeBase(tmpRemote string, base, head string) (strin
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCompareInfo generates and returns compare information between base and head branches of repositories.
|
// GetCompareInfo generates and returns compare information between base and head branches of repositories.
|
||||||
func (repo *Repository) GetCompareInfo(basePath, baseBranch, headBranch string) (_ *CompareInfo, err error) {
|
func (repo *Repository) GetCompareInfo(basePath, baseBranch, headBranch string, directComparison bool) (_ *CompareInfo, err error) {
|
||||||
var (
|
var (
|
||||||
remoteBranch string
|
remoteBranch string
|
||||||
tmpRemote string
|
tmpRemote string
|
||||||
|
@ -79,8 +79,15 @@ func (repo *Repository) GetCompareInfo(basePath, baseBranch, headBranch string)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
compareInfo.BaseCommitID = remoteBranch
|
compareInfo.BaseCommitID = remoteBranch
|
||||||
}
|
}
|
||||||
|
separator := "..."
|
||||||
|
baseCommitID := compareInfo.MergeBase
|
||||||
|
if directComparison {
|
||||||
|
separator = ".."
|
||||||
|
baseCommitID = compareInfo.BaseCommitID
|
||||||
|
}
|
||||||
|
|
||||||
// We have a common base - therefore we know that ... should work
|
// We have a common base - therefore we know that ... should work
|
||||||
logs, err := NewCommand("log", compareInfo.MergeBase+"..."+headBranch, prettyLogFormat).RunInDirBytes(repo.Path)
|
logs, err := NewCommand("log", baseCommitID+separator+headBranch, prettyLogFormat).RunInDirBytes(repo.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -100,7 +107,7 @@ func (repo *Repository) GetCompareInfo(basePath, baseBranch, headBranch string)
|
||||||
// Count number of changed files.
|
// Count number of changed files.
|
||||||
// This probably should be removed as we need to use shortstat elsewhere
|
// This probably should be removed as we need to use shortstat elsewhere
|
||||||
// Now there is git diff --shortstat but this appears to be slower than simply iterating with --nameonly
|
// Now there is git diff --shortstat but this appears to be slower than simply iterating with --nameonly
|
||||||
compareInfo.NumFiles, err = repo.GetDiffNumChangedFiles(remoteBranch, headBranch)
|
compareInfo.NumFiles, err = repo.GetDiffNumChangedFiles(remoteBranch, headBranch, directComparison)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -120,12 +127,17 @@ func (l *lineCountWriter) Write(p []byte) (n int, err error) {
|
||||||
|
|
||||||
// GetDiffNumChangedFiles counts the number of changed files
|
// GetDiffNumChangedFiles counts the number of changed files
|
||||||
// This is substantially quicker than shortstat but...
|
// This is substantially quicker than shortstat but...
|
||||||
func (repo *Repository) GetDiffNumChangedFiles(base, head string) (int, error) {
|
func (repo *Repository) GetDiffNumChangedFiles(base, head string, directComparison bool) (int, error) {
|
||||||
// Now there is git diff --shortstat but this appears to be slower than simply iterating with --nameonly
|
// Now there is git diff --shortstat but this appears to be slower than simply iterating with --nameonly
|
||||||
w := &lineCountWriter{}
|
w := &lineCountWriter{}
|
||||||
stderr := new(bytes.Buffer)
|
stderr := new(bytes.Buffer)
|
||||||
|
|
||||||
if err := NewCommand("diff", "-z", "--name-only", base+"..."+head).
|
separator := "..."
|
||||||
|
if directComparison {
|
||||||
|
separator = ".."
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := NewCommand("diff", "-z", "--name-only", base+separator+head).
|
||||||
RunInDirPipeline(repo.Path, w, stderr); err != nil {
|
RunInDirPipeline(repo.Path, w, stderr); err != nil {
|
||||||
if strings.Contains(stderr.String(), "no merge base") {
|
if strings.Contains(stderr.String(), "no merge base") {
|
||||||
// git >= 2.28 now returns an error if base and head have become unrelated.
|
// git >= 2.28 now returns an error if base and head have become unrelated.
|
||||||
|
|
|
@ -1386,6 +1386,8 @@ pulls.compare_changes = New Pull Request
|
||||||
pulls.compare_changes_desc = Select the branch to merge into and the branch to pull from.
|
pulls.compare_changes_desc = Select the branch to merge into and the branch to pull from.
|
||||||
pulls.compare_base = merge into
|
pulls.compare_base = merge into
|
||||||
pulls.compare_compare = pull from
|
pulls.compare_compare = pull from
|
||||||
|
pulls.switch_comparison_type = Switch comparison type
|
||||||
|
pulls.switch_head_and_base = Switch head and base
|
||||||
pulls.filter_branch = Filter branch
|
pulls.filter_branch = Filter branch
|
||||||
pulls.no_results = No results found.
|
pulls.no_results = No results found.
|
||||||
pulls.nothing_to_compare = These branches are equal. There is no need to create a pull request.
|
pulls.nothing_to_compare = These branches are equal. There is no need to create a pull request.
|
||||||
|
|
|
@ -1006,7 +1006,7 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil, nil, nil, nil, "", ""
|
||||||
}
|
}
|
||||||
|
|
||||||
compareInfo, err := headGitRepo.GetCompareInfo(models.RepoPath(baseRepo.Owner.Name, baseRepo.Name), baseBranch, headBranch)
|
compareInfo, err := headGitRepo.GetCompareInfo(models.RepoPath(baseRepo.Owner.Name, baseRepo.Name), baseBranch, headBranch, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
headGitRepo.Close()
|
headGitRepo.Close()
|
||||||
ctx.Error(http.StatusInternalServerError, "GetCompareInfo", err)
|
ctx.Error(http.StatusInternalServerError, "GetCompareInfo", err)
|
||||||
|
@ -1183,9 +1183,9 @@ func GetPullRequestCommits(ctx *context.APIContext) {
|
||||||
}
|
}
|
||||||
defer baseGitRepo.Close()
|
defer baseGitRepo.Close()
|
||||||
if pr.HasMerged {
|
if pr.HasMerged {
|
||||||
prInfo, err = baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(), pr.MergeBase, pr.GetGitRefName())
|
prInfo, err = baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(), pr.MergeBase, pr.GetGitRefName(), true)
|
||||||
} else {
|
} else {
|
||||||
prInfo, err = baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(), pr.BaseBranch, pr.GetGitRefName())
|
prInfo, err = baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(), pr.BaseBranch, pr.GetGitRefName(), true)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("GetCompareInfo", err)
|
ctx.ServerError("GetCompareInfo", err)
|
||||||
|
|
|
@ -299,7 +299,8 @@ func Diff(ctx *context.Context) {
|
||||||
diff, err := gitdiff.GetDiffCommitWithWhitespaceBehavior(gitRepo,
|
diff, err := gitdiff.GetDiffCommitWithWhitespaceBehavior(gitRepo,
|
||||||
commitID, setting.Git.MaxGitDiffLines,
|
commitID, setting.Git.MaxGitDiffLines,
|
||||||
setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles,
|
setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles,
|
||||||
gitdiff.GetWhitespaceFlag(ctx.Data["WhitespaceBehavior"].(string)))
|
gitdiff.GetWhitespaceFlag(ctx.Data["WhitespaceBehavior"].(string)),
|
||||||
|
false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.NotFound("GetDiffCommitWithWhitespaceBehavior", err)
|
ctx.NotFound("GetDiffCommitWithWhitespaceBehavior", err)
|
||||||
return
|
return
|
||||||
|
|
|
@ -145,9 +145,21 @@ func setCsvCompareContext(ctx *context.Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CompareInfo represents the collected results from ParseCompareInfo
|
||||||
|
type CompareInfo struct {
|
||||||
|
HeadUser *models.User
|
||||||
|
HeadRepo *models.Repository
|
||||||
|
HeadGitRepo *git.Repository
|
||||||
|
CompareInfo *git.CompareInfo
|
||||||
|
BaseBranch string
|
||||||
|
HeadBranch string
|
||||||
|
DirectComparison bool
|
||||||
|
}
|
||||||
|
|
||||||
// ParseCompareInfo parse compare info between two commit for preparing comparing references
|
// ParseCompareInfo parse compare info between two commit for preparing comparing references
|
||||||
func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *git.Repository, *git.CompareInfo, string, string) {
|
func ParseCompareInfo(ctx *context.Context) *CompareInfo {
|
||||||
baseRepo := ctx.Repo.Repository
|
baseRepo := ctx.Repo.Repository
|
||||||
|
ci := &CompareInfo{}
|
||||||
|
|
||||||
// Get compared branches information
|
// Get compared branches information
|
||||||
// A full compare url is of the form:
|
// A full compare url is of the form:
|
||||||
|
@ -173,92 +185,97 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
|
||||||
// same repo: master...feature
|
// same repo: master...feature
|
||||||
|
|
||||||
var (
|
var (
|
||||||
headUser *models.User
|
|
||||||
headRepo *models.Repository
|
|
||||||
headBranch string
|
|
||||||
isSameRepo bool
|
isSameRepo bool
|
||||||
infoPath string
|
infoPath string
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
infoPath = ctx.Params("*")
|
infoPath = ctx.Params("*")
|
||||||
infos := strings.SplitN(infoPath, "...", 2)
|
infos := strings.SplitN(infoPath, "...", 2)
|
||||||
|
|
||||||
|
if len(infos) != 2 {
|
||||||
|
infos = strings.SplitN(infoPath, "..", 2)
|
||||||
|
ci.DirectComparison = true
|
||||||
|
ctx.Data["PageIsComparePull"] = false
|
||||||
|
}
|
||||||
|
|
||||||
if len(infos) != 2 {
|
if len(infos) != 2 {
|
||||||
log.Trace("ParseCompareInfo[%d]: not enough compared branches information %s", baseRepo.ID, infos)
|
log.Trace("ParseCompareInfo[%d]: not enough compared branches information %s", baseRepo.ID, infos)
|
||||||
ctx.NotFound("CompareAndPullRequest", nil)
|
ctx.NotFound("CompareAndPullRequest", nil)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Data["BaseName"] = baseRepo.OwnerName
|
ctx.Data["BaseName"] = baseRepo.OwnerName
|
||||||
baseBranch := infos[0]
|
ci.BaseBranch = infos[0]
|
||||||
ctx.Data["BaseBranch"] = baseBranch
|
ctx.Data["BaseBranch"] = ci.BaseBranch
|
||||||
|
|
||||||
// If there is no head repository, it means compare between same repository.
|
// If there is no head repository, it means compare between same repository.
|
||||||
headInfos := strings.Split(infos[1], ":")
|
headInfos := strings.Split(infos[1], ":")
|
||||||
if len(headInfos) == 1 {
|
if len(headInfos) == 1 {
|
||||||
isSameRepo = true
|
isSameRepo = true
|
||||||
headUser = ctx.Repo.Owner
|
ci.HeadUser = ctx.Repo.Owner
|
||||||
headBranch = headInfos[0]
|
ci.HeadBranch = headInfos[0]
|
||||||
|
|
||||||
} else if len(headInfos) == 2 {
|
} else if len(headInfos) == 2 {
|
||||||
headInfosSplit := strings.Split(headInfos[0], "/")
|
headInfosSplit := strings.Split(headInfos[0], "/")
|
||||||
if len(headInfosSplit) == 1 {
|
if len(headInfosSplit) == 1 {
|
||||||
headUser, err = models.GetUserByName(headInfos[0])
|
ci.HeadUser, err = models.GetUserByName(headInfos[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if models.IsErrUserNotExist(err) {
|
if models.IsErrUserNotExist(err) {
|
||||||
ctx.NotFound("GetUserByName", nil)
|
ctx.NotFound("GetUserByName", nil)
|
||||||
} else {
|
} else {
|
||||||
ctx.ServerError("GetUserByName", err)
|
ctx.ServerError("GetUserByName", err)
|
||||||
}
|
}
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil
|
||||||
}
|
}
|
||||||
headBranch = headInfos[1]
|
ci.HeadBranch = headInfos[1]
|
||||||
isSameRepo = headUser.ID == ctx.Repo.Owner.ID
|
isSameRepo = ci.HeadUser.ID == ctx.Repo.Owner.ID
|
||||||
if isSameRepo {
|
if isSameRepo {
|
||||||
headRepo = baseRepo
|
ci.HeadRepo = baseRepo
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
headRepo, err = models.GetRepositoryByOwnerAndName(headInfosSplit[0], headInfosSplit[1])
|
ci.HeadRepo, err = models.GetRepositoryByOwnerAndName(headInfosSplit[0], headInfosSplit[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if models.IsErrRepoNotExist(err) {
|
if models.IsErrRepoNotExist(err) {
|
||||||
ctx.NotFound("GetRepositoryByOwnerAndName", nil)
|
ctx.NotFound("GetRepositoryByOwnerAndName", nil)
|
||||||
} else {
|
} else {
|
||||||
ctx.ServerError("GetRepositoryByOwnerAndName", err)
|
ctx.ServerError("GetRepositoryByOwnerAndName", err)
|
||||||
}
|
}
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil
|
||||||
}
|
}
|
||||||
if err := headRepo.GetOwner(); err != nil {
|
if err := ci.HeadRepo.GetOwner(); err != nil {
|
||||||
if models.IsErrUserNotExist(err) {
|
if models.IsErrUserNotExist(err) {
|
||||||
ctx.NotFound("GetUserByName", nil)
|
ctx.NotFound("GetUserByName", nil)
|
||||||
} else {
|
} else {
|
||||||
ctx.ServerError("GetUserByName", err)
|
ctx.ServerError("GetUserByName", err)
|
||||||
}
|
}
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil
|
||||||
}
|
}
|
||||||
headBranch = headInfos[1]
|
ci.HeadBranch = headInfos[1]
|
||||||
headUser = headRepo.Owner
|
ci.HeadUser = ci.HeadRepo.Owner
|
||||||
isSameRepo = headRepo.ID == ctx.Repo.Repository.ID
|
isSameRepo = ci.HeadRepo.ID == ctx.Repo.Repository.ID
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ctx.NotFound("CompareAndPullRequest", nil)
|
ctx.NotFound("CompareAndPullRequest", nil)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil
|
||||||
}
|
}
|
||||||
ctx.Data["HeadUser"] = headUser
|
ctx.Data["HeadUser"] = ci.HeadUser
|
||||||
ctx.Data["HeadBranch"] = headBranch
|
ctx.Data["HeadBranch"] = ci.HeadBranch
|
||||||
ctx.Repo.PullRequest.SameRepo = isSameRepo
|
ctx.Repo.PullRequest.SameRepo = isSameRepo
|
||||||
|
|
||||||
// Check if base branch is valid.
|
// Check if base branch is valid.
|
||||||
baseIsCommit := ctx.Repo.GitRepo.IsCommitExist(baseBranch)
|
baseIsCommit := ctx.Repo.GitRepo.IsCommitExist(ci.BaseBranch)
|
||||||
baseIsBranch := ctx.Repo.GitRepo.IsBranchExist(baseBranch)
|
baseIsBranch := ctx.Repo.GitRepo.IsBranchExist(ci.BaseBranch)
|
||||||
baseIsTag := ctx.Repo.GitRepo.IsTagExist(baseBranch)
|
baseIsTag := ctx.Repo.GitRepo.IsTagExist(ci.BaseBranch)
|
||||||
if !baseIsCommit && !baseIsBranch && !baseIsTag {
|
if !baseIsCommit && !baseIsBranch && !baseIsTag {
|
||||||
// Check if baseBranch is short sha commit hash
|
// Check if baseBranch is short sha commit hash
|
||||||
if baseCommit, _ := ctx.Repo.GitRepo.GetCommit(baseBranch); baseCommit != nil {
|
if baseCommit, _ := ctx.Repo.GitRepo.GetCommit(ci.BaseBranch); baseCommit != nil {
|
||||||
baseBranch = baseCommit.ID.String()
|
ci.BaseBranch = baseCommit.ID.String()
|
||||||
ctx.Data["BaseBranch"] = baseBranch
|
ctx.Data["BaseBranch"] = ci.BaseBranch
|
||||||
baseIsCommit = true
|
baseIsCommit = true
|
||||||
} else {
|
} else {
|
||||||
ctx.NotFound("IsRefExist", nil)
|
ctx.NotFound("IsRefExist", nil)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx.Data["BaseIsCommit"] = baseIsCommit
|
ctx.Data["BaseIsCommit"] = baseIsCommit
|
||||||
|
@ -284,7 +301,7 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !models.IsErrRepoNotExist(err) {
|
if !models.IsErrRepoNotExist(err) {
|
||||||
ctx.ServerError("Unable to find root repo", err)
|
ctx.ServerError("Unable to find root repo", err)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rootRepo = baseRepo.BaseRepo
|
rootRepo = baseRepo.BaseRepo
|
||||||
|
@ -303,29 +320,29 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
has := headRepo != nil
|
has := ci.HeadRepo != nil
|
||||||
// 3. If the base is a forked from "RootRepo" and the owner of
|
// 3. If the base is a forked from "RootRepo" and the owner of
|
||||||
// the "RootRepo" is the :headUser - set headRepo to that
|
// the "RootRepo" is the :headUser - set headRepo to that
|
||||||
if !has && rootRepo != nil && rootRepo.OwnerID == headUser.ID {
|
if !has && rootRepo != nil && rootRepo.OwnerID == ci.HeadUser.ID {
|
||||||
headRepo = rootRepo
|
ci.HeadRepo = rootRepo
|
||||||
has = true
|
has = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. If the ctx.User has their own fork of the baseRepo and the headUser is the ctx.User
|
// 4. If the ctx.User has their own fork of the baseRepo and the headUser is the ctx.User
|
||||||
// set the headRepo to the ownFork
|
// set the headRepo to the ownFork
|
||||||
if !has && ownForkRepo != nil && ownForkRepo.OwnerID == headUser.ID {
|
if !has && ownForkRepo != nil && ownForkRepo.OwnerID == ci.HeadUser.ID {
|
||||||
headRepo = ownForkRepo
|
ci.HeadRepo = ownForkRepo
|
||||||
has = true
|
has = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. If the headOwner has a fork of the baseRepo - use that
|
// 5. If the headOwner has a fork of the baseRepo - use that
|
||||||
if !has {
|
if !has {
|
||||||
headRepo, has = models.HasForkedRepo(headUser.ID, baseRepo.ID)
|
ci.HeadRepo, has = models.HasForkedRepo(ci.HeadUser.ID, baseRepo.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. If the baseRepo is a fork and the headUser has a fork of that use that
|
// 6. If the baseRepo is a fork and the headUser has a fork of that use that
|
||||||
if !has && baseRepo.IsFork {
|
if !has && baseRepo.IsFork {
|
||||||
headRepo, has = models.HasForkedRepo(headUser.ID, baseRepo.ForkID)
|
ci.HeadRepo, has = models.HasForkedRepo(ci.HeadUser.ID, baseRepo.ForkID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7. Otherwise if we're not the same repo and haven't found a repo give up
|
// 7. Otherwise if we're not the same repo and haven't found a repo give up
|
||||||
|
@ -334,20 +351,19 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
|
||||||
}
|
}
|
||||||
|
|
||||||
// 8. Finally open the git repo
|
// 8. Finally open the git repo
|
||||||
var headGitRepo *git.Repository
|
|
||||||
if isSameRepo {
|
if isSameRepo {
|
||||||
headRepo = ctx.Repo.Repository
|
ci.HeadRepo = ctx.Repo.Repository
|
||||||
headGitRepo = ctx.Repo.GitRepo
|
ci.HeadGitRepo = ctx.Repo.GitRepo
|
||||||
} else if has {
|
} else if has {
|
||||||
headGitRepo, err = git.OpenRepository(headRepo.RepoPath())
|
ci.HeadGitRepo, err = git.OpenRepository(ci.HeadRepo.RepoPath())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("OpenRepository", err)
|
ctx.ServerError("OpenRepository", err)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil
|
||||||
}
|
}
|
||||||
defer headGitRepo.Close()
|
defer ci.HeadGitRepo.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Data["HeadRepo"] = headRepo
|
ctx.Data["HeadRepo"] = ci.HeadRepo
|
||||||
|
|
||||||
// Now we need to assert that the ctx.User has permission to read
|
// Now we need to assert that the ctx.User has permission to read
|
||||||
// the baseRepo's code and pulls
|
// the baseRepo's code and pulls
|
||||||
|
@ -355,7 +371,7 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
|
||||||
permBase, err := models.GetUserRepoPermission(baseRepo, ctx.User)
|
permBase, err := models.GetUserRepoPermission(baseRepo, ctx.User)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("GetUserRepoPermission", err)
|
ctx.ServerError("GetUserRepoPermission", err)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil
|
||||||
}
|
}
|
||||||
if !permBase.CanRead(models.UnitTypeCode) {
|
if !permBase.CanRead(models.UnitTypeCode) {
|
||||||
if log.IsTrace() {
|
if log.IsTrace() {
|
||||||
|
@ -365,26 +381,26 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
|
||||||
permBase)
|
permBase)
|
||||||
}
|
}
|
||||||
ctx.NotFound("ParseCompareInfo", nil)
|
ctx.NotFound("ParseCompareInfo", nil)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're not merging from the same repo:
|
// If we're not merging from the same repo:
|
||||||
if !isSameRepo {
|
if !isSameRepo {
|
||||||
// Assert ctx.User has permission to read headRepo's codes
|
// Assert ctx.User has permission to read headRepo's codes
|
||||||
permHead, err := models.GetUserRepoPermission(headRepo, ctx.User)
|
permHead, err := models.GetUserRepoPermission(ci.HeadRepo, ctx.User)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("GetUserRepoPermission", err)
|
ctx.ServerError("GetUserRepoPermission", err)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil
|
||||||
}
|
}
|
||||||
if !permHead.CanRead(models.UnitTypeCode) {
|
if !permHead.CanRead(models.UnitTypeCode) {
|
||||||
if log.IsTrace() {
|
if log.IsTrace() {
|
||||||
log.Trace("Permission Denied: User: %-v cannot read code in Repo: %-v\nUser in headRepo has Permissions: %-+v",
|
log.Trace("Permission Denied: User: %-v cannot read code in Repo: %-v\nUser in headRepo has Permissions: %-+v",
|
||||||
ctx.User,
|
ctx.User,
|
||||||
headRepo,
|
ci.HeadRepo,
|
||||||
permHead)
|
permHead)
|
||||||
}
|
}
|
||||||
ctx.NotFound("ParseCompareInfo", nil)
|
ctx.NotFound("ParseCompareInfo", nil)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,12 +409,12 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
|
||||||
// 2. the computed head
|
// 2. the computed head
|
||||||
// then get the branches of it
|
// then get the branches of it
|
||||||
if rootRepo != nil &&
|
if rootRepo != nil &&
|
||||||
rootRepo.ID != headRepo.ID &&
|
rootRepo.ID != ci.HeadRepo.ID &&
|
||||||
rootRepo.ID != baseRepo.ID {
|
rootRepo.ID != baseRepo.ID {
|
||||||
perm, branches, tags, err := getBranchesAndTagsForRepo(ctx.User, rootRepo)
|
perm, branches, tags, err := getBranchesAndTagsForRepo(ctx.User, rootRepo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("GetBranchesForRepo", err)
|
ctx.ServerError("GetBranchesForRepo", err)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil
|
||||||
}
|
}
|
||||||
if perm {
|
if perm {
|
||||||
ctx.Data["RootRepo"] = rootRepo
|
ctx.Data["RootRepo"] = rootRepo
|
||||||
|
@ -413,13 +429,13 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
|
||||||
// 3. The rootRepo (if we have one)
|
// 3. The rootRepo (if we have one)
|
||||||
// then get the branches from it.
|
// then get the branches from it.
|
||||||
if ownForkRepo != nil &&
|
if ownForkRepo != nil &&
|
||||||
ownForkRepo.ID != headRepo.ID &&
|
ownForkRepo.ID != ci.HeadRepo.ID &&
|
||||||
ownForkRepo.ID != baseRepo.ID &&
|
ownForkRepo.ID != baseRepo.ID &&
|
||||||
(rootRepo == nil || ownForkRepo.ID != rootRepo.ID) {
|
(rootRepo == nil || ownForkRepo.ID != rootRepo.ID) {
|
||||||
perm, branches, tags, err := getBranchesAndTagsForRepo(ctx.User, ownForkRepo)
|
perm, branches, tags, err := getBranchesAndTagsForRepo(ctx.User, ownForkRepo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("GetBranchesForRepo", err)
|
ctx.ServerError("GetBranchesForRepo", err)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil
|
||||||
}
|
}
|
||||||
if perm {
|
if perm {
|
||||||
ctx.Data["OwnForkRepo"] = ownForkRepo
|
ctx.Data["OwnForkRepo"] = ownForkRepo
|
||||||
|
@ -429,18 +445,18 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if head branch is valid.
|
// Check if head branch is valid.
|
||||||
headIsCommit := headGitRepo.IsCommitExist(headBranch)
|
headIsCommit := ci.HeadGitRepo.IsCommitExist(ci.HeadBranch)
|
||||||
headIsBranch := headGitRepo.IsBranchExist(headBranch)
|
headIsBranch := ci.HeadGitRepo.IsBranchExist(ci.HeadBranch)
|
||||||
headIsTag := headGitRepo.IsTagExist(headBranch)
|
headIsTag := ci.HeadGitRepo.IsTagExist(ci.HeadBranch)
|
||||||
if !headIsCommit && !headIsBranch && !headIsTag {
|
if !headIsCommit && !headIsBranch && !headIsTag {
|
||||||
// Check if headBranch is short sha commit hash
|
// Check if headBranch is short sha commit hash
|
||||||
if headCommit, _ := headGitRepo.GetCommit(headBranch); headCommit != nil {
|
if headCommit, _ := ci.HeadGitRepo.GetCommit(ci.HeadBranch); headCommit != nil {
|
||||||
headBranch = headCommit.ID.String()
|
ci.HeadBranch = headCommit.ID.String()
|
||||||
ctx.Data["HeadBranch"] = headBranch
|
ctx.Data["HeadBranch"] = ci.HeadBranch
|
||||||
headIsCommit = true
|
headIsCommit = true
|
||||||
} else {
|
} else {
|
||||||
ctx.NotFound("IsRefExist", nil)
|
ctx.NotFound("IsRefExist", nil)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx.Data["HeadIsCommit"] = headIsCommit
|
ctx.Data["HeadIsCommit"] = headIsCommit
|
||||||
|
@ -460,40 +476,36 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
|
||||||
permBase)
|
permBase)
|
||||||
}
|
}
|
||||||
ctx.NotFound("ParseCompareInfo", nil)
|
ctx.NotFound("ParseCompareInfo", nil)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
baseBranchRef := baseBranch
|
baseBranchRef := ci.BaseBranch
|
||||||
if baseIsBranch {
|
if baseIsBranch {
|
||||||
baseBranchRef = git.BranchPrefix + baseBranch
|
baseBranchRef = git.BranchPrefix + ci.BaseBranch
|
||||||
} else if baseIsTag {
|
} else if baseIsTag {
|
||||||
baseBranchRef = git.TagPrefix + baseBranch
|
baseBranchRef = git.TagPrefix + ci.BaseBranch
|
||||||
}
|
}
|
||||||
headBranchRef := headBranch
|
headBranchRef := ci.HeadBranch
|
||||||
if headIsBranch {
|
if headIsBranch {
|
||||||
headBranchRef = git.BranchPrefix + headBranch
|
headBranchRef = git.BranchPrefix + ci.HeadBranch
|
||||||
} else if headIsTag {
|
} else if headIsTag {
|
||||||
headBranchRef = git.TagPrefix + headBranch
|
headBranchRef = git.TagPrefix + ci.HeadBranch
|
||||||
}
|
}
|
||||||
|
|
||||||
compareInfo, err := headGitRepo.GetCompareInfo(baseRepo.RepoPath(), baseBranchRef, headBranchRef)
|
ci.CompareInfo, err = ci.HeadGitRepo.GetCompareInfo(baseRepo.RepoPath(), baseBranchRef, headBranchRef, ci.DirectComparison)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("GetCompareInfo", err)
|
ctx.ServerError("GetCompareInfo", err)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil
|
||||||
}
|
}
|
||||||
ctx.Data["BeforeCommitID"] = compareInfo.MergeBase
|
ctx.Data["BeforeCommitID"] = ci.CompareInfo.MergeBase
|
||||||
|
|
||||||
return headUser, headRepo, headGitRepo, compareInfo, baseBranch, headBranch
|
return ci
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrepareCompareDiff renders compare diff page
|
// PrepareCompareDiff renders compare diff page
|
||||||
func PrepareCompareDiff(
|
func PrepareCompareDiff(
|
||||||
ctx *context.Context,
|
ctx *context.Context,
|
||||||
headUser *models.User,
|
ci *CompareInfo,
|
||||||
headRepo *models.Repository,
|
|
||||||
headGitRepo *git.Repository,
|
|
||||||
compareInfo *git.CompareInfo,
|
|
||||||
baseBranch, headBranch string,
|
|
||||||
whitespaceBehavior string) bool {
|
whitespaceBehavior string) bool {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -503,19 +515,20 @@ func PrepareCompareDiff(
|
||||||
)
|
)
|
||||||
|
|
||||||
// Get diff information.
|
// Get diff information.
|
||||||
ctx.Data["CommitRepoLink"] = headRepo.Link()
|
ctx.Data["CommitRepoLink"] = ci.HeadRepo.Link()
|
||||||
|
|
||||||
headCommitID := compareInfo.HeadCommitID
|
headCommitID := ci.CompareInfo.HeadCommitID
|
||||||
|
|
||||||
ctx.Data["AfterCommitID"] = headCommitID
|
ctx.Data["AfterCommitID"] = headCommitID
|
||||||
|
|
||||||
if headCommitID == compareInfo.MergeBase {
|
if (headCommitID == ci.CompareInfo.MergeBase && !ci.DirectComparison) ||
|
||||||
|
headCommitID == ci.CompareInfo.BaseCommitID {
|
||||||
ctx.Data["IsNothingToCompare"] = true
|
ctx.Data["IsNothingToCompare"] = true
|
||||||
if unit, err := repo.GetUnit(models.UnitTypePullRequests); err == nil {
|
if unit, err := repo.GetUnit(models.UnitTypePullRequests); err == nil {
|
||||||
config := unit.PullRequestsConfig()
|
config := unit.PullRequestsConfig()
|
||||||
|
|
||||||
if !config.AutodetectManualMerge {
|
if !config.AutodetectManualMerge {
|
||||||
allowEmptyPr := !(baseBranch == headBranch && ctx.Repo.Repository.Name == headRepo.Name)
|
allowEmptyPr := !(ci.BaseBranch == ci.HeadBranch && ctx.Repo.Repository.Name == ci.HeadRepo.Name)
|
||||||
ctx.Data["AllowEmptyPr"] = allowEmptyPr
|
ctx.Data["AllowEmptyPr"] = allowEmptyPr
|
||||||
|
|
||||||
return !allowEmptyPr
|
return !allowEmptyPr
|
||||||
|
@ -526,9 +539,14 @@ func PrepareCompareDiff(
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
diff, err := gitdiff.GetDiffRangeWithWhitespaceBehavior(headGitRepo,
|
beforeCommitID := ci.CompareInfo.MergeBase
|
||||||
compareInfo.MergeBase, headCommitID, setting.Git.MaxGitDiffLines,
|
if ci.DirectComparison {
|
||||||
setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, whitespaceBehavior)
|
beforeCommitID = ci.CompareInfo.BaseCommitID
|
||||||
|
}
|
||||||
|
|
||||||
|
diff, err := gitdiff.GetDiffRangeWithWhitespaceBehavior(ci.HeadGitRepo,
|
||||||
|
beforeCommitID, headCommitID, setting.Git.MaxGitDiffLines,
|
||||||
|
setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, whitespaceBehavior, ci.DirectComparison)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("GetDiffRangeWithWhitespaceBehavior", err)
|
ctx.ServerError("GetDiffRangeWithWhitespaceBehavior", err)
|
||||||
return false
|
return false
|
||||||
|
@ -536,14 +554,14 @@ func PrepareCompareDiff(
|
||||||
ctx.Data["Diff"] = diff
|
ctx.Data["Diff"] = diff
|
||||||
ctx.Data["DiffNotAvailable"] = diff.NumFiles == 0
|
ctx.Data["DiffNotAvailable"] = diff.NumFiles == 0
|
||||||
|
|
||||||
headCommit, err := headGitRepo.GetCommit(headCommitID)
|
headCommit, err := ci.HeadGitRepo.GetCommit(headCommitID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("GetCommit", err)
|
ctx.ServerError("GetCommit", err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
baseGitRepo := ctx.Repo.GitRepo
|
baseGitRepo := ctx.Repo.GitRepo
|
||||||
baseCommitID := compareInfo.BaseCommitID
|
baseCommitID := ci.CompareInfo.BaseCommitID
|
||||||
|
|
||||||
baseCommit, err := baseGitRepo.GetCommit(baseCommitID)
|
baseCommit, err := baseGitRepo.GetCommit(baseCommitID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -551,7 +569,7 @@ func PrepareCompareDiff(
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
commits := models.ConvertFromGitCommit(compareInfo.Commits, headRepo)
|
commits := models.ConvertFromGitCommit(ci.CompareInfo.Commits, ci.HeadRepo)
|
||||||
ctx.Data["Commits"] = commits
|
ctx.Data["Commits"] = commits
|
||||||
ctx.Data["CommitCount"] = len(commits)
|
ctx.Data["CommitCount"] = len(commits)
|
||||||
|
|
||||||
|
@ -564,7 +582,7 @@ func PrepareCompareDiff(
|
||||||
ctx.Data["content"] = strings.Join(body[1:], "\n")
|
ctx.Data["content"] = strings.Join(body[1:], "\n")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
title = headBranch
|
title = ci.HeadBranch
|
||||||
}
|
}
|
||||||
if len(title) > 255 {
|
if len(title) > 255 {
|
||||||
var trailer string
|
var trailer string
|
||||||
|
@ -579,10 +597,10 @@ func PrepareCompareDiff(
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Data["title"] = title
|
ctx.Data["title"] = title
|
||||||
ctx.Data["Username"] = headUser.Name
|
ctx.Data["Username"] = ci.HeadUser.Name
|
||||||
ctx.Data["Reponame"] = headRepo.Name
|
ctx.Data["Reponame"] = ci.HeadRepo.Name
|
||||||
|
|
||||||
headTarget := path.Join(headUser.Name, repo.Name)
|
headTarget := path.Join(ci.HeadUser.Name, repo.Name)
|
||||||
setCompareContext(ctx, baseCommit, headCommit, headTarget)
|
setCompareContext(ctx, baseCommit, headCommit, headTarget)
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
@ -615,17 +633,25 @@ func getBranchesAndTagsForRepo(user *models.User, repo *models.Repository) (bool
|
||||||
|
|
||||||
// CompareDiff show different from one commit to another commit
|
// CompareDiff show different from one commit to another commit
|
||||||
func CompareDiff(ctx *context.Context) {
|
func CompareDiff(ctx *context.Context) {
|
||||||
headUser, headRepo, headGitRepo, compareInfo, baseBranch, headBranch := ParseCompareInfo(ctx)
|
ci := ParseCompareInfo(ctx)
|
||||||
defer func() {
|
defer func() {
|
||||||
if headGitRepo != nil {
|
if ci.HeadGitRepo != nil {
|
||||||
headGitRepo.Close()
|
ci.HeadGitRepo.Close()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
nothingToCompare := PrepareCompareDiff(ctx, headUser, headRepo, headGitRepo, compareInfo, baseBranch, headBranch,
|
ctx.Data["DirectComparison"] = ci.DirectComparison
|
||||||
|
ctx.Data["OtherCompareSeparator"] = ".."
|
||||||
|
ctx.Data["CompareSeparator"] = "..."
|
||||||
|
if ci.DirectComparison {
|
||||||
|
ctx.Data["CompareSeparator"] = ".."
|
||||||
|
ctx.Data["OtherCompareSeparator"] = "..."
|
||||||
|
}
|
||||||
|
|
||||||
|
nothingToCompare := PrepareCompareDiff(ctx, ci,
|
||||||
gitdiff.GetWhitespaceFlag(ctx.Data["WhitespaceBehavior"].(string)))
|
gitdiff.GetWhitespaceFlag(ctx.Data["WhitespaceBehavior"].(string)))
|
||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
return
|
return
|
||||||
|
@ -639,14 +665,14 @@ func CompareDiff(ctx *context.Context) {
|
||||||
}
|
}
|
||||||
ctx.Data["Tags"] = baseTags
|
ctx.Data["Tags"] = baseTags
|
||||||
|
|
||||||
headBranches, _, err := headGitRepo.GetBranches(0, 0)
|
headBranches, _, err := ci.HeadGitRepo.GetBranches(0, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("GetBranches", err)
|
ctx.ServerError("GetBranches", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.Data["HeadBranches"] = headBranches
|
ctx.Data["HeadBranches"] = headBranches
|
||||||
|
|
||||||
headTags, err := headGitRepo.GetTags(0, 0)
|
headTags, err := ci.HeadGitRepo.GetTags(0, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("GetTags", err)
|
ctx.ServerError("GetTags", err)
|
||||||
return
|
return
|
||||||
|
@ -654,7 +680,7 @@ func CompareDiff(ctx *context.Context) {
|
||||||
ctx.Data["HeadTags"] = headTags
|
ctx.Data["HeadTags"] = headTags
|
||||||
|
|
||||||
if ctx.Data["PageIsComparePull"] == true {
|
if ctx.Data["PageIsComparePull"] == true {
|
||||||
pr, err := models.GetUnmergedPullRequest(headRepo.ID, ctx.Repo.Repository.ID, headBranch, baseBranch, models.PullRequestFlowGithub)
|
pr, err := models.GetUnmergedPullRequest(ci.HeadRepo.ID, ctx.Repo.Repository.ID, ci.HeadBranch, ci.BaseBranch, models.PullRequestFlowGithub)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !models.IsErrPullRequestNotExist(err) {
|
if !models.IsErrPullRequestNotExist(err) {
|
||||||
ctx.ServerError("GetUnmergedPullRequest", err)
|
ctx.ServerError("GetUnmergedPullRequest", err)
|
||||||
|
@ -678,7 +704,11 @@ func CompareDiff(ctx *context.Context) {
|
||||||
beforeCommitID := ctx.Data["BeforeCommitID"].(string)
|
beforeCommitID := ctx.Data["BeforeCommitID"].(string)
|
||||||
afterCommitID := ctx.Data["AfterCommitID"].(string)
|
afterCommitID := ctx.Data["AfterCommitID"].(string)
|
||||||
|
|
||||||
ctx.Data["Title"] = "Comparing " + base.ShortSha(beforeCommitID) + "..." + base.ShortSha(afterCommitID)
|
separator := "..."
|
||||||
|
if ci.DirectComparison {
|
||||||
|
separator = ".."
|
||||||
|
}
|
||||||
|
ctx.Data["Title"] = "Comparing " + base.ShortSha(beforeCommitID) + separator + base.ShortSha(afterCommitID)
|
||||||
|
|
||||||
ctx.Data["IsRepoToolbarCommits"] = true
|
ctx.Data["IsRepoToolbarCommits"] = true
|
||||||
ctx.Data["IsDiffCompare"] = true
|
ctx.Data["IsDiffCompare"] = true
|
||||||
|
|
|
@ -318,7 +318,7 @@ func PrepareMergedViewPullInfo(ctx *context.Context, issue *models.Issue) *git.C
|
||||||
ctx.Data["HasMerged"] = true
|
ctx.Data["HasMerged"] = true
|
||||||
|
|
||||||
compareInfo, err := ctx.Repo.GitRepo.GetCompareInfo(ctx.Repo.Repository.RepoPath(),
|
compareInfo, err := ctx.Repo.GitRepo.GetCompareInfo(ctx.Repo.Repository.RepoPath(),
|
||||||
pull.MergeBase, pull.GetGitRefName())
|
pull.MergeBase, pull.GetGitRefName(), true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.Contains(err.Error(), "fatal: Not a valid object name") || strings.Contains(err.Error(), "unknown revision or path not in the working tree") {
|
if strings.Contains(err.Error(), "fatal: Not a valid object name") || strings.Contains(err.Error(), "unknown revision or path not in the working tree") {
|
||||||
ctx.Data["IsPullRequestBroken"] = true
|
ctx.Data["IsPullRequestBroken"] = true
|
||||||
|
@ -401,7 +401,7 @@ func PrepareViewPullInfo(ctx *context.Context, issue *models.Issue) *git.Compare
|
||||||
}
|
}
|
||||||
|
|
||||||
compareInfo, err := baseGitRepo.GetCompareInfo(pull.BaseRepo.RepoPath(),
|
compareInfo, err := baseGitRepo.GetCompareInfo(pull.BaseRepo.RepoPath(),
|
||||||
pull.MergeBase, pull.GetGitRefName())
|
pull.MergeBase, pull.GetGitRefName(), true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.Contains(err.Error(), "fatal: Not a valid object name") {
|
if strings.Contains(err.Error(), "fatal: Not a valid object name") {
|
||||||
ctx.Data["IsPullRequestBroken"] = true
|
ctx.Data["IsPullRequestBroken"] = true
|
||||||
|
@ -517,7 +517,7 @@ func PrepareViewPullInfo(ctx *context.Context, issue *models.Issue) *git.Compare
|
||||||
}
|
}
|
||||||
|
|
||||||
compareInfo, err := baseGitRepo.GetCompareInfo(pull.BaseRepo.RepoPath(),
|
compareInfo, err := baseGitRepo.GetCompareInfo(pull.BaseRepo.RepoPath(),
|
||||||
git.BranchPrefix+pull.BaseBranch, pull.GetGitRefName())
|
git.BranchPrefix+pull.BaseBranch, pull.GetGitRefName(), true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.Contains(err.Error(), "fatal: Not a valid object name") {
|
if strings.Contains(err.Error(), "fatal: Not a valid object name") {
|
||||||
ctx.Data["IsPullRequestBroken"] = true
|
ctx.Data["IsPullRequestBroken"] = true
|
||||||
|
@ -635,7 +635,7 @@ func ViewPullFiles(ctx *context.Context) {
|
||||||
diff, err := gitdiff.GetDiffRangeWithWhitespaceBehavior(gitRepo,
|
diff, err := gitdiff.GetDiffRangeWithWhitespaceBehavior(gitRepo,
|
||||||
startCommitID, endCommitID, setting.Git.MaxGitDiffLines,
|
startCommitID, endCommitID, setting.Git.MaxGitDiffLines,
|
||||||
setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles,
|
setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles,
|
||||||
gitdiff.GetWhitespaceFlag(ctx.Data["WhitespaceBehavior"].(string)))
|
gitdiff.GetWhitespaceFlag(ctx.Data["WhitespaceBehavior"].(string)), false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("GetDiffRangeWithWhitespaceBehavior", err)
|
ctx.ServerError("GetDiffRangeWithWhitespaceBehavior", err)
|
||||||
return
|
return
|
||||||
|
@ -1041,10 +1041,10 @@ func CompareAndPullRequestPost(ctx *context.Context) {
|
||||||
attachments []string
|
attachments []string
|
||||||
)
|
)
|
||||||
|
|
||||||
headUser, headRepo, headGitRepo, prInfo, baseBranch, headBranch := ParseCompareInfo(ctx)
|
ci := ParseCompareInfo(ctx)
|
||||||
defer func() {
|
defer func() {
|
||||||
if headGitRepo != nil {
|
if ci.HeadGitRepo != nil {
|
||||||
headGitRepo.Close()
|
ci.HeadGitRepo.Close()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
|
@ -1065,7 +1065,7 @@ func CompareAndPullRequestPost(ctx *context.Context) {
|
||||||
|
|
||||||
// This stage is already stop creating new pull request, so it does not matter if it has
|
// This stage is already stop creating new pull request, so it does not matter if it has
|
||||||
// something to compare or not.
|
// something to compare or not.
|
||||||
PrepareCompareDiff(ctx, headUser, headRepo, headGitRepo, prInfo, baseBranch, headBranch,
|
PrepareCompareDiff(ctx, ci,
|
||||||
gitdiff.GetWhitespaceFlag(ctx.Data["WhitespaceBehavior"].(string)))
|
gitdiff.GetWhitespaceFlag(ctx.Data["WhitespaceBehavior"].(string)))
|
||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
return
|
return
|
||||||
|
@ -1084,7 +1084,7 @@ func CompareAndPullRequestPost(ctx *context.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if util.IsEmptyString(form.Title) {
|
if util.IsEmptyString(form.Title) {
|
||||||
PrepareCompareDiff(ctx, headUser, headRepo, headGitRepo, prInfo, baseBranch, headBranch,
|
PrepareCompareDiff(ctx, ci,
|
||||||
gitdiff.GetWhitespaceFlag(ctx.Data["WhitespaceBehavior"].(string)))
|
gitdiff.GetWhitespaceFlag(ctx.Data["WhitespaceBehavior"].(string)))
|
||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
return
|
return
|
||||||
|
@ -1104,13 +1104,13 @@ func CompareAndPullRequestPost(ctx *context.Context) {
|
||||||
Content: form.Content,
|
Content: form.Content,
|
||||||
}
|
}
|
||||||
pullRequest := &models.PullRequest{
|
pullRequest := &models.PullRequest{
|
||||||
HeadRepoID: headRepo.ID,
|
HeadRepoID: ci.HeadRepo.ID,
|
||||||
BaseRepoID: repo.ID,
|
BaseRepoID: repo.ID,
|
||||||
HeadBranch: headBranch,
|
HeadBranch: ci.HeadBranch,
|
||||||
BaseBranch: baseBranch,
|
BaseBranch: ci.BaseBranch,
|
||||||
HeadRepo: headRepo,
|
HeadRepo: ci.HeadRepo,
|
||||||
BaseRepo: repo,
|
BaseRepo: repo,
|
||||||
MergeBase: prInfo.MergeBase,
|
MergeBase: ci.CompareInfo.MergeBase,
|
||||||
Type: models.PullRequestGitea,
|
Type: models.PullRequestGitea,
|
||||||
}
|
}
|
||||||
// FIXME: check error in the case two people send pull request at almost same time, give nice error prompt
|
// FIXME: check error in the case two people send pull request at almost same time, give nice error prompt
|
||||||
|
|
|
@ -1217,7 +1217,7 @@ func readFileName(rd *strings.Reader) (string, bool) {
|
||||||
// GetDiffRangeWithWhitespaceBehavior builds a Diff between two commits of a repository.
|
// GetDiffRangeWithWhitespaceBehavior builds a Diff between two commits of a repository.
|
||||||
// Passing the empty string as beforeCommitID returns a diff from the parent commit.
|
// Passing the empty string as beforeCommitID returns a diff from the parent commit.
|
||||||
// The whitespaceBehavior is either an empty string or a git flag
|
// The whitespaceBehavior is either an empty string or a git flag
|
||||||
func GetDiffRangeWithWhitespaceBehavior(gitRepo *git.Repository, beforeCommitID, afterCommitID string, maxLines, maxLineCharacters, maxFiles int, whitespaceBehavior string) (*Diff, error) {
|
func GetDiffRangeWithWhitespaceBehavior(gitRepo *git.Repository, beforeCommitID, afterCommitID string, maxLines, maxLineCharacters, maxFiles int, whitespaceBehavior string, directComparison bool) (*Diff, error) {
|
||||||
repoPath := gitRepo.Path
|
repoPath := gitRepo.Path
|
||||||
|
|
||||||
commit, err := gitRepo.GetCommit(afterCommitID)
|
commit, err := gitRepo.GetCommit(afterCommitID)
|
||||||
|
@ -1357,7 +1357,12 @@ func GetDiffRangeWithWhitespaceBehavior(gitRepo *git.Repository, beforeCommitID,
|
||||||
return nil, fmt.Errorf("Wait: %v", err)
|
return nil, fmt.Errorf("Wait: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
shortstatArgs := []string{beforeCommitID + "..." + afterCommitID}
|
separator := "..."
|
||||||
|
if directComparison {
|
||||||
|
separator = ".."
|
||||||
|
}
|
||||||
|
|
||||||
|
shortstatArgs := []string{beforeCommitID + separator + afterCommitID}
|
||||||
if len(beforeCommitID) == 0 || beforeCommitID == git.EmptySHA {
|
if len(beforeCommitID) == 0 || beforeCommitID == git.EmptySHA {
|
||||||
shortstatArgs = []string{git.EmptyTreeSHA, afterCommitID}
|
shortstatArgs = []string{git.EmptyTreeSHA, afterCommitID}
|
||||||
}
|
}
|
||||||
|
@ -1377,8 +1382,8 @@ func GetDiffRangeWithWhitespaceBehavior(gitRepo *git.Repository, beforeCommitID,
|
||||||
|
|
||||||
// GetDiffCommitWithWhitespaceBehavior builds a Diff representing the given commitID.
|
// GetDiffCommitWithWhitespaceBehavior builds a Diff representing the given commitID.
|
||||||
// The whitespaceBehavior is either an empty string or a git flag
|
// The whitespaceBehavior is either an empty string or a git flag
|
||||||
func GetDiffCommitWithWhitespaceBehavior(gitRepo *git.Repository, commitID string, maxLines, maxLineCharacters, maxFiles int, whitespaceBehavior string) (*Diff, error) {
|
func GetDiffCommitWithWhitespaceBehavior(gitRepo *git.Repository, commitID string, maxLines, maxLineCharacters, maxFiles int, whitespaceBehavior string, directComparison bool) (*Diff, error) {
|
||||||
return GetDiffRangeWithWhitespaceBehavior(gitRepo, "", commitID, maxLines, maxLineCharacters, maxFiles, whitespaceBehavior)
|
return GetDiffRangeWithWhitespaceBehavior(gitRepo, "", commitID, maxLines, maxLineCharacters, maxFiles, whitespaceBehavior, directComparison)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommentAsDiff returns c.Patch as *Diff
|
// CommentAsDiff returns c.Patch as *Diff
|
||||||
|
|
|
@ -523,7 +523,7 @@ func TestGetDiffRangeWithWhitespaceBehavior(t *testing.T) {
|
||||||
defer gitRepo.Close()
|
defer gitRepo.Close()
|
||||||
for _, behavior := range []string{"-w", "--ignore-space-at-eol", "-b", ""} {
|
for _, behavior := range []string{"-w", "--ignore-space-at-eol", "-b", ""} {
|
||||||
diffs, err := GetDiffRangeWithWhitespaceBehavior(gitRepo, "559c156f8e0178b71cb44355428f24001b08fc68", "bd7063cc7c04689c4d082183d32a604ed27a24f9",
|
diffs, err := GetDiffRangeWithWhitespaceBehavior(gitRepo, "559c156f8e0178b71cb44355428f24001b08fc68", "bd7063cc7c04689c4d082183d32a604ed27a24f9",
|
||||||
setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffFiles, behavior)
|
setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffFiles, behavior, false)
|
||||||
assert.NoError(t, err, fmt.Sprintf("Error when diff with %s", behavior))
|
assert.NoError(t, err, fmt.Sprintf("Error when diff with %s", behavior))
|
||||||
for _, f := range diffs.Files {
|
for _, f := range diffs.Files {
|
||||||
assert.True(t, len(f.Sections) > 0, fmt.Sprintf("%s should have sections", f.Name))
|
assert.True(t, len(f.Sections) > 0, fmt.Sprintf("%s should have sections", f.Name))
|
||||||
|
|
|
@ -80,7 +80,7 @@ func NewPullRequest(repo *models.Repository, pull *models.Issue, labelIDs []int6
|
||||||
defer baseGitRepo.Close()
|
defer baseGitRepo.Close()
|
||||||
|
|
||||||
compareInfo, err := baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(),
|
compareInfo, err := baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(),
|
||||||
git.BranchPrefix+pr.BaseBranch, pr.GetGitRefName())
|
git.BranchPrefix+pr.BaseBranch, pr.GetGitRefName(), true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
<div class="ui segment choose branch">
|
<div class="ui segment choose branch">
|
||||||
{{svg "octicon-git-compare"}}
|
<a href="{{$.HeadRepo.Link}}/compare/{{EscapePound $.HeadBranch}}{{$.CompareSeparator}}{{if not $.PullRequestCtx.SameRepo}}{{$.BaseName}}/{{$.Repository.Name}}:{{end}}{{EscapePound $.BaseBranch}}" title="{{.i18n.Tr "repo.pulls.switch_head_and_base"}}">{{svg "octicon-git-compare"}}</a>
|
||||||
<div class="ui floating filter dropdown" data-no-results="{{.i18n.Tr "repo.pulls.no_results"}}">
|
<div class="ui floating filter dropdown" data-no-results="{{.i18n.Tr "repo.pulls.no_results"}}">
|
||||||
<div class="ui basic small button">
|
<div class="ui basic small button">
|
||||||
<span class="text">{{if $.PageIsComparePull}}{{.i18n.Tr "repo.pulls.compare_base"}}{{else}}{{.i18n.Tr "repo.compare.compare_base"}}{{end}}: {{$BaseCompareName}}:{{$.BaseBranch}}</span>
|
<span class="text">{{if $.PageIsComparePull}}{{.i18n.Tr "repo.pulls.compare_base"}}{{else}}{{.i18n.Tr "repo.compare.compare_base"}}{{end}}: {{$BaseCompareName}}:{{$.BaseBranch}}</span>
|
||||||
|
@ -62,47 +62,47 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="scrolling menu reference-list-menu base-branch-list">
|
<div class="scrolling menu reference-list-menu base-branch-list">
|
||||||
{{range .Branches}}
|
{{range .Branches}}
|
||||||
<div class="item {{if eq $.BaseBranch .}}selected{{end}}" data-url="{{$.RepoLink}}/compare/{{EscapePound .}}...{{if not $.PullRequestCtx.SameRepo}}{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{end}}{{EscapePound $.HeadBranch}}">{{$BaseCompareName}}:{{.}}</div>
|
<div class="item {{if eq $.BaseBranch .}}selected{{end}}" data-url="{{$.RepoLink}}/compare/{{EscapePound .}}{{$.CompareSeparator}}{{if not $.PullRequestCtx.SameRepo}}{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{end}}{{EscapePound $.HeadBranch}}">{{$BaseCompareName}}:{{.}}</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if not .PullRequestCtx.SameRepo}}
|
{{if not .PullRequestCtx.SameRepo}}
|
||||||
{{range .HeadBranches}}
|
{{range .HeadBranches}}
|
||||||
<div class="item" data-url="{{$.HeadRepo.Link}}/compare/{{EscapePound .}}...{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{EscapePound $.HeadBranch}}">{{$HeadCompareName}}:{{.}}</div>
|
<div class="item" data-url="{{$.HeadRepo.Link}}/compare/{{EscapePound .}}{{$.CompareSeparator}}{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{EscapePound $.HeadBranch}}">{{$HeadCompareName}}:{{.}}</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .OwnForkRepo}}
|
{{if .OwnForkRepo}}
|
||||||
{{range .OwnForkRepoBranches}}
|
{{range .OwnForkRepoBranches}}
|
||||||
<div class="item" data-url="{{$.OwnForkRepo.Link}}/compare/{{EscapePound .}}...{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{EscapePound $.HeadBranch}}">{{$OwnForkCompareName}}:{{.}}</div>
|
<div class="item" data-url="{{$.OwnForkRepo.Link}}/compare/{{EscapePound .}}{{$.CompareSeparator}}{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{EscapePound $.HeadBranch}}">{{$OwnForkCompareName}}:{{.}}</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .RootRepo}}
|
{{if .RootRepo}}
|
||||||
{{range .RootRepoBranches}}
|
{{range .RootRepoBranches}}
|
||||||
<div class="item" data-url="{{$.RootRepo.Link}}/compare/{{EscapePound .}}...{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{EscapePound $.HeadBranch}}">{{$RootRepoCompareName}}:{{.}}</div>
|
<div class="item" data-url="{{$.RootRepo.Link}}/compare/{{EscapePound .}}{{$.CompareSeparator}}{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{EscapePound $.HeadBranch}}">{{$RootRepoCompareName}}:{{.}}</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
<div class="scrolling menu reference-list-menu base-tag-list" style="display: none">
|
<div class="scrolling menu reference-list-menu base-tag-list" style="display: none">
|
||||||
{{range .Tags}}
|
{{range .Tags}}
|
||||||
<div class="item {{if eq $.BaseBranch .}}selected{{end}}" data-url="{{$.RepoLink}}/compare/{{EscapePound .}}...{{if not $.PullRequestCtx.SameRepo}}{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{end}}{{EscapePound $.HeadBranch}}">{{$BaseCompareName}}:{{.}}</div>
|
<div class="item {{if eq $.BaseBranch .}}selected{{end}}" data-url="{{$.RepoLink}}/compare/{{EscapePound .}}{{$.CompareSeparator}}{{if not $.PullRequestCtx.SameRepo}}{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{end}}{{EscapePound $.HeadBranch}}">{{$BaseCompareName}}:{{.}}</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if not .PullRequestCtx.SameRepo}}
|
{{if not .PullRequestCtx.SameRepo}}
|
||||||
{{range .HeadTags}}
|
{{range .HeadTags}}
|
||||||
<div class="item" data-url="{{$.HeadRepo.Link}}/compare/{{EscapePound .}}...{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{EscapePound $.HeadBranch}}">{{$HeadCompareName}}:{{.}}</div>
|
<div class="item" data-url="{{$.HeadRepo.Link}}/compare/{{EscapePound .}}{{$.CompareSeparator}}{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{EscapePound $.HeadBranch}}">{{$HeadCompareName}}:{{.}}</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .OwnForkRepo}}
|
{{if .OwnForkRepo}}
|
||||||
{{range .OwnForkRepoTags}}
|
{{range .OwnForkRepoTags}}
|
||||||
<div class="item" data-url="{{$.OwnForkRepo.Link}}/compare/{{EscapePound .}}...{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{EscapePound $.HeadBranch}}">{{$OwnForkCompareName}}:{{.}}</div>
|
<div class="item" data-url="{{$.OwnForkRepo.Link}}/compare/{{EscapePound .}}{{$.CompareSeparator}}{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{EscapePound $.HeadBranch}}">{{$OwnForkCompareName}}:{{.}}</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .RootRepo}}
|
{{if .RootRepo}}
|
||||||
{{range .RootRepoTags}}
|
{{range .RootRepoTags}}
|
||||||
<div class="item" data-url="{{$.RootRepo.Link}}/compare/{{EscapePound .}}...{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{EscapePound $.HeadBranch}}">{{$RootRepoCompareName}}:{{.}}</div>
|
<div class="item" data-url="{{$.RootRepo.Link}}/compare/{{EscapePound .}}{{$.CompareSeparator}}{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{EscapePound $.HeadBranch}}">{{$RootRepoCompareName}}:{{.}}</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
...
|
<a href="{{.RepoLink}}/compare/{{EscapePound .BaseBranch}}{{.OtherCompareSeparator}}{{if not $.PullRequestCtx.SameRepo}}{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{end}}{{EscapePound $.HeadBranch}}" title="{{.i18n.Tr "repo.pulls.switch_comparison_type"}}">{{.CompareSeparator}}</a>
|
||||||
<div class="ui floating filter dropdown">
|
<div class="ui floating filter dropdown">
|
||||||
<div class="ui basic small button">
|
<div class="ui basic small button">
|
||||||
<span class="text">{{if $.PageIsComparePull}}{{.i18n.Tr "repo.pulls.compare_compare"}}{{else}}{{.i18n.Tr "repo.compare.compare_head"}}{{end}}: {{$HeadCompareName}}:{{$.HeadBranch}}</span>
|
<span class="text">{{if $.PageIsComparePull}}{{.i18n.Tr "repo.pulls.compare_compare"}}{{else}}{{.i18n.Tr "repo.compare.compare_head"}}{{end}}: {{$HeadCompareName}}:{{$.HeadBranch}}</span>
|
||||||
|
@ -131,41 +131,41 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="scrolling menu reference-list-menu head-branch-list">
|
<div class="scrolling menu reference-list-menu head-branch-list">
|
||||||
{{range .HeadBranches}}
|
{{range .HeadBranches}}
|
||||||
<div class="{{if eq $.HeadBranch .}}selected{{end}} item" data-url="{{$.RepoLink}}/compare/{{EscapePound $.BaseBranch}}...{{if not $.PullRequestCtx.SameRepo}}{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{end}}{{EscapePound .}}">{{$HeadCompareName}}:{{.}}</div>
|
<div class="{{if eq $.HeadBranch .}}selected{{end}} item" data-url="{{$.RepoLink}}/compare/{{EscapePound $.BaseBranch}}{{$.CompareSeparator}}{{if not $.PullRequestCtx.SameRepo}}{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{end}}{{EscapePound .}}">{{$HeadCompareName}}:{{.}}</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if not .PullRequestCtx.SameRepo}}
|
{{if not .PullRequestCtx.SameRepo}}
|
||||||
{{range .Branches}}
|
{{range .Branches}}
|
||||||
<div class="item" data-url="{{$.RepoLink}}/compare/{{EscapePound $.BaseBranch}}...{{$.BaseName}}/{{$.Repository.Name}}:{{EscapePound .}}">{{$BaseCompareName}}:{{.}}</div>
|
<div class="item" data-url="{{$.RepoLink}}/compare/{{EscapePound $.BaseBranch}}{{$.CompareSeparator}}{{$.BaseName}}/{{$.Repository.Name}}:{{EscapePound .}}">{{$BaseCompareName}}:{{.}}</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .OwnForkRepo}}
|
{{if .OwnForkRepo}}
|
||||||
{{range .OwnForkRepoBranches}}
|
{{range .OwnForkRepoBranches}}
|
||||||
<div class="item" data-url="{{$.RepoLink}}/compare/{{EscapePound $.BaseBranch}}...{{$.OwnForkRepo.OwnerName}}/{{$.OwnForkRepo.Name}}:{{EscapePound .}}">{{$OwnForkCompareName}}:{{.}}</div>
|
<div class="item" data-url="{{$.RepoLink}}/compare/{{EscapePound $.BaseBranch}}{{$.CompareSeparator}}{{$.OwnForkRepo.OwnerName}}/{{$.OwnForkRepo.Name}}:{{EscapePound .}}">{{$OwnForkCompareName}}:{{.}}</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .RootRepo}}
|
{{if .RootRepo}}
|
||||||
{{range .RootRepoBranches}}
|
{{range .RootRepoBranches}}
|
||||||
<div class="item" data-url="{{$.RepoLink}}/compare/{{EscapePound $.BaseBranch}}...{{$.RootRepo.OwnerName}}/{{$.RootRepo.Name}}:{{EscapePound .}}">{{$RootRepoCompareName}}:{{.}}</div>
|
<div class="item" data-url="{{$.RepoLink}}/compare/{{EscapePound $.BaseBranch}}{{$.CompareSeparator}}{{$.RootRepo.OwnerName}}/{{$.RootRepo.Name}}:{{EscapePound .}}">{{$RootRepoCompareName}}:{{.}}</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
<div class="scrolling menu reference-list-menu head-tag-list" style="display: none">
|
<div class="scrolling menu reference-list-menu head-tag-list" style="display: none">
|
||||||
{{range .HeadTags}}
|
{{range .HeadTags}}
|
||||||
<div class="{{if eq $.HeadBranch .}}selected{{end}} item" data-url="{{$.RepoLink}}/compare/{{EscapePound $.BaseBranch}}...{{if not $.PullRequestCtx.SameRepo}}{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{end}}{{EscapePound .}}">{{$HeadCompareName}}:{{.}}</div>
|
<div class="{{if eq $.HeadBranch .}}selected{{end}} item" data-url="{{$.RepoLink}}/compare/{{EscapePound $.BaseBranch}}{{$.CompareSeparator}}{{if not $.PullRequestCtx.SameRepo}}{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{end}}{{EscapePound .}}">{{$HeadCompareName}}:{{.}}</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if not .PullRequestCtx.SameRepo}}
|
{{if not .PullRequestCtx.SameRepo}}
|
||||||
{{range .Tags}}
|
{{range .Tags}}
|
||||||
<div class="item" data-url="{{$.RepoLink}}/compare/{{EscapePound $.BaseBranch}}...{{$.BaseName}}/{{$.Repository.Name}}:{{EscapePound .}}">{{$BaseCompareName}}:{{.}}</div>
|
<div class="item" data-url="{{$.RepoLink}}/compare/{{EscapePound $.BaseBranch}}{{$.CompareSeparator}}{{$.BaseName}}/{{$.Repository.Name}}:{{EscapePound .}}">{{$BaseCompareName}}:{{.}}</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .OwnForkRepo}}
|
{{if .OwnForkRepo}}
|
||||||
{{range .OwnForkRepoTags}}
|
{{range .OwnForkRepoTags}}
|
||||||
<div class="item" data-url="{{$.RepoLink}}/compare/{{EscapePound $.BaseBranch}}...{{$.OwnForkRepo.OwnerName}}/{{$.OwnForkRepo.Name}}:{{EscapePound .}}">{{$OwnForkCompareName}}:{{.}}</div>
|
<div class="item" data-url="{{$.RepoLink}}/compare/{{EscapePound $.BaseBranch}}{{$.CompareSeparator}}{{$.OwnForkRepo.OwnerName}}/{{$.OwnForkRepo.Name}}:{{EscapePound .}}">{{$OwnForkCompareName}}:{{.}}</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .RootRepo}}
|
{{if .RootRepo}}
|
||||||
{{range .RootRepoTags}}
|
{{range .RootRepoTags}}
|
||||||
<div class="item" data-url="{{$.RepoLink}}/compare/{{EscapePound $.BaseBranch}}...{{$.RootRepo.OwnerName}}/{{$.RootRepo.Name}}:{{EscapePound .}}">{{$RootRepoCompareName}}:{{.}}</div>
|
<div class="item" data-url="{{$.RepoLink}}/compare/{{EscapePound $.BaseBranch}}{{$.CompareSeparator}}{{$.RootRepo.OwnerName}}/{{$.RootRepo.Name}}:{{EscapePound .}}">{{$RootRepoCompareName}}:{{.}}</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
|
Reference in a new issue