Skip to content

Compare branches, commits and tags with each other #6991

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 26 commits into from
Jun 7, 2019
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
ae31016
Supports tags when comparing commits or branches
saitho Apr 27, 2019
6b08eff
Hide headline when only comparing and don't load unused data
saitho Apr 27, 2019
b39064e
Merges compare logics to allow comparing branches, commits and tags w…
saitho Apr 28, 2019
449b62a
Display branch or tag instead of commit when used for comparing
saitho Apr 28, 2019
129025c
Show pull request form after click on button
saitho Apr 28, 2019
c6a3e13
Merge branch 'master' into feature/4567-Compare_tags
saitho May 4, 2019
68911af
Merge remote-tracking branch 'origin/master' into feature/4567-Compar…
saitho May 19, 2019
5f4fbb3
Transfers relevant pull.go changes from master to compare.go
saitho May 19, 2019
77f46c7
Fixes error when comparing forks against a commit or tag
saitho May 19, 2019
d25e139
Removes console.log from JavaScript file
saitho May 19, 2019
75c4dd5
Show icon next to commit reference when comparing branch or tag
saitho May 19, 2019
8d9f14e
Updates css file
saitho May 19, 2019
5e4dfc2
Fixes import order
saitho May 19, 2019
a6978fe
Renames template variable
saitho May 19, 2019
fa14c89
Update routers/repo/compare.go
saitho May 22, 2019
9406344
Merge remote-tracking branch 'origin/master' into feature/4567-Compar…
saitho May 27, 2019
8d96a0a
Update from master
saitho May 27, 2019
c73353b
Merge branch 'feature/4567-Compare_tags' of github.com:saitho/gitea i…
saitho May 27, 2019
8484a2f
Allow short-shas in compare
zeripath May 29, 2019
f96f53a
Renames prInfo to compareInfo
saitho May 30, 2019
90325f8
Check PR permissions only if compare is pull request
saitho May 30, 2019
6913c5b
Merge remote-tracking branch 'origin/master' into feature/4567-Compar…
saitho May 30, 2019
eef8bef
Adjusts comment
saitho May 30, 2019
577f15f
Use compareInfo instead of prInfo
saitho Jun 1, 2019
f0ff5db
Merge branch 'master' into feature/4567-Compare_tags
zeripath Jun 3, 2019
76c6fa9
Merge branch 'master' into feature/4567-Compare_tags
lunny Jun 6, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions models/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -1144,8 +1144,7 @@ func (pr *PullRequest) UpdatePatch() (err error) {
defer func() {
headGitRepo.RemoveRemote(tmpRemote)
}()
remoteBranch := "remotes/" + tmpRemote + "/" + pr.BaseBranch
pr.MergeBase, err = headGitRepo.GetMergeBase(remoteBranch, pr.HeadBranch)
pr.MergeBase, err = headGitRepo.GetMergeBase(tmpRemote, pr.BaseBranch, pr.HeadBranch)
if err != nil {
return fmt.Errorf("GetMergeBase: %v", err)
} else if err = pr.Update(); err != nil {
Expand Down
10 changes: 10 additions & 0 deletions modules/git/repo_commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@ func (repo *Repository) GetRefCommitID(name string) (string, error) {
return ref.Hash().String(), nil
}

// IsCommitExist returns true if given commit exists in current repository.
func (repo *Repository) IsCommitExist(name string) bool {
hash := plumbing.NewHash(name)
_, err := repo.gogitRepo.CommitObject(hash)
if err != nil {
return false
}
return true
}

// GetBranchCommitID returns last commit ID string of given branch.
func (repo *Repository) GetBranchCommitID(name string) (string, error) {
return repo.GetRefCommitID(BranchPrefix + name)
Expand Down
54 changes: 33 additions & 21 deletions modules/git/repo_pull.go → modules/git/repo_compare.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Copyright 2015 The Gogs Authors. All rights reserved.
// Copyright 2019 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

Expand All @@ -14,55 +15,66 @@ import (
"time"
)

// PullRequestInfo represents needed information for a pull request.
type PullRequestInfo struct {
// CompareInfo represents needed information for comparing references.
type CompareInfo struct {
MergeBase string
Commits *list.List
NumFiles int
}

// GetMergeBase checks and returns merge base of two branches.
func (repo *Repository) GetMergeBase(base, head string) (string, error) {
func (repo *Repository) GetMergeBase(tmpRemote string, base, head string) (string, error) {
if tmpRemote == "" {
tmpRemote = "origin"
}

if tmpRemote != "origin" {
tmpBaseName := "refs/remotes/" + tmpRemote + "/tmp_" + base
// Fetch commit into a temporary branch in order to be able to handle commits and tags
_, err := NewCommand("fetch", tmpRemote, base+":"+tmpBaseName).RunInDir(repo.Path)
if err == nil {
base = tmpBaseName
}
}

stdout, err := NewCommand("merge-base", base, head).RunInDir(repo.Path)
return strings.TrimSpace(stdout), err
}

// GetPullRequestInfo generates and returns pull request information
// between base and head branches of repositories.
func (repo *Repository) GetPullRequestInfo(basePath, baseBranch, headBranch string) (_ *PullRequestInfo, err error) {
var remoteBranch string
// GetCompareInfo generates and returns compare information between base and head branches of repositories.
func (repo *Repository) GetCompareInfo(basePath, baseBranch, headBranch string) (_ *CompareInfo, err error) {
var (
remoteBranch string
tmpRemote string
)

// We don't need a temporary remote for same repository.
if repo.Path != basePath {
// Add a temporary remote
tmpRemote := strconv.FormatInt(time.Now().UnixNano(), 10)
tmpRemote = strconv.FormatInt(time.Now().UnixNano(), 10)
if err = repo.AddRemote(tmpRemote, basePath, true); err != nil {
return nil, fmt.Errorf("AddRemote: %v", err)
}
defer repo.RemoveRemote(tmpRemote)

remoteBranch = "remotes/" + tmpRemote + "/" + baseBranch
} else {
remoteBranch = baseBranch
}

prInfo := new(PullRequestInfo)
prInfo.MergeBase, err = repo.GetMergeBase(remoteBranch, headBranch)
compareInfo := new(CompareInfo)
compareInfo.MergeBase, err = repo.GetMergeBase(tmpRemote, baseBranch, headBranch)
if err == nil {
// We have a common base
logs, err := NewCommand("log", prInfo.MergeBase+"..."+headBranch, prettyLogFormat).RunInDirBytes(repo.Path)
logs, err := NewCommand("log", compareInfo.MergeBase+"..."+headBranch, prettyLogFormat).RunInDirBytes(repo.Path)
if err != nil {
return nil, err
}
prInfo.Commits, err = repo.parsePrettyFormatLogToList(logs)
compareInfo.Commits, err = repo.parsePrettyFormatLogToList(logs)
if err != nil {
return nil, fmt.Errorf("parsePrettyFormatLogToList: %v", err)
}
} else {
prInfo.Commits = list.New()
prInfo.MergeBase, err = GetFullCommitID(repo.Path, remoteBranch)
compareInfo.Commits = list.New()
compareInfo.MergeBase, err = GetFullCommitID(repo.Path, remoteBranch)
if err != nil {
prInfo.MergeBase = remoteBranch
compareInfo.MergeBase = remoteBranch
}
}

Expand All @@ -71,9 +83,9 @@ func (repo *Repository) GetPullRequestInfo(basePath, baseBranch, headBranch stri
if err != nil {
return nil, err
}
prInfo.NumFiles = len(strings.Split(stdout, "\n")) - 1
compareInfo.NumFiles = len(strings.Split(stdout, "\n")) - 1

return prInfo, nil
return compareInfo, nil
}

// GetPatch generates and returns patch data between given revisions.
Expand Down
File renamed without changes.
1 change: 1 addition & 0 deletions public/css/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,7 @@ footer .ui.left,footer .ui.right{line-height:40px}
.repository .milestone.list>.item .content{padding-top:10px}
.repository.new.milestone textarea{height:200px}
.repository.new.milestone #deadline{width:150px}
.repository.compare.pull .show-form-container{text-align:left}
.repository.compare.pull .choose.branch .octicon{padding-right:10px}
.repository.compare.pull .comment.form .content:after,.repository.compare.pull .comment.form .content:before{right:100%;top:20px;border:solid transparent;content:" ";height:0;width:0;position:absolute;pointer-events:none}
.repository.compare.pull .comment.form .content:before{border-right-color:#d3d3d4;border-width:9px;margin-top:-9px}
Expand Down
9 changes: 8 additions & 1 deletion public/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -959,8 +959,15 @@ function initRepository() {
});

// Pull request
if ($('.repository.compare.pull').length > 0) {
var $repoComparePull = $('.repository.compare.pull');
if ($repoComparePull.length > 0) {
initFilterSearchDropdown('.choose.branch .dropdown');
// show pull request form
$repoComparePull.find('button.show-form').on('click', function(e) {
e.preventDefault();
$repoComparePull.find('.pullrequest-form').show();
$(this).parent().hide();
});
}

// Branches
Expand Down
3 changes: 3 additions & 0 deletions public/less/_repository.less
Original file line number Diff line number Diff line change
Expand Up @@ -1109,6 +1109,9 @@
}

&.compare.pull {
.show-form-container {
text-align: left;
}
.choose.branch {
.octicon {
padding-right: 10px;
Expand Down
6 changes: 3 additions & 3 deletions routers/api/v1/repo/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -600,7 +600,7 @@ func MergePullRequest(ctx *context.APIContext, form auth.MergePullRequestForm) {
ctx.Status(200)
}

func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption) (*models.User, *models.Repository, *git.Repository, *git.PullRequestInfo, string, string) {
func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption) (*models.User, *models.Repository, *git.Repository, *git.CompareInfo, string, string) {
baseRepo := ctx.Repo.Repository

// Get compared branches information
Expand Down Expand Up @@ -712,9 +712,9 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption)
return nil, nil, nil, nil, "", ""
}

prInfo, err := headGitRepo.GetPullRequestInfo(models.RepoPath(baseRepo.Owner.Name, baseRepo.Name), baseBranch, headBranch)
prInfo, err := headGitRepo.GetCompareInfo(models.RepoPath(baseRepo.Owner.Name, baseRepo.Name), baseBranch, headBranch)
if err != nil {
ctx.Error(500, "GetPullRequestInfo", err)
ctx.Error(500, "GetCompareInfo", err)
return nil, nil, nil, nil, "", ""
}

Expand Down
59 changes: 4 additions & 55 deletions routers/repo/commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ import (
)

const (
tplCommits base.TplName = "repo/commits"
tplGraph base.TplName = "repo/graph"
tplDiff base.TplName = "repo/diff/page"
tplCommits base.TplName = "repo/commits"
tplGraph base.TplName = "repo/graph"
tplCommitPage base.TplName = "repo/commit_page"
)

// RefCommits render commits page
Expand Down Expand Up @@ -261,7 +261,7 @@ func Diff(ctx *context.Context) {
}
ctx.Data["RawPath"] = setting.AppSubURL + "/" + path.Join(userName, repoName, "raw", "commit", commitID)
ctx.Data["BranchName"], err = commit.GetBranchName()
ctx.HTML(200, tplDiff)
ctx.HTML(200, tplCommitPage)
}

// RawDiff dumps diff results of repository in given commit ID to io.Writer
Expand All @@ -276,54 +276,3 @@ func RawDiff(ctx *context.Context) {
return
}
}

// CompareDiff show different from one commit to another commit
func CompareDiff(ctx *context.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.NotFound("GetCommit", err)
return
}

diff, err := models.GetDiffRange(models.RepoPath(userName, repoName), beforeCommitID,
afterCommitID, setting.Git.MaxGitDiffLines,
setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles)
if err != nil {
ctx.NotFound("GetDiffRange", err)
return
}

commits, err := commit.CommitsBeforeUntil(beforeCommitID)
if err != nil {
ctx.ServerError("CommitsBeforeUntil", err)
return
}
commits = models.ValidateCommitsWithEmails(commits)
commits = models.ParseCommitsWithSignature(commits)
commits = models.ParseCommitsWithStatus(commits, ctx.Repo.Repository)

ctx.Data["CommitRepoLink"] = ctx.Repo.RepoLink
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"] = commit.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"] = setting.AppSubURL + "/" + path.Join(userName, repoName, "src", "commit", afterCommitID)
ctx.Data["BeforeSourcePath"] = setting.AppSubURL + "/" + path.Join(userName, repoName, "src", "commit", beforeCommitID)
ctx.Data["RawPath"] = setting.AppSubURL + "/" + path.Join(userName, repoName, "raw", "commit", afterCommitID)
ctx.Data["RequireHighlightJS"] = true
ctx.HTML(200, tplDiff)
}
Loading