From e637008fe3908a0027606846eab367e697ccc71d Mon Sep 17 00:00:00 2001 From: wxiaoguang <wxiaoguang@gmail.com> Date: Sun, 5 Jan 2025 23:18:02 +0800 Subject: [PATCH] Fix empty git repo handling logic and fix mobile view (#33101) (#33102) Backport #33101 and UI fix from main (including #33108) --- models/repo/repo.go | 2 ++ options/locale/locale_en-US.ini | 1 + routers/web/repo/view_home.go | 46 ++++++++++++++++++---------- services/context/repo.go | 3 -- templates/base/head_navbar.tmpl | 6 ++-- templates/repo/commit_page.tmpl | 2 +- templates/repo/empty.tmpl | 21 ++++++------- templates/repo/header.tmpl | 2 +- templates/user/dashboard/navbar.tmpl | 4 +-- web_src/css/base.css | 10 +++--- web_src/css/modules/navbar.css | 3 +- 11 files changed, 56 insertions(+), 44 deletions(-) diff --git a/models/repo/repo.go b/models/repo/repo.go index 8d211caf40..c5060a419f 100644 --- a/models/repo/repo.go +++ b/models/repo/repo.go @@ -276,6 +276,8 @@ func (repo *Repository) IsBroken() bool { } // MarkAsBrokenEmpty marks the repo as broken and empty +// FIXME: the status "broken" and "is_empty" were abused, +// The code always set them together, no way to distinguish whether a repo is really "empty" or "broken" func (repo *Repository) MarkAsBrokenEmpty() { repo.Status = RepositoryBroken repo.IsEmpty = true diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 16bd0fe8b6..2c10a4dbe1 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1231,6 +1231,7 @@ create_new_repo_command = Creating a new repository on the command line push_exist_repo = Pushing an existing repository from the command line empty_message = This repository does not contain any content. broken_message = The Git data underlying this repository cannot be read. Contact the administrator of this instance or delete this repository. +no_branch = This repository doesn’t have any branches. code = Code code.desc = Access source code, files, commits and branches. diff --git a/routers/web/repo/view_home.go b/routers/web/repo/view_home.go index b318c4a621..1d886a5ffb 100644 --- a/routers/web/repo/view_home.go +++ b/routers/web/repo/view_home.go @@ -223,16 +223,37 @@ func prepareRecentlyPushedNewBranches(ctx *context.Context) { } } +func updateContextRepoEmptyAndStatus(ctx *context.Context, empty bool, status repo_model.RepositoryStatus) { + ctx.Repo.Repository.IsEmpty = empty + if ctx.Repo.Repository.Status == repo_model.RepositoryReady || ctx.Repo.Repository.Status == repo_model.RepositoryBroken { + ctx.Repo.Repository.Status = status // only handle ready and broken status, leave other status as-is + } + if err := repo_model.UpdateRepositoryCols(ctx, ctx.Repo.Repository, "is_empty", "status"); err != nil { + ctx.ServerError("updateContextRepoEmptyAndStatus: UpdateRepositoryCols", err) + return + } +} + func handleRepoEmptyOrBroken(ctx *context.Context) { showEmpty := true - var err error if ctx.Repo.GitRepo != nil { - showEmpty, err = ctx.Repo.GitRepo.IsEmpty() + reallyEmpty, err := ctx.Repo.GitRepo.IsEmpty() if err != nil { + showEmpty = true // the repo is broken + updateContextRepoEmptyAndStatus(ctx, true, repo_model.RepositoryBroken) log.Error("GitRepo.IsEmpty: %v", err) - ctx.Repo.Repository.Status = repo_model.RepositoryBroken - showEmpty = true ctx.Flash.Error(ctx.Tr("error.occurred"), true) + } else if reallyEmpty { + showEmpty = true // the repo is really empty + updateContextRepoEmptyAndStatus(ctx, true, repo_model.RepositoryReady) + } else if ctx.Repo.Commit == nil { + showEmpty = true // it is not really empty, but there is no branch + // at the moment, other repo units like "actions" are not able to handle such case, + // so we just mark the repo as empty to prevent from displaying these units. + updateContextRepoEmptyAndStatus(ctx, true, repo_model.RepositoryReady) + } else { + // the repo is actually not empty and has branches, need to update the database later + showEmpty = false } } if showEmpty { @@ -240,18 +261,11 @@ func handleRepoEmptyOrBroken(ctx *context.Context) { return } - // the repo is not really empty, so we should update the modal in database - // such problem may be caused by: - // 1) an error occurs during pushing/receiving. 2) the user replaces an empty git repo manually - // and even more: the IsEmpty flag is deeply broken and should be removed with the UI changed to manage to cope with empty repos. - // it's possible for a repository to be non-empty by that flag but still 500 - // because there are no branches - only tags -or the default branch is non-extant as it has been 0-pushed. - ctx.Repo.Repository.IsEmpty = false - if err = repo_model.UpdateRepositoryCols(ctx, ctx.Repo.Repository, "is_empty"); err != nil { - ctx.ServerError("UpdateRepositoryCols", err) - return - } - if err = repo_module.UpdateRepoSize(ctx, ctx.Repo.Repository); err != nil { + // The repo is not really empty, so we should update the model in database, such problem may be caused by: + // 1) an error occurs during pushing/receiving. + // 2) the user replaces an empty git repo manually. + updateContextRepoEmptyAndStatus(ctx, false, repo_model.RepositoryReady) + if err := repo_module.UpdateRepoSize(ctx, ctx.Repo.Repository); err != nil { ctx.ServerError("UpdateRepoSize", err) return } diff --git a/services/context/repo.go b/services/context/repo.go index 9b54439110..1e7c430347 100644 --- a/services/context/repo.go +++ b/services/context/repo.go @@ -908,10 +908,8 @@ func RepoRefByType(detectRefType RepoRefType, opts ...RepoRefByTypeOptions) func refName = brs[0].Name } else if len(brs) == 0 { log.Error("No branches in non-empty repository %s", ctx.Repo.GitRepo.Path) - ctx.Repo.Repository.MarkAsBrokenEmpty() } else { log.Error("GetBranches error: %v", err) - ctx.Repo.Repository.MarkAsBrokenEmpty() } } ctx.Repo.RefName = refName @@ -922,7 +920,6 @@ func RepoRefByType(detectRefType RepoRefType, opts ...RepoRefByTypeOptions) func } else if strings.Contains(err.Error(), "fatal: not a git repository") || strings.Contains(err.Error(), "object does not exist") { // if the repository is broken, we can continue to the handler code, to show "Settings -> Delete Repository" for end users log.Error("GetBranchCommit: %v", err) - ctx.Repo.Repository.MarkAsBrokenEmpty() } else { ctx.ServerError("GetBranchCommit", err) return cancel diff --git a/templates/base/head_navbar.tmpl b/templates/base/head_navbar.tmpl index 951ee590d1..bbb2a7ef01 100644 --- a/templates/base/head_navbar.tmpl +++ b/templates/base/head_navbar.tmpl @@ -11,7 +11,7 @@ </a> <!-- mobile right menu, it must be here because in mobile view, each item is a flex column, the first item is a full row column --> - <div class="ui secondary menu item navbar-mobile-right only-mobile"> + <div class="ui secondary menu navbar-mobile-right only-mobile"> {{if and .IsSigned EnableTimetracking .ActiveStopwatch}} <a id="mobile-stopwatch-icon" class="active-stopwatch item tw-mx-0" href="{{.ActiveStopwatch.IssueLink}}" title="{{ctx.Locale.Tr "active_stopwatch"}}" data-seconds="{{.ActiveStopwatch.Seconds}}"> <div class="tw-relative"> @@ -70,7 +70,7 @@ <span class="not-mobile">{{svg "octicon-triangle-down"}}</span> </span> <div class="menu user-menu"> - <div class="ui header"> + <div class="header"> {{ctx.Locale.Tr "signed_in_as"}} <strong>{{.SignedUser.Name}}</strong> </div> @@ -128,7 +128,7 @@ <span class="not-mobile">{{svg "octicon-triangle-down"}}</span> </span> <div class="menu user-menu"> - <div class="ui header"> + <div class="header"> {{ctx.Locale.Tr "signed_in_as"}} <strong>{{.SignedUser.Name}}</strong> </div> diff --git a/templates/repo/commit_page.tmpl b/templates/repo/commit_page.tmpl index 71f77154fb..38e3df8e70 100644 --- a/templates/repo/commit_page.tmpl +++ b/templates/repo/commit_page.tmpl @@ -30,7 +30,7 @@ {{ctx.Locale.Tr "repo.commit.operations"}} {{svg "octicon-triangle-down" 14 "dropdown icon"}} <div class="menu"> - <div class="ui header">{{ctx.Locale.Tr "repo.commit.operations"}}</div> + <div class="header">{{ctx.Locale.Tr "repo.commit.operations"}}</div> <div class="divider"></div> <div class="item show-create-branch-modal" data-content="{{ctx.Locale.Tr "repo.branch.new_branch_from" (.CommitID)}}" {{/* used by the form */}} diff --git a/templates/repo/empty.tmpl b/templates/repo/empty.tmpl index 7170fe3602..dfda5b7b2b 100644 --- a/templates/repo/empty.tmpl +++ b/templates/repo/empty.tmpl @@ -14,14 +14,13 @@ {{end}} </div> {{end}} + {{if .Repository.IsBroken}} - <div class="ui segment center"> - {{ctx.Locale.Tr "repo.broken_message"}} - </div> + <div class="ui segment center">{{ctx.Locale.Tr "repo.broken_message"}}</div> + {{else if .Repository.IsEmpty}} + <div class="ui segment center">{{ctx.Locale.Tr "repo.no_branch"}}</div> {{else if .CanWriteCode}} - <h4 class="ui top attached header"> - {{ctx.Locale.Tr "repo.quick_guide"}} - </h4> + <h4 class="ui top attached header">{{ctx.Locale.Tr "repo.quick_guide"}}</h4> <div class="ui attached guide table segment empty-repo-guide"> <div class="item"> <h3>{{ctx.Locale.Tr "repo.clone_this_repo"}} <small>{{ctx.Locale.Tr "repo.clone_helper" "http://git-scm.com/book/en/v2/Git-Basics-Getting-a-Git-Repository"}}</small></h3> @@ -66,12 +65,10 @@ git push -u origin {{.Repository.DefaultBranch}}</code></pre> </div> </div> {{end}} - {{else}} - <div class="ui segment center"> - {{ctx.Locale.Tr "repo.empty_message"}} - </div> - {{end}} - </div> + </div> + {{else}} + <div class="ui segment center">{{ctx.Locale.Tr "repo.empty_message"}}</div> + {{end}} </div> </div> </div> diff --git a/templates/repo/header.tmpl b/templates/repo/header.tmpl index c3ae697f31..e187ef1a87 100644 --- a/templates/repo/header.tmpl +++ b/templates/repo/header.tmpl @@ -162,7 +162,7 @@ </a> {{end}} - {{if and .EnableActions (.Permission.CanRead ctx.Consts.RepoUnitTypeActions)}} + {{if and .EnableActions (.Permission.CanRead ctx.Consts.RepoUnitTypeActions) (not .IsEmptyRepo)}} <a class="{{if .PageIsActions}}active {{end}}item" href="{{.RepoLink}}/actions"> {{svg "octicon-play"}} {{ctx.Locale.Tr "actions.actions"}} {{if .Repository.NumOpenActionRuns}} diff --git a/templates/user/dashboard/navbar.tmpl b/templates/user/dashboard/navbar.tmpl index 7982cbd950..a828bc90e4 100644 --- a/templates/user/dashboard/navbar.tmpl +++ b/templates/user/dashboard/navbar.tmpl @@ -12,7 +12,7 @@ {{svg "octicon-triangle-down" 14 "dropdown icon tw-ml-1"}} </span> <div class="context user overflow menu"> - <div class="ui header"> + <div class="header"> {{ctx.Locale.Tr "home.switch_dashboard_context"}} </div> <div class="scrolling menu items"> @@ -56,7 +56,7 @@ </span> {{svg "octicon-triangle-down" 14 "dropdown icon"}} <div class="context user overflow menu"> - <div class="ui header"> + <div class="header"> {{ctx.Locale.Tr "home.filter_by_team_repositories"}} </div> <div class="scrolling menu items"> diff --git a/web_src/css/base.css b/web_src/css/base.css index a0bfefebf5..1a354c9663 100644 --- a/web_src/css/base.css +++ b/web_src/css/base.css @@ -336,8 +336,13 @@ a.label, border-color: var(--color-secondary); } +.ui.dropdown .menu > .header { + text-transform: none; /* reset fomantic's "uppercase" */ +} + .ui.dropdown .menu > .header:not(.ui) { color: var(--color-text); + font-size: 0.95em; /* reset fomantic's small font-size */ } .ui.dropdown .menu > .item { @@ -691,11 +696,6 @@ input:-webkit-autofill:active, box-shadow: 0 6px 18px var(--color-shadow) !important; } -.ui.dropdown .menu > .header { - font-size: 0.8em; - text-transform: none; /* reset fomantic's "uppercase" */ -} - .ui .text.left { text-align: left !important; } diff --git a/web_src/css/modules/navbar.css b/web_src/css/modules/navbar.css index 556da2df3b..73914d9a21 100644 --- a/web_src/css/modules/navbar.css +++ b/web_src/css/modules/navbar.css @@ -66,7 +66,8 @@ align-items: stretch; } /* hide all items */ - #navbar .item { + #navbar .navbar-left > .item, + #navbar .navbar-right > .item { display: none; } #navbar #navbar-logo {