Compare commits

..

No commits in common. 'eb62dea91e516e36e4c347667366b5aff5755867' and '4c7786b3b6e5bf8b5798da3ce387624d4da63f7c' have entirely different histories.

  1. 13
      CHANGELOG.md
  2. 13
      models/fixtures/repo_unit.yml
  3. 2
      modules/context/access_log.go
  4. 2
      modules/git/commit.go
  5. 2
      modules/repository/init.go
  6. 15
      routers/api/v1/repo/pull.go
  7. 11
      routers/web/repo/compare.go
  8. 16
      routers/web/repo/pull.go
  9. 2
      services/automerge/automerge.go
  10. 2
      services/forms/repo_form.go
  11. 37
      services/pull/check.go
  12. 8
      services/pull/merge.go
  13. 5
      services/repository/files/tree.go
  14. 15
      templates/base/footer_content.tmpl
  15. 21
      templates/base/head_navbar.tmpl
  16. 2
      templates/org/member/members.tmpl
  17. 2
      templates/repo/diff/box.tmpl
  18. 2
      templates/repo/issue/view_content/comments.tmpl
  19. 18
      templates/repo/issue/view_content/pull.tmpl
  20. 2
      tests/gitea-repositories-meta/user2/repo20.git/hooks/post-receive.d/gitea
  21. 2
      tests/gitea-repositories-meta/user2/repo20.git/hooks/pre-receive.d/gitea
  22. 2
      tests/gitea-repositories-meta/user2/repo20.git/hooks/update.d/gitea
  23. BIN
      tests/gitea-repositories-meta/user2/repo20.git/objects/07/0b2e783a6b3e521a23fdead377a3e41a04410d
  24. BIN
      tests/gitea-repositories-meta/user2/repo20.git/objects/79/adb592126eddce5f656f56db797910db025af0
  25. 1
      tests/gitea-repositories-meta/user2/repo20.git/objects/8b/abce967f21b9dfa6987f943b91093dac58a4f0
  26. BIN
      tests/gitea-repositories-meta/user2/repo20.git/objects/a4/202876cd8bbc3f38b7d99594edbe1bb7f97a6f
  27. BIN
      tests/gitea-repositories-meta/user2/repo20.git/objects/b0/246d5964a3630491bd06c756be46513e3d7035
  28. BIN
      tests/gitea-repositories-meta/user2/repo20.git/objects/b6/7e43a07d48243a5f670ace063acd5e13f719df
  29. 2
      tests/gitea-repositories-meta/user2/repo20.git/objects/c8/e31bc7688741a5287fcde4fbb8fc129ca07027
  30. 3
      tests/gitea-repositories-meta/user2/repo20.git/objects/cf/e3b3c1fd36fba04f9183287b106497e1afe986
  31. BIN
      tests/gitea-repositories-meta/user2/repo20.git/objects/ea/f5f7510320b6a327fb308379de2f94d8859a54
  32. 1
      tests/gitea-repositories-meta/user2/repo20.git/refs/heads/add-csv
  33. 1
      tests/gitea-repositories-meta/user2/repo20.git/refs/heads/remove-files-a
  34. 1
      tests/gitea-repositories-meta/user2/repo20.git/refs/heads/remove-files-b
  35. 78
      tests/integration/compare_test.go
  36. 1
      tokarchuk/templates/base/footer_content.tmpl
  37. 1
      tokarchuk/templates/base/head_navbar.tmpl
  38. 11
      web_src/js/components/PullRequestMergeForm.vue

