mirror of
https://github.com/go-gitea/gitea.git
synced 2025-07-13 00:01:02 -04:00
Compare commits
No commits in common. "93e907de4173a64263b024293ac867f8111d4c40" and "426c0ad14c5edc6b7afdf7386d71889732ca11ac" have entirely different histories.
93e907de41
...
426c0ad14c
@ -1087,9 +1087,6 @@ func (ctx *Context) IssueTemplatesErrorsFromDefaultBranch() ([]*api.IssueTemplat
|
||||
if it, err := template.UnmarshalFromEntry(entry, dirName); err != nil {
|
||||
invalidFiles[fullName] = err
|
||||
} else {
|
||||
if !strings.HasPrefix(it.Ref, "refs/") { // Assume that the ref intended is always a branch - for tags users should use refs/tags/<ref>
|
||||
it.Ref = git.BranchPrefix + it.Ref
|
||||
}
|
||||
issueTemplates = append(issueTemplates, it)
|
||||
}
|
||||
}
|
||||
|
@ -100,9 +100,6 @@ func RefURL(repoURL, ref string) string {
|
||||
return repoURL + "/src/branch/" + refName
|
||||
case strings.HasPrefix(ref, TagPrefix):
|
||||
return repoURL + "/src/tag/" + refName
|
||||
case !IsValidSHAPattern(ref):
|
||||
// assume they mean a branch
|
||||
return repoURL + "/src/branch/" + refName
|
||||
default:
|
||||
return repoURL + "/src/commit/" + refName
|
||||
}
|
||||
|
@ -110,6 +110,32 @@ func (q *ChannelQueue) Flush(timeout time.Duration) error {
|
||||
return q.FlushWithContext(ctx)
|
||||
}
|
||||
|
||||
// FlushWithContext is very similar to CleanUp but it will return as soon as the dataChan is empty
|
||||
func (q *ChannelQueue) FlushWithContext(ctx context.Context) error {
|
||||
log.Trace("ChannelQueue: %d Flush", q.qid)
|
||||
paused, _ := q.IsPausedIsResumed()
|
||||
for {
|
||||
select {
|
||||
case <-paused:
|
||||
return nil
|
||||
case data, ok := <-q.dataChan:
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
if unhandled := q.handle(data); unhandled != nil {
|
||||
log.Error("Unhandled Data whilst flushing queue %d", q.qid)
|
||||
}
|
||||
atomic.AddInt64(&q.numInQueue, -1)
|
||||
case <-q.baseCtx.Done():
|
||||
return q.baseCtx.Err()
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Shutdown processing from this queue
|
||||
func (q *ChannelQueue) Shutdown() {
|
||||
q.lock.Lock()
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"fmt"
|
||||
"runtime/pprof"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/container"
|
||||
@ -167,6 +168,35 @@ func (q *ChannelUniqueQueue) Flush(timeout time.Duration) error {
|
||||
return q.FlushWithContext(ctx)
|
||||
}
|
||||
|
||||
// FlushWithContext is very similar to CleanUp but it will return as soon as the dataChan is empty
|
||||
func (q *ChannelUniqueQueue) FlushWithContext(ctx context.Context) error {
|
||||
log.Trace("ChannelUniqueQueue: %d Flush", q.qid)
|
||||
paused, _ := q.IsPausedIsResumed()
|
||||
for {
|
||||
select {
|
||||
case <-paused:
|
||||
return nil
|
||||
default:
|
||||
}
|
||||
select {
|
||||
case data, ok := <-q.dataChan:
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
if unhandled := q.handle(data); unhandled != nil {
|
||||
log.Error("Unhandled Data whilst flushing queue %d", q.qid)
|
||||
}
|
||||
atomic.AddInt64(&q.numInQueue, -1)
|
||||
case <-q.baseCtx.Done():
|
||||
return q.baseCtx.Err()
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Shutdown processing from this queue
|
||||
func (q *ChannelUniqueQueue) Shutdown() {
|
||||
log.Trace("ChannelUniqueQueue: %s Shutting down", q.name)
|
||||
|
@ -464,43 +464,13 @@ func (p *WorkerPool) IsEmpty() bool {
|
||||
return atomic.LoadInt64(&p.numInQueue) == 0
|
||||
}
|
||||
|
||||
// contextError returns either ctx.Done(), the base context's error or nil
|
||||
func (p *WorkerPool) contextError(ctx context.Context) error {
|
||||
select {
|
||||
case <-p.baseCtx.Done():
|
||||
return p.baseCtx.Err()
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// FlushWithContext is very similar to CleanUp but it will return as soon as the dataChan is empty
|
||||
// NB: The worker will not be registered with the manager.
|
||||
func (p *WorkerPool) FlushWithContext(ctx context.Context) error {
|
||||
log.Trace("WorkerPool: %d Flush", p.qid)
|
||||
paused, _ := p.IsPausedIsResumed()
|
||||
for {
|
||||
// Because select will return any case that is satisified at random we precheck here before looking at dataChan.
|
||||
select {
|
||||
case <-paused:
|
||||
// Ensure that even if paused that the cancelled error is still sent
|
||||
return p.contextError(ctx)
|
||||
case <-p.baseCtx.Done():
|
||||
return p.baseCtx.Err()
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
select {
|
||||
case <-paused:
|
||||
return p.contextError(ctx)
|
||||
case data, ok := <-p.dataChan:
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
case data := <-p.dataChan:
|
||||
if unhandled := p.handle(data); unhandled != nil {
|
||||
log.Error("Unhandled Data whilst flushing queue %d", p.qid)
|
||||
}
|
||||
@ -526,7 +496,6 @@ func (p *WorkerPool) doWork(ctx context.Context) {
|
||||
paused, _ := p.IsPausedIsResumed()
|
||||
data := make([]Data, 0, p.batchLength)
|
||||
for {
|
||||
// Because select will return any case that is satisified at random we precheck here before looking at dataChan.
|
||||
select {
|
||||
case <-paused:
|
||||
log.Trace("Worker for Queue %d Pausing", p.qid)
|
||||
@ -547,19 +516,8 @@ func (p *WorkerPool) doWork(ctx context.Context) {
|
||||
log.Trace("Worker shutting down")
|
||||
return
|
||||
}
|
||||
case <-ctx.Done():
|
||||
if len(data) > 0 {
|
||||
log.Trace("Handling: %d data, %v", len(data), data)
|
||||
if unhandled := p.handle(data...); unhandled != nil {
|
||||
log.Error("Unhandled Data in queue %d", p.qid)
|
||||
}
|
||||
atomic.AddInt64(&p.numInQueue, -1*int64(len(data)))
|
||||
}
|
||||
log.Trace("Worker shutting down")
|
||||
return
|
||||
default:
|
||||
}
|
||||
|
||||
select {
|
||||
case <-paused:
|
||||
// go back around
|
||||
|
@ -784,10 +784,6 @@ func setTemplateIfExists(ctx *context.Context, ctxDataKey string, possibleFiles
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if !strings.HasPrefix(template.Ref, "refs/") { // Assume that the ref intended is always a branch - for tags users should use refs/tags/<ref>
|
||||
template.Ref = git.BranchPrefix + template.Ref
|
||||
}
|
||||
ctx.Data["HasSelectedLabel"] = len(labelIDs) > 0
|
||||
ctx.Data["label_ids"] = strings.Join(labelIDs, ",")
|
||||
|
@ -18,6 +18,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/notification"
|
||||
"code.gitea.io/gitea/modules/storage"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
)
|
||||
|
||||
// NewIssue creates new issue with labels for repository.
|
||||
@ -200,7 +201,7 @@ func GetRefEndNamesAndURLs(issues []*issues_model.Issue, repoLink string) (map[i
|
||||
for _, issue := range issues {
|
||||
if issue.Ref != "" {
|
||||
issueRefEndNames[issue.ID] = git.RefEndName(issue.Ref)
|
||||
issueRefURLs[issue.ID] = git.RefURL(repoLink, issue.Ref)
|
||||
issueRefURLs[issue.ID] = git.RefURL(repoLink, util.PathEscapeSegments(issue.Ref))
|
||||
}
|
||||
}
|
||||
return issueRefEndNames, issueRefURLs
|
||||
|
@ -73,8 +73,32 @@ func GitGcRepos(ctx context.Context, timeout time.Duration, args ...git.CmdArg)
|
||||
return db.ErrCancelledf("before GC of %s", repo.FullName())
|
||||
default:
|
||||
}
|
||||
// we can ignore the error here because it will be logged in GitGCRepo
|
||||
_ = GitGcRepo(ctx, repo, timeout, args)
|
||||
log.Trace("Running git gc on %v", repo)
|
||||
command := git.NewCommand(ctx, args...).
|
||||
SetDescription(fmt.Sprintf("Repository Garbage Collection: %s", repo.FullName()))
|
||||
var stdout string
|
||||
var err error
|
||||
stdout, _, err = command.RunStdString(&git.RunOpts{Timeout: timeout, Dir: repo.RepoPath()})
|
||||
|
||||
if err != nil {
|
||||
log.Error("Repository garbage collection failed for %v. Stdout: %s\nError: %v", repo, stdout, err)
|
||||
desc := fmt.Sprintf("Repository garbage collection failed for %s. Stdout: %s\nError: %v", repo.RepoPath(), stdout, err)
|
||||
if err = system_model.CreateRepositoryNotice(desc); err != nil {
|
||||
log.Error("CreateRepositoryNotice: %v", err)
|
||||
}
|
||||
return fmt.Errorf("Repository garbage collection failed in repo: %s: Error: %w", repo.FullName(), err)
|
||||
}
|
||||
|
||||
// Now update the size of the repository
|
||||
if err := repo_module.UpdateRepoSize(ctx, repo); err != nil {
|
||||
log.Error("Updating size as part of garbage collection failed for %v. Stdout: %s\nError: %v", repo, stdout, err)
|
||||
desc := fmt.Sprintf("Updating size as part of garbage collection failed for %s. Stdout: %s\nError: %v", repo.RepoPath(), stdout, err)
|
||||
if err = system_model.CreateRepositoryNotice(desc); err != nil {
|
||||
log.Error("CreateRepositoryNotice: %v", err)
|
||||
}
|
||||
return fmt.Errorf("Updating size as part of garbage collection failed in repo: %s: Error: %w", repo.FullName(), err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
); err != nil {
|
||||
@ -85,37 +109,6 @@ func GitGcRepos(ctx context.Context, timeout time.Duration, args ...git.CmdArg)
|
||||
return nil
|
||||
}
|
||||
|
||||
// GitGcRepo calls 'git gc' to remove unnecessary files and optimize the local repository
|
||||
func GitGcRepo(ctx context.Context, repo *repo_model.Repository, timeout time.Duration, args []git.CmdArg) error {
|
||||
log.Trace("Running git gc on %-v", repo)
|
||||
command := git.NewCommand(ctx, args...).
|
||||
SetDescription(fmt.Sprintf("Repository Garbage Collection: %s", repo.FullName()))
|
||||
var stdout string
|
||||
var err error
|
||||
stdout, _, err = command.RunStdString(&git.RunOpts{Timeout: timeout, Dir: repo.RepoPath()})
|
||||
|
||||
if err != nil {
|
||||
log.Error("Repository garbage collection failed for %-v. Stdout: %s\nError: %v", repo, stdout, err)
|
||||
desc := fmt.Sprintf("Repository garbage collection failed for %s. Stdout: %s\nError: %v", repo.RepoPath(), stdout, err)
|
||||
if err := system_model.CreateRepositoryNotice(desc); err != nil {
|
||||
log.Error("CreateRepositoryNotice: %v", err)
|
||||
}
|
||||
return fmt.Errorf("Repository garbage collection failed in repo: %s: Error: %w", repo.FullName(), err)
|
||||
}
|
||||
|
||||
// Now update the size of the repository
|
||||
if err := repo_module.UpdateRepoSize(ctx, repo); err != nil {
|
||||
log.Error("Updating size as part of garbage collection failed for %-v. Stdout: %s\nError: %v", repo, stdout, err)
|
||||
desc := fmt.Sprintf("Updating size as part of garbage collection failed for %s. Stdout: %s\nError: %v", repo.RepoPath(), stdout, err)
|
||||
if err := system_model.CreateRepositoryNotice(desc); err != nil {
|
||||
log.Error("CreateRepositoryNotice: %v", err)
|
||||
}
|
||||
return fmt.Errorf("Updating size as part of garbage collection failed in repo: %s: Error: %w", repo.FullName(), err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func gatherMissingRepoRecords(ctx context.Context) ([]*repo_model.Repository, error) {
|
||||
repos := make([]*repo_model.Repository, 0, 10)
|
||||
if err := db.Iterate(
|
||||
@ -169,7 +162,7 @@ func DeleteMissingRepositories(ctx context.Context, doer *user_model.User) error
|
||||
}
|
||||
log.Trace("Deleting %d/%d...", repo.OwnerID, repo.ID)
|
||||
if err := models.DeleteRepository(doer, repo.OwnerID, repo.ID); err != nil {
|
||||
log.Error("Failed to DeleteRepository %-v: Error: %v", repo, err)
|
||||
log.Error("Failed to DeleteRepository %s [%d]: Error: %v", repo.FullName(), repo.ID, err)
|
||||
if err2 := system_model.CreateRepositoryNotice("Failed to DeleteRepository %s [%d]: Error: %v", repo.FullName(), repo.ID, err); err2 != nil {
|
||||
log.Error("CreateRepositoryNotice: %v", err)
|
||||
}
|
||||
|
@ -139,7 +139,7 @@ func (f *WechatworkPayload) PullRequest(p *api.PullRequestPayload) (api.Payloade
|
||||
func (f *WechatworkPayload) Review(p *api.PullRequestPayload, event webhook_model.HookEventType) (api.Payloader, error) {
|
||||
var text, title string
|
||||
switch p.Action {
|
||||
case api.HookIssueReviewed:
|
||||
case api.HookIssueSynchronized:
|
||||
action, err := parseHookPullRequestEventType(event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -27,7 +27,7 @@
|
||||
</a>
|
||||
{{if and ($.Permission.CanWrite $.UnitTypeCode) (not $.Repository.IsArchived) (not .IsDeleted)}}{{- /* */ -}}
|
||||
<div class="ui primary tiny floating dropdown icon button">{{.locale.Tr "repo.commit.actions"}}
|
||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}<span class="sr-mobile-only">{{.locale.Tr "repo.commit.actions"}}</span>
|
||||
<div class="menu">
|
||||
<div class="ui header">{{.locale.Tr "repo.commit.actions"}}</div>
|
||||
<div class="divider"></div>
|
||||
|
@ -143,7 +143,7 @@
|
||||
{{$.locale.Tr "repo.diff.file_suppressed_line_too_long"}}
|
||||
{{else}}
|
||||
{{$.locale.Tr "repo.diff.file_suppressed"}}
|
||||
<a class="ui basic tiny button diff-load-button" data-href="{{$.Link}}?file-only=true&files={{$file.Name}}&files={{$file.OldName}}">{{$.locale.Tr "repo.diff.load"}}</a>
|
||||
<a class="ui basic tiny button diff-show-more-button" data-href="{{$.Link}}?file-only=true&files={{$file.Name}}&files={{$file.OldName}}">{{$.locale.Tr "repo.diff.load"}}</a>
|
||||
{{end}}
|
||||
{{else}}
|
||||
{{$.locale.Tr "repo.diff.bin_not_shown"}}
|
||||
|
@ -209,6 +209,8 @@ func (s *TestSession) MakeRequestNilResponseHashSumRecorder(t testing.TB, req *h
|
||||
|
||||
const userPassword = "password"
|
||||
|
||||
var loginSessionCache = make(map[string]*TestSession, 10)
|
||||
|
||||
func emptyTestSession(t testing.TB) *TestSession {
|
||||
t.Helper()
|
||||
jar, err := cookiejar.New(nil)
|
||||
@ -223,8 +225,12 @@ func getUserToken(t testing.TB, userName string) string {
|
||||
|
||||
func loginUser(t testing.TB, userName string) *TestSession {
|
||||
t.Helper()
|
||||
|
||||
return loginUserWithPassword(t, userName, userPassword)
|
||||
if session, ok := loginSessionCache[userName]; ok {
|
||||
return session
|
||||
}
|
||||
session := loginUserWithPassword(t, userName, userPassword)
|
||||
loginSessionCache[userName] = session
|
||||
return session
|
||||
}
|
||||
|
||||
func loginUserWithPassword(t testing.TB, userName, password string) *TestSession {
|
||||
|
@ -22,4 +22,7 @@ func TestSignOut(t *testing.T) {
|
||||
// try to view a private repo, should fail
|
||||
req = NewRequest(t, "GET", "/user2/repo2")
|
||||
session.MakeRequest(t, req, http.StatusNotFound)
|
||||
|
||||
// invalidate cached cookies for user2, for subsequent tests
|
||||
delete(loginSessionCache, "user2")
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
<DiffFileTreeItem v-for="item in fileTree" :key="item.name" :item="item" />
|
||||
</div>
|
||||
<div v-if="isIncomplete" id="diff-too-many-files-stats" class="pt-2">
|
||||
<span class="mr-2">{{ tooManyFilesMessage }}</span><a :class="['ui', 'basic', 'tiny', 'button', isLoadingNewData === true ? 'disabled' : '']" id="diff-show-more-files-stats" @click.stop="loadMoreData">{{ showMoreMessage }}</a>
|
||||
<span>{{ tooManyFilesMessage }}</span><a :class="['ui', 'basic', 'tiny', 'button', isLoadingNewData === true ? 'disabled' : '']" id="diff-show-more-files-stats" @click.stop="loadMoreData">{{ showMoreMessage }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -98,9 +98,6 @@ export default {
|
||||
mounted() {
|
||||
// ensure correct buttons when we are mounted to the dom
|
||||
this.adjustToggleButton(this.fileTreeIsVisible);
|
||||
// replace the pageData.diffFileInfo.files with our watched data so we get updates
|
||||
pageData.diffFileInfo.files = this.files;
|
||||
|
||||
document.querySelector('.diff-toggle-file-tree-button').addEventListener('click', this.toggleVisibility);
|
||||
},
|
||||
unmounted() {
|
||||
|
@ -119,47 +119,26 @@ function onShowMoreFiles() {
|
||||
|
||||
export function doLoadMoreFiles(link, diffEnd, callback) {
|
||||
const url = `${link}?skip-to=${diffEnd}&file-only=true`;
|
||||
loadMoreFiles(url, callback);
|
||||
}
|
||||
|
||||
function loadMoreFiles(url, callback) {
|
||||
const $target = $('a#diff-show-more-files');
|
||||
if ($target.hasClass('disabled')) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
$target.addClass('disabled');
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url,
|
||||
}).done((resp) => {
|
||||
if (!resp) {
|
||||
$target.removeClass('disabled');
|
||||
callback(resp);
|
||||
return;
|
||||
}
|
||||
$('#diff-incomplete').replaceWith($(resp).find('#diff-file-boxes').children());
|
||||
// By simply rerunning the script we add the new data to our existing
|
||||
// pagedata object. this triggers vue and the filetree and filelist will
|
||||
// render the new elements.
|
||||
$('body').append($(resp).find('script#diff-data-script'));
|
||||
onShowMoreFiles();
|
||||
callback(resp);
|
||||
}).fail(() => {
|
||||
$target.removeClass('disabled');
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
export function initRepoDiffShowMore() {
|
||||
$(document).on('click', 'a#diff-show-more-files', (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const $target = $(e.target);
|
||||
loadMoreFiles($target.data('href'), () => {});
|
||||
});
|
||||
|
||||
$(document).on('click', 'a.diff-load-button', (e) => {
|
||||
$(document).on('click', 'a.diff-show-more-button', (e) => {
|
||||
e.preventDefault();
|
||||
const $target = $(e.target);
|
||||
|
||||
|
@ -1665,9 +1665,6 @@
|
||||
background-color: var(--color-teal);
|
||||
}
|
||||
}
|
||||
.button {
|
||||
padding: 8px 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.diff-box .header:not(.resolved-placeholder) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user