@ -4,19 +4,6 @@ This changelog goes through all the changes that have been made in each release
without substantial changes to our git log; to see the highlights of what has without substantial changes to our git log; to see the highlights of what has
been added to each release, please refer to the [blog](https://blog.gitea.io). been added to each release, please refer to the [blog](https://blog.gitea.io).
## [1.18.5](https://github.com/go-gitea/gitea/releases/tag/v1.18.5) - 2023-02-21
* ENHANCEMENTS
* Hide 2FA status from other members in organization members list (#22999) (#23023)
* BUGFIXES
* Add force_merge to merge request and fix checking mergable (#23010) (#23032)
* Use `--message=%s` for git commit message (#23028) (#23029)
* Render access log template as text instead of HTML (#23013) (#23025)
* Fix the Manually Merged form (#23015) (#23017)
* Use beforeCommit instead of baseCommit (#22949) (#22996)
* Display attachments of review comment when comment content is blank (#23035) (#23046)
* Return empty url for submodule tree entries (#23043) (#23048)
## [1.18.4](https://github.com/go-gitea/gitea/releases/tag/1.18.4) - 2023-02-20 ## [1.18.4](https://github.com/go-gitea/gitea/releases/tag/1.18.4) - 2023-02-20
* SECURITY * SECURITY

@ -544,16 +544,3 @@
repo_id: 51 repo_id: 51
type: 2 type: 2
created_unix: 946684810 created_unix: 946684810
-
id: 80
repo_id: 31
type: 1
created_unix: 946684810
-
id: 81
repo_id: 31
type: 3
config: "{\"IgnoreWhitespaceConflicts\":false,\"AllowMerge\":true,\"AllowRebase\":true,\"AllowRebaseMerge\":true,\"AllowSquash\":true}"
created_unix: 946684810

@ -7,8 +7,8 @@ package context
import ( import (
"bytes" "bytes"
"context" "context"
"html/template"
"net/http" "net/http"
"text/template"
"time" "time"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"

@ -132,7 +132,7 @@ func CommitChangesWithArgs(repoPath string, args []CmdArg, opts CommitChangesOpt
if opts.Author != nil { if opts.Author != nil {
cmd.AddArguments(CmdArg(fmt.Sprintf("--author='%s <%s>'", opts.Author.Name, opts.Author.Email))) cmd.AddArguments(CmdArg(fmt.Sprintf("--author='%s <%s>'", opts.Author.Name, opts.Author.Email)))
} }
cmd.AddArguments(CmdArg("--message=" + opts.Message)) cmd.AddArguments("-m").AddDynamicArguments(opts.Message)
_, _, err := cmd.RunStdString(&RunOpts{Dir: repoPath}) _, _, err := cmd.RunStdString(&RunOpts{Dir: repoPath})
// No stderr but exit status 1 means nothing to commit. // No stderr but exit status 1 means nothing to commit.

@ -319,7 +319,7 @@ func initRepoCommit(ctx context.Context, tmpPath string, repo *repo_model.Reposi
cmd := git.NewCommand(ctx, cmd := git.NewCommand(ctx,
"commit", git.CmdArg(fmt.Sprintf("--author='%s <%s>'", sig.Name, sig.Email)), "commit", git.CmdArg(fmt.Sprintf("--author='%s <%s>'", sig.Name, sig.Email)),
"--message=Initial commit", "-m", "Initial commit",
) )
sign, keyID, signer, _ := asymkey_service.SignInitialCommit(ctx, tmpPath, u) sign, keyID, signer, _ := asymkey_service.SignInitialCommit(ctx, tmpPath, u)

@ -767,18 +767,11 @@ func MergePullRequest(ctx *context.APIContext) {
} }
} }
manuallyMerged := repo_model.MergeStyle(form.Do) == repo_model.MergeStyleManuallyMerged manuallMerge := repo_model.MergeStyle(form.Do) == repo_model.MergeStyleManuallyMerged
force := form.ForceMerge != nil && *form.ForceMerge
mergeCheckType := pull_service.MergeCheckTypeGeneral
if form.MergeWhenChecksSucceed {
mergeCheckType = pull_service.MergeCheckTypeAuto
}
if manuallyMerged {
mergeCheckType = pull_service.MergeCheckTypeManually
}
// start with merging by checking // start with merging by checking
if err := pull_service.CheckPullMergable(ctx, ctx.Doer, &ctx.Repo.Permission, pr, mergeCheckType, form.ForceMerge); err != nil { if err := pull_service.CheckPullMergable(ctx, ctx.Doer, &ctx.Repo.Permission, pr, manuallMerge, force); err != nil {
if errors.Is(err, pull_service.ErrIsClosed) { if errors.Is(err, pull_service.ErrIsClosed) {
ctx.NotFound() ctx.NotFound()
} else if errors.Is(err, pull_service.ErrUserNotAllowedToMerge) { } else if errors.Is(err, pull_service.ErrUserNotAllowedToMerge) {
@ -800,7 +793,7 @@ func MergePullRequest(ctx *context.APIContext) {
} }
// handle manually-merged mark // handle manually-merged mark
if manuallyMerged { if manuallMerge {
if err := pull_service.MergedManually(pr, ctx.Doer, ctx.Repo.GitRepo, form.MergeCommitID); err != nil { if err := pull_service.MergedManually(pr, ctx.Doer, ctx.Repo.GitRepo, form.MergeCommitID); err != nil {
if models.IsErrInvalidMergeStyle(err) { if models.IsErrInvalidMergeStyle(err) {
ctx.Error(http.StatusMethodNotAllowed, "Invalid merge style", fmt.Errorf("%s is not allowed an allowed merge style for this repository", repo_model.MergeStyle(form.Do))) ctx.Error(http.StatusMethodNotAllowed, "Invalid merge style", fmt.Errorf("%s is not allowed an allowed merge style for this repository", repo_model.MergeStyle(form.Do)))

@ -43,8 +43,8 @@ const (
) )
// setCompareContext sets context data. // setCompareContext sets context data.
func setCompareContext(ctx *context.Context, before, head *git.Commit, headOwner, headName string) { func setCompareContext(ctx *context.Context, base, head *git.Commit, headOwner, headName string) {
ctx.Data["BeforeCommit"] = before ctx.Data["BaseCommit"] = base
ctx.Data["HeadCommit"] = head ctx.Data["HeadCommit"] = head
ctx.Data["GetBlobByPathForCommit"] = func(commit *git.Commit, path string) *git.Blob { ctx.Data["GetBlobByPathForCommit"] = func(commit *git.Commit, path string) *git.Blob {
@ -59,7 +59,7 @@ func setCompareContext(ctx *context.Context, before, head *git.Commit, headOwner
return blob return blob
} }
setPathsCompareContext(ctx, before, head, headOwner, headName) setPathsCompareContext(ctx, base, head, headOwner, headName)
setImageCompareContext(ctx) setImageCompareContext(ctx)
setCsvCompareContext(ctx) setCsvCompareContext(ctx)
} }
@ -629,8 +629,9 @@ func PrepareCompareDiff(
} }
baseGitRepo := ctx.Repo.GitRepo baseGitRepo := ctx.Repo.GitRepo
baseCommitID := ci.CompareInfo.BaseCommitID
beforeCommit, err := baseGitRepo.GetCommit(beforeCommitID) baseCommit, err := baseGitRepo.GetCommit(baseCommitID)
if err != nil { if err != nil {
ctx.ServerError("GetCommit", err) ctx.ServerError("GetCommit", err)
return false return false
@ -667,7 +668,7 @@ func PrepareCompareDiff(
ctx.Data["Username"] = ci.HeadUser.Name ctx.Data["Username"] = ci.HeadUser.Name
ctx.Data["Reponame"] = ci.HeadRepo.Name ctx.Data["Reponame"] = ci.HeadRepo.Name
setCompareContext(ctx, beforeCommit, headCommit, ci.HeadUser.Name, repo.Name) setCompareContext(ctx, baseCommit, headCommit, ci.HeadUser.Name, repo.Name)
return false return false
} }

@ -912,19 +912,11 @@ func MergePullRequest(ctx *context.Context) {
pr := issue.PullRequest pr := issue.PullRequest
pr.Issue = issue pr.Issue = issue
pr.Issue.Repo = ctx.Repo.Repository pr.Issue.Repo = ctx.Repo.Repository
manualMerge := repo_model.MergeStyle(form.Do) == repo_model.MergeStyleManuallyMerged
manuallyMerged := repo_model.MergeStyle(form.Do) == repo_model.MergeStyleManuallyMerged forceMerge := form.ForceMerge != nil && *form.ForceMerge
mergeCheckType := pull_service.MergeCheckTypeGeneral
if form.MergeWhenChecksSucceed {
mergeCheckType = pull_service.MergeCheckTypeAuto
}
if manuallyMerged {
mergeCheckType = pull_service.MergeCheckTypeManually
}
// start with merging by checking // start with merging by checking
if err := pull_service.CheckPullMergable(ctx, ctx.Doer, &ctx.Repo.Permission, pr, mergeCheckType, form.ForceMerge); err != nil { if err := pull_service.CheckPullMergable(ctx, ctx.Doer, &ctx.Repo.Permission, pr, manualMerge, forceMerge); err != nil {
switch { switch {
case errors.Is(err, pull_service.ErrIsClosed): case errors.Is(err, pull_service.ErrIsClosed):
if issue.IsPull { if issue.IsPull {
@ -956,7 +948,7 @@ func MergePullRequest(ctx *context.Context) {
} }
// handle manually-merged mark // handle manually-merged mark
if manuallyMerged { if manualMerge {
if err := pull_service.MergedManually(pr, ctx.Doer, ctx.Repo.GitRepo, form.MergeCommitID); err != nil { if err := pull_service.MergedManually(pr, ctx.Doer, ctx.Repo.GitRepo, form.MergeCommitID); err != nil {
switch { switch {

@ -231,7 +231,7 @@ func handlePull(pullID int64, sha string) {
return return
} }
if err := pull_service.CheckPullMergable(ctx, doer, &perm, pr, pull_service.MergeCheckTypeGeneral, false); err != nil { if err := pull_service.CheckPullMergable(ctx, doer, &perm, pr, false, false); err != nil {
if errors.Is(pull_service.ErrUserNotAllowedToMerge, err) { if errors.Is(pull_service.ErrUserNotAllowedToMerge, err) {
log.Info("%-v was scheduled to automerge by an unauthorized user", pr) log.Info("%-v was scheduled to automerge by an unauthorized user", pr)
return return

@ -597,7 +597,7 @@ type MergePullRequestForm struct {
MergeMessageField string MergeMessageField string
MergeCommitID string // only used for manually-merged MergeCommitID string // only used for manually-merged
HeadCommitID string `json:"head_commit_id,omitempty"` HeadCommitID string `json:"head_commit_id,omitempty"`
ForceMerge bool `json:"force_merge,omitempty"` ForceMerge *bool `json:"force_merge,omitempty"`
MergeWhenChecksSucceed bool `json:"merge_when_checks_succeed,omitempty"` MergeWhenChecksSucceed bool `json:"merge_when_checks_succeed,omitempty"`
DeleteBranchAfterMerge bool `json:"delete_branch_after_merge,omitempty"` DeleteBranchAfterMerge bool `json:"delete_branch_after_merge,omitempty"`
} }

@ -59,16 +59,8 @@ func AddToTaskQueue(pr *issues_model.PullRequest) {
} }
} }
type MergeCheckType int
const (
MergeCheckTypeGeneral MergeCheckType = iota // general merge checks for "merge", "rebase", "squash", etc
MergeCheckTypeManually // Manually Merged button (mark a PR as merged manually)
MergeCheckTypeAuto // Auto Merge (Scheduled Merge) After Checks Succeed
)
// CheckPullMergable check if the pull mergable based on all conditions (branch protection, merge options, ...) // CheckPullMergable check if the pull mergable based on all conditions (branch protection, merge options, ...)
func CheckPullMergable(stdCtx context.Context, doer *user_model.User, perm *access_model.Permission, pr *issues_model.PullRequest, mergeCheckType MergeCheckType, adminSkipProtectionCheck bool) error { func CheckPullMergable(stdCtx context.Context, doer *user_model.User, perm *access_model.Permission, pr *issues_model.PullRequest, manuallMerge, force bool) error {
return db.WithTx(func(ctx context.Context) error { return db.WithTx(func(ctx context.Context) error {
if pr.HasMerged { if pr.HasMerged {
return ErrHasMerged return ErrHasMerged
@ -88,8 +80,8 @@ func CheckPullMergable(stdCtx context.Context, doer *user_model.User, perm *acce
return ErrUserNotAllowedToMerge return ErrUserNotAllowedToMerge
} }
if mergeCheckType == MergeCheckTypeManually { if manuallMerge {
// if doer is doing "manually merge" (mark as merged manually), do not check anything // don't check rules to "auto merge", doer is going to mark this pull as merged manually
return nil return nil
} }
@ -111,25 +103,14 @@ func CheckPullMergable(stdCtx context.Context, doer *user_model.User, perm *acce
return err return err
} }
// Now the branch protection check failed, check whether the failure could be skipped (skip by setting err = nil) if !force {
return err
// * when doing Auto Merge (Scheduled Merge After Checks Succeed), skip the branch protection check
if mergeCheckType == MergeCheckTypeAuto {
err = nil
}
// * if the doer is admin, they could skip the branch protection check
if adminSkipProtectionCheck {
if isRepoAdmin, errCheckAdmin := access_model.IsUserRepoAdmin(ctx, pr.BaseRepo, doer); errCheckAdmin != nil {
log.Error("Unable to check if %-v is a repo admin in %-v: %v", doer, pr.BaseRepo, errCheckAdmin)
return errCheckAdmin
} else if isRepoAdmin {
err = nil // repo admin can skip the check, so clear the error
}
} }
// If there is still a branch protection check error, return it if isRepoAdmin, err2 := access_model.IsUserRepoAdmin(ctx, pr.BaseRepo, doer); err2 != nil {
if err != nil { log.Error("Unable to check if %-v is a repo admin in %-v: %v", doer, pr.BaseRepo, err2)
return err2
} else if !isRepoAdmin {
return err return err
} }
} }

@ -516,7 +516,7 @@ func rawMerge(ctx context.Context, pr *issues_model.PullRequest, doer *user_mode
} }
sig := pr.Issue.Poster.NewGitSig() sig := pr.Issue.Poster.NewGitSig()
if signArg == "" { if signArg == "" {
if err := git.NewCommand(ctx, "commit", git.CmdArg(fmt.Sprintf("--author='%s <%s>'", sig.Name, sig.Email)), git.CmdArg("--message="+message)). if err := git.NewCommand(ctx, "commit", git.CmdArg(fmt.Sprintf("--author='%s <%s>'", sig.Name, sig.Email)), "-m").AddDynamicArguments(message).
Run(&git.RunOpts{ Run(&git.RunOpts{
Env: env, Env: env,
Dir: tmpBasePath, Dir: tmpBasePath,
@ -534,7 +534,7 @@ func rawMerge(ctx context.Context, pr *issues_model.PullRequest, doer *user_mode
if err := git.NewCommand(ctx, "commit"). if err := git.NewCommand(ctx, "commit").
AddArguments(signArg). AddArguments(signArg).
AddArguments(git.CmdArg(fmt.Sprintf("--author='%s <%s>'", sig.Name, sig.Email))). AddArguments(git.CmdArg(fmt.Sprintf("--author='%s <%s>'", sig.Name, sig.Email))).
AddArguments(git.CmdArg("--message=" + message)). AddArguments("-m").AddDynamicArguments(message).
Run(&git.RunOpts{ Run(&git.RunOpts{
Env: env, Env: env,
Dir: tmpBasePath, Dir: tmpBasePath,
@ -644,7 +644,7 @@ func rawMerge(ctx context.Context, pr *issues_model.PullRequest, doer *user_mode
func commitAndSignNoAuthor(ctx context.Context, pr *issues_model.PullRequest, message string, signArg git.CmdArg, tmpBasePath string, env []string) error { func commitAndSignNoAuthor(ctx context.Context, pr *issues_model.PullRequest, message string, signArg git.CmdArg, tmpBasePath string, env []string) error {
var outbuf, errbuf strings.Builder var outbuf, errbuf strings.Builder
if signArg == "" { if signArg == "" {
if err := git.NewCommand(ctx, "commit", git.CmdArg("--message="+message)). if err := git.NewCommand(ctx, "commit", "-m").AddDynamicArguments(message).
Run(&git.RunOpts{ Run(&git.RunOpts{
Env: env, Env: env,
Dir: tmpBasePath, Dir: tmpBasePath,
@ -655,7 +655,7 @@ func commitAndSignNoAuthor(ctx context.Context, pr *issues_model.PullRequest, me
return fmt.Errorf("git commit [%s:%s -> %s:%s]: %w\n%s\n%s", pr.HeadRepo.FullName(), pr.HeadBranch, pr.BaseRepo.FullName(), pr.BaseBranch, err, outbuf.String(), errbuf.String()) return fmt.Errorf("git commit [%s:%s -> %s:%s]: %w\n%s\n%s", pr.HeadRepo.FullName(), pr.HeadBranch, pr.BaseRepo.FullName(), pr.BaseBranch, err, outbuf.String(), errbuf.String())
} }
} else { } else {
if err := git.NewCommand(ctx, "commit").AddArguments(signArg).AddArguments(git.CmdArg("--message=" + message)). if err := git.NewCommand(ctx, "commit").AddArguments(signArg).AddArguments("-m").AddDynamicArguments(message).
Run(&git.RunOpts{ Run(&git.RunOpts{
Env: env, Env: env,
Dir: tmpBasePath, Dir: tmpBasePath,

@ -86,11 +86,6 @@ func GetTreeBySHA(ctx context.Context, repo *repo_model.Repository, gitRepo *git
if entries[e].IsDir() { if entries[e].IsDir() {
copy(treeURL[copyPos:], entries[e].ID.String()) copy(treeURL[copyPos:], entries[e].ID.String())
tree.Entries[i].URL = string(treeURL) tree.Entries[i].URL = string(treeURL)
} else if entries[e].IsSubModule() {
// In Github Rest API Version=2022-11-28, if a tree entry is a submodule,
// its url will be returned as an empty string.
// So the URL will be set to "" here.
tree.Entries[i].URL = ""
} else { } else {
copy(blobURL[copyPos:], entries[e].ID.String()) copy(blobURL[copyPos:], entries[e].ID.String())
tree.Entries[i].URL = string(blobURL) tree.Entries[i].URL = string(blobURL)

@ -1,7 +1,19 @@
<footer> <footer>
<div class="ui container"> <div class="ui container">
<div class="ui left"> <div class="ui left">
{{.locale.Tr "powered_by" "Nikita Tokarchuk and Gitea"}} <a target="_blank" rel="noopener noreferrer" href="https://gitea.io">{{.locale.Tr "powered_by" "Gitea"}}</a>
{{if (or .ShowFooterVersion .PageIsAdmin)}}
{{.locale.Tr "version"}}:
{{if .IsAdmin}}
<a href="{{AppSubUrl}}/admin/config">{{AppVer}}</a>
{{else}}
{{AppVer}}
{{end}}
{{end}}
{{if and .TemplateLoadTimes ShowFooterTemplateLoadTime}}
{{.locale.Tr "page"}}: <strong>{{LoadTimes .PageStartTime}}</strong>
{{.locale.Tr "template"}}{{if .TemplateName}} {{.TemplateName}}{{end}}: <strong>{{call .TemplateLoadTimes}}</strong>
{{end}}
</div> </div>
<div class="ui right links"> <div class="ui right links">
{{if .ShowFooterBranding}} {{if .ShowFooterBranding}}
@ -17,6 +29,7 @@
</div> </div>
</div> </div>
<a href="{{AssetUrlPrefix}}/js/licenses.txt">{{.locale.Tr "licenses"}}</a> <a href="{{AssetUrlPrefix}}/js/licenses.txt">{{.locale.Tr "licenses"}}</a>
{{if .EnableSwagger}}<a href="{{AppSubUrl}}/api/swagger">API</a>{{end}}
{{template "custom/extra_links_footer" .}} {{template "custom/extra_links_footer" .}}
</div> </div>
</div> </div>

@ -1,12 +1,22 @@
<div class="ui container" style="padding-top: 4px;" id="navbar"> <div class="ui container" id="navbar">
{{$notificationUnreadCount := 0}} {{$notificationUnreadCount := 0}}
{{if .IsSigned}} {{if .IsSigned}}
{{if .NotificationUnreadCount}}{{$notificationUnreadCount = call .NotificationUnreadCount}}{{end}} {{if .NotificationUnreadCount}}{{$notificationUnreadCount = call .NotificationUnreadCount}}{{end}}
{{end}} {{end}}
<div class="left item brand" style="justify-content: space-between;padding-top: 1px;margin-right: 0px!important;"> <div class="item brand" style="justify-content: space-between;">
<a href="{{AppSubUrl}}/" aria-label="{{if .IsSigned}}{{.locale.Tr "dashboard"}}{{else}}{{.locale.Tr "home"}}{{end}}"> <a href="{{AppSubUrl}}/" aria-label="{{if .IsSigned}}{{.locale.Tr "dashboard"}}{{else}}{{.locale.Tr "home"}}{{end}}">
<span style="font-size: 2em;color: #046380;">code</span>.tokarch.uk <img width="30" height="30" src="{{AssetUrlPrefix}}/img/logo.svg" alt="{{.locale.Tr "logo"}}" aria-hidden="true">
</a> </a>
{{if .IsSigned}}
<a href="{{AppSubUrl}}/notifications" class="tooltip mobile-only" data-content='{{.locale.Tr "notifications"}}'>
<span class="text black">
<span class="fitted">{{svg "octicon-bell"}}</span>
<span class="ui red label mini{{if not $notificationUnreadCount}} hidden{{end}} notification_count">
{{$notificationUnreadCount}}
</span>
</span>
</a>
{{end}}
<div class="ui basic icon button mobile-only" id="navbar-expand-toggle"> <div class="ui basic icon button mobile-only" id="navbar-expand-toggle">
<i class="sidebar icon"></i> <i class="sidebar icon"></i>
</div> </div>
@ -82,7 +92,7 @@
<a class="stopwatch-link df ac" href="{{.ActiveStopwatch.IssueLink}}"> <a class="stopwatch-link df ac" href="{{.ActiveStopwatch.IssueLink}}">
{{svg "octicon-issue-opened" 16 "mr-3"}} {{svg "octicon-issue-opened" 16 "mr-3"}}
<span class="stopwatch-issue">{{.ActiveStopwatch.RepoSlug}}#{{.ActiveStopwatch.IssueIndex}}</span> <span class="stopwatch-issue">{{.ActiveStopwatch.RepoSlug}}#{{.ActiveStopwatch.IssueIndex}}</span>
<span class="ui label blue stopwatch-time my-0 mx-4" data-seconds="{{.ActiveStopwatch.Seconds}}"> <span class="ui primary label stopwatch-time my-0 mx-4" data-seconds="{{.ActiveStopwatch.Seconds}}">
{{if .ActiveStopwatch}}{{Sec2Time .ActiveStopwatch.Seconds}}{{end}} {{if .ActiveStopwatch}}{{Sec2Time .ActiveStopwatch.Seconds}}{{end}}
</span> </span>
</a> </a>
@ -111,9 +121,6 @@
<a href="{{AppSubUrl}}/notifications" class="item tooltip not-mobile" data-content="{{.locale.Tr "notifications"}}" aria-label="{{.locale.Tr "notifications"}}"> <a href="{{AppSubUrl}}/notifications" class="item tooltip not-mobile" data-content="{{.locale.Tr "notifications"}}" aria-label="{{.locale.Tr "notifications"}}">
<span class="text"> <span class="text">
<span class="fitted">{{svg "octicon-bell"}}</span> <span class="fitted">{{svg "octicon-bell"}}</span>
<span class="sr-mobile-only">{{.i18n.Tr "notifications"}}</span>
{{$notificationUnreadCount := 0}}
{{if .NotificationUnreadCount}}{{$notificationUnreadCount = call .NotificationUnreadCount}}{{end}}
<span class="ui red label {{if not $notificationUnreadCount}}hidden{{end}} notification_count"> <span class="ui red label {{if not $notificationUnreadCount}}hidden{{end}} notification_count">
{{$notificationUnreadCount}} {{$notificationUnreadCount}}
</span> </span>

@ -39,7 +39,6 @@
</div> </div>
</div> </div>
<div class="ui two wide column center"> <div class="ui two wide column center">
{{if $.IsOrganizationOwner}}
<div class="meta"> <div class="meta">
{{$.locale.Tr "admin.users.2fa"}} {{$.locale.Tr "admin.users.2fa"}}
</div> </div>
@ -52,7 +51,6 @@
{{end}} {{end}}
</strong> </strong>
</div> </div>
{{end}}
</div> </div>
{{end}} {{end}}
<div class="ui three wide column"> <div class="ui three wide column">

@ -71,7 +71,7 @@
<div id="diff-file-boxes" class="sixteen wide column"> <div id="diff-file-boxes" class="sixteen wide column">
{{range $i, $file := .Diff.Files}} {{range $i, $file := .Diff.Files}}
{{/*notice: the index of Diff.Files should not be used for element ID, because the index will be restarted from 0 when doing load-more for PRs with a lot of files*/}} {{/*notice: the index of Diff.Files should not be used for element ID, because the index will be restarted from 0 when doing load-more for PRs with a lot of files*/}}
{{$blobBase := call $.GetBlobByPathForCommit $.BeforeCommit $file.OldName}} {{$blobBase := call $.GetBlobByPathForCommit $.BaseCommit $file.OldName}}
{{$blobHead := call $.GetBlobByPathForCommit $.HeadCommit $file.Name}} {{$blobHead := call $.GetBlobByPathForCommit $.HeadCommit $file.Name}}
{{$isImage := or (call $.IsBlobAnImage $blobBase) (call $.IsBlobAnImage $blobHead)}} {{$isImage := or (call $.IsBlobAnImage $blobBase) (call $.IsBlobAnImage $blobHead)}}
{{$isCsv := (call $.IsCsvFile $file)}} {{$isCsv := (call $.IsCsvFile $file)}}

@ -399,7 +399,7 @@
{{end}} {{end}}
</span> </span>
</div> </div>
{{if or .Content .Attachments}} {{if .Content}}
<div class="timeline-item comment" id="{{.HashTag}}"> <div class="timeline-item comment" id="{{.HashTag}}">
<div class="content comment-container"> <div class="content comment-container">
<div class="ui top attached header comment-header df ac sb"> <div class="ui top attached header comment-header df ac sb">

@ -129,7 +129,6 @@
<div class="content"> <div class="content">
{{template "repo/pulls/status" .}} {{template "repo/pulls/status" .}}
{{$canAutoMerge := false}} {{$canAutoMerge := false}}
{{$showGeneralMergeForm := false}}
<div class="ui attached merge-section segment {{if not $.LatestCommitStatus}}no-header{{end}}"> <div class="ui attached merge-section segment {{if not $.LatestCommitStatus}}no-header{{end}}">
{{if .Issue.PullRequest.HasMerged}} {{if .Issue.PullRequest.HasMerged}}
<div class="item text"> <div class="item text">
@ -352,7 +351,6 @@
'textAutoMergeButtonWhenSucceed': {{$.locale.Tr "repo.pulls.auto_merge_button_when_succeed"}}, 'textAutoMergeButtonWhenSucceed': {{$.locale.Tr "repo.pulls.auto_merge_button_when_succeed"}},
'textAutoMergeWhenSucceed': {{$.locale.Tr "repo.pulls.auto_merge_when_succeed"}}, 'textAutoMergeWhenSucceed': {{$.locale.Tr "repo.pulls.auto_merge_when_succeed"}},
'textAutoMergeCancelSchedule': {{$.locale.Tr "repo.pulls.auto_merge_cancel_schedule"}}, 'textAutoMergeCancelSchedule': {{$.locale.Tr "repo.pulls.auto_merge_cancel_schedule"}},
'textMergeCommitId': {{$.locale.Tr "repo.pulls.merge_commit_id"}},
'canMergeNow': {{$canMergeNow}}, 'canMergeNow': {{$canMergeNow}},
'allOverridableChecksOk': {{not $notAllOverridableChecksOk}}, 'allOverridableChecksOk': {{not $notAllOverridableChecksOk}},
@ -412,7 +410,6 @@
})(); })();
</script> </script>
{{$showGeneralMergeForm = true}}
<div id="pull-request-merge-form"></div> <div id="pull-request-merge-form"></div>
{{if .ShowMergeInstructions}} {{if .ShowMergeInstructions}}
@ -490,11 +487,11 @@
{{$.locale.Tr "repo.pulls.cannot_auto_merge_helper"}} {{$.locale.Tr "repo.pulls.cannot_auto_merge_helper"}}
</div> </div>
{{end}} {{end}}
{{end}}{{/* end if: pull request status */}} {{end}}
{{if and $.StillCanManualMerge (not $showGeneralMergeForm)}} {{if $.StillCanManualMerge}}
<div class="ui divider"></div> <div class="ui divider"></div>
<div class="ui form"> <div class="ui form manually-merged-fields" style="display: none">
<form action="{{.Link}}/merge" method="post"> <form action="{{.Link}}/merge" method="post">
{{.CsrfTokenHtml}} {{.CsrfTokenHtml}}
<div class="field"> <div class="field">
@ -503,8 +500,17 @@
<button class="ui red button" type="submit" name="do" value="manually-merged"> <button class="ui red button" type="submit" name="do" value="manually-merged">
{{$.locale.Tr "repo.pulls.merge_manually"}} {{$.locale.Tr "repo.pulls.merge_manually"}}
</button> </button>
<button class="ui button merge-cancel">
{{$.locale.Tr "cancel"}}
</button>
</form> </form>
</div> </div>
<div class="ui red buttons merge-button">
<button class="ui button" data-do="manually-merged">
{{$.locale.Tr "repo.pulls.merge_manually"}}
</button>
</div>
{{end}} {{end}}
</div> </div>
</div> </div>

@ -1,2 +1,2 @@
#!/usr/bin/env bash #!/usr/bin/env bash
"$GITEA_ROOT/gitea" hook --config="$GITEA_ROOT/$GITEA_CONF" post-receive "/home/tris/Projects/go/src/code.gitea.io/gitea/gitea" hook --config='/home/tris/Projects/go/src/code.gitea.io/gitea/custom/conf/app.ini' post-receive

@ -1,2 +1,2 @@
#!/usr/bin/env bash #!/usr/bin/env bash
"$GITEA_ROOT/gitea" hook --config="$GITEA_ROOT/$GITEA_CONF" pre-receive "/home/tris/Projects/go/src/code.gitea.io/gitea/gitea" hook --config='/home/tris/Projects/go/src/code.gitea.io/gitea/custom/conf/app.ini' pre-receive

@ -1,2 +1,2 @@
#!/usr/bin/env bash #!/usr/bin/env bash
"$GITEA_ROOT/gitea" hook --config="$GITEA_ROOT/$GITEA_CONF" update $1 $2 $3 "/home/tris/Projects/go/src/code.gitea.io/gitea/gitea" hook --config='/home/tris/Projects/go/src/code.gitea.io/gitea/custom/conf/app.ini' update $1 $2 $3

@ -1 +0,0 @@
x•ŽAnÃ0 sÖ+ø<EFBFBD>”l‘ Ð[_A‹TkIJC>ø÷Õz[,f1›·Zç!øKÛÍ€“è<EFBFBD>L5[,©DÒ‰'<EFBFBD>:aˆRнe·µÁDlã È:^C<EFBFBD>g”lHƒd<EFBFBD>æ‡Â>iqr´ßm‡ïs1ø‚ÛK<EFBFBD>º­m=?Uæå3oõž˜®<EFBFBD>òð<EFBFBD>Ñõ¶¿köß<EFBFBD>{ª‚@wÔʼ˜û<EFBFBD>E]

@ -1,2 +0,0 @@
x•ÎA
Â0@Q×9Å\@™NÒ&wž"“L´Ø4Ò¦‚·×+¸ýðàÇZÊØ€ˆvm<EFBFBD>`ÉÙ!&ÇuÖŽmò¾÷FKÇl³·aÈê8t¨]¢l;ÆÀHè}g´<EFBFBD>9'2{<EFBFBD>*líQ¸}&<EFBFBD>+Ÿi+unóv¾—0N‡XË ºÁŽ,!Â{Dõ«¿»&ÿ:uI š¬ âú†<N¢¾¨qEo

@ -1,3 +0,0 @@
x•ŽAnÂ0EYűs<EFBFBD>=v2FB v=D5¶';U<EFBFBD>Tâöř
Ýţ§÷ôóZ묀ş‰€%›P(z“—ŁźŠpńDě%8¶!8[Ě/oŇrďR¦1FępŔHS.¦”┞3÷$’á]ëßďEŕ—gŮëÚ´í×{ĺy9ĺµ~<EFBFBD>{ ĎŽv°ÖôµżSůŻgn˛<EFBFBD>
¨Ľô”_Ŕ­Ŕ2·çĎc6tuI‚

@ -1 +0,0 @@
c8e31bc7688741a5287fcde4fbb8fc129ca07027

@ -5,7 +5,6 @@
package integration package integration
import ( import (
"fmt"
"net/http" "net/http"
"strings" "strings"
"testing" "testing"
@ -42,80 +41,3 @@ func TestCompareDefault(t *testing.T) {
selection := htmlDoc.doc.Find(".choose.branch .filter.dropdown") selection := htmlDoc.doc.Find(".choose.branch .filter.dropdown")
assert.Lenf(t, selection.Nodes, 2, "The template has changed") assert.Lenf(t, selection.Nodes, 2, "The template has changed")
} }
// Ensure the comparison matches what we expect
func inspectCompare(t *testing.T, htmlDoc *HTMLDoc, diffCount int, diffChanges []string) {
selection := htmlDoc.doc.Find("#diff-file-boxes").Children()
assert.Lenf(t, selection.Nodes, diffCount, "Expected %v diffed files, found: %v", diffCount, len(selection.Nodes))
for _, diffChange := range diffChanges {
selection = htmlDoc.doc.Find(fmt.Sprintf("[data-new-filename=\"%s\"]", diffChange))
assert.Lenf(t, selection.Nodes, 1, "Expected 1 match for [data-new-filename=\"%s\"], found: %v", diffChange, len(selection.Nodes))
}
}
// Git commit graph for repo20
// * 8babce9 (origin/remove-files-b) Add a dummy file
// * b67e43a Delete test.csv and link_hi
// | * cfe3b3c (origin/remove-files-a) Delete test.csv and link_hi
// |/
// * c8e31bc (origin/add-csv) Add test csv file
// * 808038d (HEAD -> master, origin/master, origin/HEAD) Added test links
func TestCompareBranches(t *testing.T) {
defer tests.PrepareTestEnv(t)()
session := loginUser(t, "user2")
// Inderect compare remove-files-b (head) with add-csv (base) branch
//
// 'link_hi' and 'test.csv' are deleted, 'test.txt' is added
req := NewRequest(t, "GET", "/user2/repo20/compare/add-csv...remove-files-b")
resp := session.MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body)
diffCount := 3
diffChanges := []string{"link_hi", "test.csv", "test.txt"}
inspectCompare(t, htmlDoc, diffCount, diffChanges)
// Inderect compare remove-files-b (head) with remove-files-a (base) branch
//
// 'link_hi' and 'test.csv' are deleted, 'test.txt' is added
req = NewRequest(t, "GET", "/user2/repo20/compare/remove-files-a...remove-files-b")
resp = session.MakeRequest(t, req, http.StatusOK)
htmlDoc = NewHTMLParser(t, resp.Body)
diffCount = 3
diffChanges = []string{"link_hi", "test.csv", "test.txt"}
inspectCompare(t, htmlDoc, diffCount, diffChanges)
// Inderect compare remove-files-a (head) with remove-files-b (base) branch
//
// 'link_hi' and 'test.csv' are deleted
req = NewRequest(t, "GET", "/user2/repo20/compare/remove-files-b...remove-files-a")
resp = session.MakeRequest(t, req, http.StatusOK)
htmlDoc = NewHTMLParser(t, resp.Body)
diffCount = 2
diffChanges = []string{"link_hi", "test.csv"}
inspectCompare(t, htmlDoc, diffCount, diffChanges)
// Direct compare remove-files-b (head) with remove-files-a (base) branch
//
// 'test.txt' is deleted
req = NewRequest(t, "GET", "/user2/repo20/compare/remove-files-b..remove-files-a")
resp = session.MakeRequest(t, req, http.StatusOK)
htmlDoc = NewHTMLParser(t, resp.Body)
diffCount = 1
diffChanges = []string{"test.txt"}
inspectCompare(t, htmlDoc, diffCount, diffChanges)
}

@ -1 +0,0 @@
../../../templates/base/footer_content.tmpl

@ -1 +0,0 @@
../../../templates/base/head_navbar.tmpl

@ -18,7 +18,6 @@
<input type="hidden" name="_csrf" :value="csrfToken"> <input type="hidden" name="_csrf" :value="csrfToken">
<input type="hidden" name="head_commit_id" v-model="mergeForm.pullHeadCommitID"> <input type="hidden" name="head_commit_id" v-model="mergeForm.pullHeadCommitID">
<input type="hidden" name="merge_when_checks_succeed" v-model="autoMergeWhenSucceed"> <input type="hidden" name="merge_when_checks_succeed" v-model="autoMergeWhenSucceed">
<input type="hidden" name="force_merge" v-model="forceMerge">
<template v-if="!mergeStyleDetail.hideMergeMessageTexts"> <template v-if="!mergeStyleDetail.hideMergeMessageTexts">
<div class="field"> <div class="field">
@ -29,10 +28,6 @@
</div> </div>
</template> </template>
<div class="field" v-if="mergeStyle === 'manually-merged'">
<input type="text" name="merge_commit_id" :placeholder="mergeForm.textMergeCommitId">
</div>
<button class="ui button" :class="mergeButtonStyleClass" type="submit" name="do" :value="mergeStyle"> <button class="ui button" :class="mergeButtonStyleClass" type="submit" name="do" :value="mergeStyle">
{{ mergeStyleDetail.textDoMerge }} {{ mergeStyleDetail.textDoMerge }}
<template v-if="autoMergeWhenSucceed"> <template v-if="autoMergeWhenSucceed">
@ -128,7 +123,6 @@ export default {
textDoMerge: '', textDoMerge: '',
mergeTitleFieldText: '', mergeTitleFieldText: '',
mergeMessageFieldText: '', mergeMessageFieldText: '',
hideAutoMerge: false,
}, },
mergeStyleAllowedCount: 0, mergeStyleAllowedCount: 0,
@ -140,10 +134,7 @@ export default {
mergeButtonStyleClass() { mergeButtonStyleClass() {
if (this.mergeForm.allOverridableChecksOk) return 'green'; if (this.mergeForm.allOverridableChecksOk) return 'green';
return this.autoMergeWhenSucceed ? 'blue' : 'red'; return this.autoMergeWhenSucceed ? 'blue' : 'red';
}, }
forceMerge() {
return this.mergeForm.canMergeNow && !this.mergeForm.allOverridableChecksOk;
},
}, },
watch: { watch: {

Loading…
Cancel
Save