You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

branch.go 13 kB

11 years ago
11 years ago
Move macaron to chi (#14293) Use [chi](https://github.com/go-chi/chi) instead of the forked [macaron](https://gitea.com/macaron/macaron). Since macaron and chi have conflicts with session share, this big PR becomes a have-to thing. According my previous idea, we can replace macaron step by step but I'm wrong. :( Below is a list of big changes on this PR. - [x] Define `context.ResponseWriter` interface with an implementation `context.Response`. - [x] Use chi instead of macaron, and also a customize `Route` to wrap chi so that the router usage is similar as before. - [x] Create different routers for `web`, `api`, `internal` and `install` so that the codes will be more clear and no magic . - [x] Use https://github.com/unrolled/render instead of macaron's internal render - [x] Use https://github.com/NYTimes/gziphandler instead of https://gitea.com/macaron/gzip - [x] Use https://gitea.com/go-chi/session which is a modified version of https://gitea.com/macaron/session and removed `nodb` support since it will not be maintained. **BREAK** - [x] Use https://gitea.com/go-chi/captcha which is a modified version of https://gitea.com/macaron/captcha - [x] Use https://gitea.com/go-chi/cache which is a modified version of https://gitea.com/macaron/cache - [x] Use https://gitea.com/go-chi/binding which is a modified version of https://gitea.com/macaron/binding - [x] Use https://github.com/go-chi/cors instead of https://gitea.com/macaron/cors - [x] Dropped https://gitea.com/macaron/i18n and make a new one in `code.gitea.io/gitea/modules/translation` - [x] Move validation form structs from `code.gitea.io/gitea/modules/auth` to `code.gitea.io/gitea/modules/forms` to avoid dependency cycle. - [x] Removed macaron log service because it's not need any more. **BREAK** - [x] All form structs have to be get by `web.GetForm(ctx)` in the route function but not as a function parameter on routes definition. - [x] Move Git HTTP protocol implementation to use routers directly. - [x] Fix the problem that chi routes don't support trailing slash but macaron did. - [x] `/api/v1/swagger` now will be redirect to `/api/swagger` but not render directly so that `APIContext` will not create a html render. Notices: - Chi router don't support request with trailing slash - Integration test `TestUserHeatmap` maybe mysql version related. It's failed on my macOS(mysql 5.7.29 installed via brew) but succeed on CI. Co-authored-by: 6543 <6543@obermui.de>
4 years ago
Move macaron to chi (#14293) Use [chi](https://github.com/go-chi/chi) instead of the forked [macaron](https://gitea.com/macaron/macaron). Since macaron and chi have conflicts with session share, this big PR becomes a have-to thing. According my previous idea, we can replace macaron step by step but I'm wrong. :( Below is a list of big changes on this PR. - [x] Define `context.ResponseWriter` interface with an implementation `context.Response`. - [x] Use chi instead of macaron, and also a customize `Route` to wrap chi so that the router usage is similar as before. - [x] Create different routers for `web`, `api`, `internal` and `install` so that the codes will be more clear and no magic . - [x] Use https://github.com/unrolled/render instead of macaron's internal render - [x] Use https://github.com/NYTimes/gziphandler instead of https://gitea.com/macaron/gzip - [x] Use https://gitea.com/go-chi/session which is a modified version of https://gitea.com/macaron/session and removed `nodb` support since it will not be maintained. **BREAK** - [x] Use https://gitea.com/go-chi/captcha which is a modified version of https://gitea.com/macaron/captcha - [x] Use https://gitea.com/go-chi/cache which is a modified version of https://gitea.com/macaron/cache - [x] Use https://gitea.com/go-chi/binding which is a modified version of https://gitea.com/macaron/binding - [x] Use https://github.com/go-chi/cors instead of https://gitea.com/macaron/cors - [x] Dropped https://gitea.com/macaron/i18n and make a new one in `code.gitea.io/gitea/modules/translation` - [x] Move validation form structs from `code.gitea.io/gitea/modules/auth` to `code.gitea.io/gitea/modules/forms` to avoid dependency cycle. - [x] Removed macaron log service because it's not need any more. **BREAK** - [x] All form structs have to be get by `web.GetForm(ctx)` in the route function but not as a function parameter on routes definition. - [x] Move Git HTTP protocol implementation to use routers directly. - [x] Fix the problem that chi routes don't support trailing slash but macaron did. - [x] `/api/v1/swagger` now will be redirect to `/api/swagger` but not render directly so that `APIContext` will not create a html render. Notices: - Chi router don't support request with trailing slash - Integration test `TestUserHeatmap` maybe mysql version related. It's failed on my macOS(mysql 5.7.29 installed via brew) but succeed on CI. Co-authored-by: 6543 <6543@obermui.de>
4 years ago
11 years ago
11 years ago
11 years ago
11 years ago
Better logging (#6038) (#6095) * Panic don't fatal on create new logger Fixes #5854 Signed-off-by: Andrew Thornton <art27@cantab.net> * partial broken * Update the logging infrastrcture Signed-off-by: Andrew Thornton <art27@cantab.net> * Reset the skip levels for Fatal and Error Signed-off-by: Andrew Thornton <art27@cantab.net> * broken ncsa * More log.Error fixes Signed-off-by: Andrew Thornton <art27@cantab.net> * Remove nal * set log-levels to lowercase * Make console_test test all levels * switch to lowercased levels * OK now working * Fix vetting issues * Fix lint * Fix tests * change default logging to match current gitea * Improve log testing Signed-off-by: Andrew Thornton <art27@cantab.net> * reset error skip levels to 0 * Update documentation and access logger configuration * Redirect the router log back to gitea if redirect macaron log but also allow setting the log level - i.e. TRACE * Fix broken level caching * Refactor the router log * Add Router logger * Add colorizing options * Adjust router colors * Only create logger if they will be used * update app.ini.sample * rename Attribute ColorAttribute * Change from white to green for function * Set fatal/error levels * Restore initial trace logger * Fix Trace arguments in modules/auth/auth.go * Properly handle XORMLogger * Improve admin/config page * fix fmt * Add auto-compression of old logs * Update error log levels * Remove the unnecessary skip argument from Error, Fatal and Critical * Add stacktrace support * Fix tests * Remove x/sync from vendors? * Add stderr option to console logger * Use filepath.ToSlash to protect against Windows in tests * Remove prefixed underscores from names in colors.go * Remove not implemented database logger This was removed from Gogs on 4 Mar 2016 but left in the configuration since then. * Ensure that log paths are relative to ROOT_PATH * use path.Join * rename jsonConfig to logConfig * Rename "config" to "jsonConfig" to make it clearer * Requested changes * Requested changes: XormLogger * Try to color the windows terminal If successful default to colorizing the console logs * fixup * Colorize initially too * update vendor * Colorize logs on default and remove if this is not a colorizing logger * Fix documentation * fix test * Use go-isatty to detect if on windows we are on msys or cygwin * Fix spelling mistake * Add missing vendors * More changes * Rationalise the ANSI writer protection * Adjust colors on advice from @0x5c * Make Flags a comma separated list * Move to use the windows constant for ENABLE_VIRTUAL_TERMINAL_PROCESSING * Ensure matching is done on the non-colored message - to simpify EXPRESSION
6 years ago
11 years ago
11 years ago
Better logging (#6038) (#6095) * Panic don't fatal on create new logger Fixes #5854 Signed-off-by: Andrew Thornton <art27@cantab.net> * partial broken * Update the logging infrastrcture Signed-off-by: Andrew Thornton <art27@cantab.net> * Reset the skip levels for Fatal and Error Signed-off-by: Andrew Thornton <art27@cantab.net> * broken ncsa * More log.Error fixes Signed-off-by: Andrew Thornton <art27@cantab.net> * Remove nal * set log-levels to lowercase * Make console_test test all levels * switch to lowercased levels * OK now working * Fix vetting issues * Fix lint * Fix tests * change default logging to match current gitea * Improve log testing Signed-off-by: Andrew Thornton <art27@cantab.net> * reset error skip levels to 0 * Update documentation and access logger configuration * Redirect the router log back to gitea if redirect macaron log but also allow setting the log level - i.e. TRACE * Fix broken level caching * Refactor the router log * Add Router logger * Add colorizing options * Adjust router colors * Only create logger if they will be used * update app.ini.sample * rename Attribute ColorAttribute * Change from white to green for function * Set fatal/error levels * Restore initial trace logger * Fix Trace arguments in modules/auth/auth.go * Properly handle XORMLogger * Improve admin/config page * fix fmt * Add auto-compression of old logs * Update error log levels * Remove the unnecessary skip argument from Error, Fatal and Critical * Add stacktrace support * Fix tests * Remove x/sync from vendors? * Add stderr option to console logger * Use filepath.ToSlash to protect against Windows in tests * Remove prefixed underscores from names in colors.go * Remove not implemented database logger This was removed from Gogs on 4 Mar 2016 but left in the configuration since then. * Ensure that log paths are relative to ROOT_PATH * use path.Join * rename jsonConfig to logConfig * Rename "config" to "jsonConfig" to make it clearer * Requested changes * Requested changes: XormLogger * Try to color the windows terminal If successful default to colorizing the console logs * fixup * Colorize initially too * update vendor * Colorize logs on default and remove if this is not a colorizing logger * Fix documentation * fix test * Use go-isatty to detect if on windows we are on msys or cygwin * Fix spelling mistake * Add missing vendors * More changes * Rationalise the ANSI writer protection * Adjust colors on advice from @0x5c * Make Flags a comma separated list * Move to use the windows constant for ENABLE_VIRTUAL_TERMINAL_PROCESSING * Ensure matching is done on the non-colored message - to simpify EXPRESSION
6 years ago
Better logging (#6038) (#6095) * Panic don't fatal on create new logger Fixes #5854 Signed-off-by: Andrew Thornton <art27@cantab.net> * partial broken * Update the logging infrastrcture Signed-off-by: Andrew Thornton <art27@cantab.net> * Reset the skip levels for Fatal and Error Signed-off-by: Andrew Thornton <art27@cantab.net> * broken ncsa * More log.Error fixes Signed-off-by: Andrew Thornton <art27@cantab.net> * Remove nal * set log-levels to lowercase * Make console_test test all levels * switch to lowercased levels * OK now working * Fix vetting issues * Fix lint * Fix tests * change default logging to match current gitea * Improve log testing Signed-off-by: Andrew Thornton <art27@cantab.net> * reset error skip levels to 0 * Update documentation and access logger configuration * Redirect the router log back to gitea if redirect macaron log but also allow setting the log level - i.e. TRACE * Fix broken level caching * Refactor the router log * Add Router logger * Add colorizing options * Adjust router colors * Only create logger if they will be used * update app.ini.sample * rename Attribute ColorAttribute * Change from white to green for function * Set fatal/error levels * Restore initial trace logger * Fix Trace arguments in modules/auth/auth.go * Properly handle XORMLogger * Improve admin/config page * fix fmt * Add auto-compression of old logs * Update error log levels * Remove the unnecessary skip argument from Error, Fatal and Critical * Add stacktrace support * Fix tests * Remove x/sync from vendors? * Add stderr option to console logger * Use filepath.ToSlash to protect against Windows in tests * Remove prefixed underscores from names in colors.go * Remove not implemented database logger This was removed from Gogs on 4 Mar 2016 but left in the configuration since then. * Ensure that log paths are relative to ROOT_PATH * use path.Join * rename jsonConfig to logConfig * Rename "config" to "jsonConfig" to make it clearer * Requested changes * Requested changes: XormLogger * Try to color the windows terminal If successful default to colorizing the console logs * fixup * Colorize initially too * update vendor * Colorize logs on default and remove if this is not a colorizing logger * Fix documentation * fix test * Use go-isatty to detect if on windows we are on msys or cygwin * Fix spelling mistake * Add missing vendors * More changes * Rationalise the ANSI writer protection * Adjust colors on advice from @0x5c * Make Flags a comma separated list * Move to use the windows constant for ENABLE_VIRTUAL_TERMINAL_PROCESSING * Ensure matching is done on the non-colored message - to simpify EXPRESSION
6 years ago
Better logging (#6038) (#6095) * Panic don't fatal on create new logger Fixes #5854 Signed-off-by: Andrew Thornton <art27@cantab.net> * partial broken * Update the logging infrastrcture Signed-off-by: Andrew Thornton <art27@cantab.net> * Reset the skip levels for Fatal and Error Signed-off-by: Andrew Thornton <art27@cantab.net> * broken ncsa * More log.Error fixes Signed-off-by: Andrew Thornton <art27@cantab.net> * Remove nal * set log-levels to lowercase * Make console_test test all levels * switch to lowercased levels * OK now working * Fix vetting issues * Fix lint * Fix tests * change default logging to match current gitea * Improve log testing Signed-off-by: Andrew Thornton <art27@cantab.net> * reset error skip levels to 0 * Update documentation and access logger configuration * Redirect the router log back to gitea if redirect macaron log but also allow setting the log level - i.e. TRACE * Fix broken level caching * Refactor the router log * Add Router logger * Add colorizing options * Adjust router colors * Only create logger if they will be used * update app.ini.sample * rename Attribute ColorAttribute * Change from white to green for function * Set fatal/error levels * Restore initial trace logger * Fix Trace arguments in modules/auth/auth.go * Properly handle XORMLogger * Improve admin/config page * fix fmt * Add auto-compression of old logs * Update error log levels * Remove the unnecessary skip argument from Error, Fatal and Critical * Add stacktrace support * Fix tests * Remove x/sync from vendors? * Add stderr option to console logger * Use filepath.ToSlash to protect against Windows in tests * Remove prefixed underscores from names in colors.go * Remove not implemented database logger This was removed from Gogs on 4 Mar 2016 but left in the configuration since then. * Ensure that log paths are relative to ROOT_PATH * use path.Join * rename jsonConfig to logConfig * Rename "config" to "jsonConfig" to make it clearer * Requested changes * Requested changes: XormLogger * Try to color the windows terminal If successful default to colorizing the console logs * fixup * Colorize initially too * update vendor * Colorize logs on default and remove if this is not a colorizing logger * Fix documentation * fix test * Use go-isatty to detect if on windows we are on msys or cygwin * Fix spelling mistake * Add missing vendors * More changes * Rationalise the ANSI writer protection * Adjust colors on advice from @0x5c * Make Flags a comma separated list * Move to use the windows constant for ENABLE_VIRTUAL_TERMINAL_PROCESSING * Ensure matching is done on the non-colored message - to simpify EXPRESSION
6 years ago
Better logging (#6038) (#6095) * Panic don't fatal on create new logger Fixes #5854 Signed-off-by: Andrew Thornton <art27@cantab.net> * partial broken * Update the logging infrastrcture Signed-off-by: Andrew Thornton <art27@cantab.net> * Reset the skip levels for Fatal and Error Signed-off-by: Andrew Thornton <art27@cantab.net> * broken ncsa * More log.Error fixes Signed-off-by: Andrew Thornton <art27@cantab.net> * Remove nal * set log-levels to lowercase * Make console_test test all levels * switch to lowercased levels * OK now working * Fix vetting issues * Fix lint * Fix tests * change default logging to match current gitea * Improve log testing Signed-off-by: Andrew Thornton <art27@cantab.net> * reset error skip levels to 0 * Update documentation and access logger configuration * Redirect the router log back to gitea if redirect macaron log but also allow setting the log level - i.e. TRACE * Fix broken level caching * Refactor the router log * Add Router logger * Add colorizing options * Adjust router colors * Only create logger if they will be used * update app.ini.sample * rename Attribute ColorAttribute * Change from white to green for function * Set fatal/error levels * Restore initial trace logger * Fix Trace arguments in modules/auth/auth.go * Properly handle XORMLogger * Improve admin/config page * fix fmt * Add auto-compression of old logs * Update error log levels * Remove the unnecessary skip argument from Error, Fatal and Critical * Add stacktrace support * Fix tests * Remove x/sync from vendors? * Add stderr option to console logger * Use filepath.ToSlash to protect against Windows in tests * Remove prefixed underscores from names in colors.go * Remove not implemented database logger This was removed from Gogs on 4 Mar 2016 but left in the configuration since then. * Ensure that log paths are relative to ROOT_PATH * use path.Join * rename jsonConfig to logConfig * Rename "config" to "jsonConfig" to make it clearer * Requested changes * Requested changes: XormLogger * Try to color the windows terminal If successful default to colorizing the console logs * fixup * Colorize initially too * update vendor * Colorize logs on default and remove if this is not a colorizing logger * Fix documentation * fix test * Use go-isatty to detect if on windows we are on msys or cygwin * Fix spelling mistake * Add missing vendors * More changes * Rationalise the ANSI writer protection * Adjust colors on advice from @0x5c * Make Flags a comma separated list * Move to use the windows constant for ENABLE_VIRTUAL_TERMINAL_PROCESSING * Ensure matching is done on the non-colored message - to simpify EXPRESSION
6 years ago
11 years ago
Move macaron to chi (#14293) Use [chi](https://github.com/go-chi/chi) instead of the forked [macaron](https://gitea.com/macaron/macaron). Since macaron and chi have conflicts with session share, this big PR becomes a have-to thing. According my previous idea, we can replace macaron step by step but I'm wrong. :( Below is a list of big changes on this PR. - [x] Define `context.ResponseWriter` interface with an implementation `context.Response`. - [x] Use chi instead of macaron, and also a customize `Route` to wrap chi so that the router usage is similar as before. - [x] Create different routers for `web`, `api`, `internal` and `install` so that the codes will be more clear and no magic . - [x] Use https://github.com/unrolled/render instead of macaron's internal render - [x] Use https://github.com/NYTimes/gziphandler instead of https://gitea.com/macaron/gzip - [x] Use https://gitea.com/go-chi/session which is a modified version of https://gitea.com/macaron/session and removed `nodb` support since it will not be maintained. **BREAK** - [x] Use https://gitea.com/go-chi/captcha which is a modified version of https://gitea.com/macaron/captcha - [x] Use https://gitea.com/go-chi/cache which is a modified version of https://gitea.com/macaron/cache - [x] Use https://gitea.com/go-chi/binding which is a modified version of https://gitea.com/macaron/binding - [x] Use https://github.com/go-chi/cors instead of https://gitea.com/macaron/cors - [x] Dropped https://gitea.com/macaron/i18n and make a new one in `code.gitea.io/gitea/modules/translation` - [x] Move validation form structs from `code.gitea.io/gitea/modules/auth` to `code.gitea.io/gitea/modules/forms` to avoid dependency cycle. - [x] Removed macaron log service because it's not need any more. **BREAK** - [x] All form structs have to be get by `web.GetForm(ctx)` in the route function but not as a function parameter on routes definition. - [x] Move Git HTTP protocol implementation to use routers directly. - [x] Fix the problem that chi routes don't support trailing slash but macaron did. - [x] `/api/v1/swagger` now will be redirect to `/api/swagger` but not render directly so that `APIContext` will not create a html render. Notices: - Chi router don't support request with trailing slash - Integration test `TestUserHeatmap` maybe mysql version related. It's failed on my macOS(mysql 5.7.29 installed via brew) but succeed on CI. Co-authored-by: 6543 <6543@obermui.de>
4 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. // Copyright 2014 The Gogs Authors. All rights reserved.
  2. // Copyright 2018 The Gitea Authors. All rights reserved.
  3. // Use of this source code is governed by a MIT-style
  4. // license that can be found in the LICENSE file.
  5. package repo
  6. import (
  7. "fmt"
  8. "strings"
  9. "code.gitea.io/gitea/models"
  10. "code.gitea.io/gitea/modules/base"
  11. "code.gitea.io/gitea/modules/context"
  12. auth "code.gitea.io/gitea/modules/forms"
  13. "code.gitea.io/gitea/modules/git"
  14. "code.gitea.io/gitea/modules/log"
  15. "code.gitea.io/gitea/modules/repofiles"
  16. repo_module "code.gitea.io/gitea/modules/repository"
  17. "code.gitea.io/gitea/modules/util"
  18. "code.gitea.io/gitea/modules/web"
  19. "code.gitea.io/gitea/routers/utils"
  20. repo_service "code.gitea.io/gitea/services/repository"
  21. )
  22. const (
  23. tplBranch base.TplName = "repo/branch/list"
  24. )
  25. // Branch contains the branch information
  26. type Branch struct {
  27. Name string
  28. Commit *git.Commit
  29. IsProtected bool
  30. IsDeleted bool
  31. IsIncluded bool
  32. DeletedBranch *models.DeletedBranch
  33. CommitsAhead int
  34. CommitsBehind int
  35. LatestPullRequest *models.PullRequest
  36. MergeMovedOn bool
  37. }
  38. // Branches render repository branch page
  39. func Branches(ctx *context.Context) {
  40. ctx.Data["Title"] = "Branches"
  41. ctx.Data["IsRepoToolbarBranches"] = true
  42. ctx.Data["DefaultBranch"] = ctx.Repo.Repository.DefaultBranch
  43. ctx.Data["AllowsPulls"] = ctx.Repo.Repository.AllowsPulls()
  44. ctx.Data["IsWriter"] = ctx.Repo.CanWrite(models.UnitTypeCode)
  45. ctx.Data["IsMirror"] = ctx.Repo.Repository.IsMirror
  46. ctx.Data["CanPull"] = ctx.Repo.CanWrite(models.UnitTypeCode) || (ctx.IsSigned && ctx.User.HasForkedRepo(ctx.Repo.Repository.ID))
  47. ctx.Data["PageIsViewCode"] = true
  48. ctx.Data["PageIsBranches"] = true
  49. page := ctx.QueryInt("page")
  50. if page <= 1 {
  51. page = 1
  52. }
  53. limit := ctx.QueryInt("limit")
  54. if limit <= 0 || limit > git.BranchesRangeSize {
  55. limit = git.BranchesRangeSize
  56. }
  57. skip := (page - 1) * limit
  58. log.Debug("Branches: skip: %d limit: %d", skip, limit)
  59. branches, branchesCount := loadBranches(ctx, skip, limit)
  60. if ctx.Written() {
  61. return
  62. }
  63. ctx.Data["Branches"] = branches
  64. pager := context.NewPagination(int(branchesCount), git.BranchesRangeSize, page, 5)
  65. pager.SetDefaultParams(ctx)
  66. ctx.Data["Page"] = pager
  67. ctx.HTML(200, tplBranch)
  68. }
  69. // DeleteBranchPost responses for delete merged branch
  70. func DeleteBranchPost(ctx *context.Context) {
  71. defer redirect(ctx)
  72. branchName := ctx.Query("name")
  73. if branchName == ctx.Repo.Repository.DefaultBranch {
  74. log.Debug("DeleteBranch: Can't delete default branch '%s'", branchName)
  75. ctx.Flash.Error(ctx.Tr("repo.branch.default_deletion_failed", branchName))
  76. return
  77. }
  78. isProtected, err := ctx.Repo.Repository.IsProtectedBranch(branchName, ctx.User)
  79. if err != nil {
  80. log.Error("DeleteBranch: %v", err)
  81. ctx.Flash.Error(ctx.Tr("repo.branch.deletion_failed", branchName))
  82. return
  83. }
  84. if isProtected {
  85. log.Debug("DeleteBranch: Can't delete protected branch '%s'", branchName)
  86. ctx.Flash.Error(ctx.Tr("repo.branch.protected_deletion_failed", branchName))
  87. return
  88. }
  89. if !ctx.Repo.GitRepo.IsBranchExist(branchName) {
  90. log.Debug("DeleteBranch: Can't delete non existing branch '%s'", branchName)
  91. ctx.Flash.Error(ctx.Tr("repo.branch.deletion_failed", branchName))
  92. return
  93. }
  94. if err := deleteBranch(ctx, branchName); err != nil {
  95. log.Error("DeleteBranch: %v", err)
  96. ctx.Flash.Error(ctx.Tr("repo.branch.deletion_failed", branchName))
  97. return
  98. }
  99. ctx.Flash.Success(ctx.Tr("repo.branch.deletion_success", branchName))
  100. }
  101. // RestoreBranchPost responses for delete merged branch
  102. func RestoreBranchPost(ctx *context.Context) {
  103. defer redirect(ctx)
  104. branchID := ctx.QueryInt64("branch_id")
  105. branchName := ctx.Query("name")
  106. deletedBranch, err := ctx.Repo.Repository.GetDeletedBranchByID(branchID)
  107. if err != nil {
  108. log.Error("GetDeletedBranchByID: %v", err)
  109. ctx.Flash.Error(ctx.Tr("repo.branch.restore_failed", branchName))
  110. return
  111. }
  112. if err := git.Push(ctx.Repo.Repository.RepoPath(), git.PushOptions{
  113. Remote: ctx.Repo.Repository.RepoPath(),
  114. Branch: fmt.Sprintf("%s:%s%s", deletedBranch.Commit, git.BranchPrefix, deletedBranch.Name),
  115. Env: models.PushingEnvironment(ctx.User, ctx.Repo.Repository),
  116. }); err != nil {
  117. if strings.Contains(err.Error(), "already exists") {
  118. log.Debug("RestoreBranch: Can't restore branch '%s', since one with same name already exist", deletedBranch.Name)
  119. ctx.Flash.Error(ctx.Tr("repo.branch.already_exists", deletedBranch.Name))
  120. return
  121. }
  122. log.Error("RestoreBranch: CreateBranch: %v", err)
  123. ctx.Flash.Error(ctx.Tr("repo.branch.restore_failed", deletedBranch.Name))
  124. return
  125. }
  126. // Don't return error below this
  127. if err := repo_service.PushUpdate(
  128. &repo_module.PushUpdateOptions{
  129. RefFullName: git.BranchPrefix + deletedBranch.Name,
  130. OldCommitID: git.EmptySHA,
  131. NewCommitID: deletedBranch.Commit,
  132. PusherID: ctx.User.ID,
  133. PusherName: ctx.User.Name,
  134. RepoUserName: ctx.Repo.Owner.Name,
  135. RepoName: ctx.Repo.Repository.Name,
  136. }); err != nil {
  137. log.Error("RestoreBranch: Update: %v", err)
  138. }
  139. ctx.Flash.Success(ctx.Tr("repo.branch.restore_success", deletedBranch.Name))
  140. }
  141. func redirect(ctx *context.Context) {
  142. ctx.JSON(200, map[string]interface{}{
  143. "redirect": ctx.Repo.RepoLink + "/branches",
  144. })
  145. }
  146. func deleteBranch(ctx *context.Context, branchName string) error {
  147. commit, err := ctx.Repo.GitRepo.GetBranchCommit(branchName)
  148. if err != nil {
  149. log.Error("GetBranchCommit: %v", err)
  150. return err
  151. }
  152. if err := ctx.Repo.GitRepo.DeleteBranch(branchName, git.DeleteBranchOptions{
  153. Force: true,
  154. }); err != nil {
  155. log.Error("DeleteBranch: %v", err)
  156. return err
  157. }
  158. // Don't return error below this
  159. if err := repo_service.PushUpdate(
  160. &repo_module.PushUpdateOptions{
  161. RefFullName: git.BranchPrefix + branchName,
  162. OldCommitID: commit.ID.String(),
  163. NewCommitID: git.EmptySHA,
  164. PusherID: ctx.User.ID,
  165. PusherName: ctx.User.Name,
  166. RepoUserName: ctx.Repo.Owner.Name,
  167. RepoName: ctx.Repo.Repository.Name,
  168. }); err != nil {
  169. log.Error("Update: %v", err)
  170. }
  171. if err := ctx.Repo.Repository.AddDeletedBranch(branchName, commit.ID.String(), ctx.User.ID); err != nil {
  172. log.Warn("AddDeletedBranch: %v", err)
  173. }
  174. return nil
  175. }
  176. // loadBranches loads branches from the repository limited by page & pageSize.
  177. // NOTE: May write to context on error.
  178. func loadBranches(ctx *context.Context, skip, limit int) ([]*Branch, int) {
  179. defaultBranch, err := repo_module.GetBranch(ctx.Repo.Repository, ctx.Repo.Repository.DefaultBranch)
  180. if err != nil {
  181. log.Error("loadBranches: get default branch: %v", err)
  182. ctx.ServerError("GetDefaultBranch", err)
  183. return nil, 0
  184. }
  185. rawBranches, totalNumOfBranches, err := repo_module.GetBranches(ctx.Repo.Repository, skip, limit)
  186. if err != nil {
  187. log.Error("GetBranches: %v", err)
  188. ctx.ServerError("GetBranches", err)
  189. return nil, 0
  190. }
  191. protectedBranches, err := ctx.Repo.Repository.GetProtectedBranches()
  192. if err != nil {
  193. ctx.ServerError("GetProtectedBranches", err)
  194. return nil, 0
  195. }
  196. repoIDToRepo := map[int64]*models.Repository{}
  197. repoIDToRepo[ctx.Repo.Repository.ID] = ctx.Repo.Repository
  198. repoIDToGitRepo := map[int64]*git.Repository{}
  199. repoIDToGitRepo[ctx.Repo.Repository.ID] = ctx.Repo.GitRepo
  200. var branches []*Branch
  201. for i := range rawBranches {
  202. if rawBranches[i].Name == defaultBranch.Name {
  203. // Skip default branch
  204. continue
  205. }
  206. var branch = loadOneBranch(ctx, rawBranches[i], protectedBranches, repoIDToRepo, repoIDToGitRepo)
  207. if branch == nil {
  208. return nil, 0
  209. }
  210. branches = append(branches, branch)
  211. }
  212. // Always add the default branch
  213. log.Debug("loadOneBranch: load default: '%s'", defaultBranch.Name)
  214. branches = append(branches, loadOneBranch(ctx, defaultBranch, protectedBranches, repoIDToRepo, repoIDToGitRepo))
  215. if ctx.Repo.CanWrite(models.UnitTypeCode) {
  216. deletedBranches, err := getDeletedBranches(ctx)
  217. if err != nil {
  218. ctx.ServerError("getDeletedBranches", err)
  219. return nil, 0
  220. }
  221. branches = append(branches, deletedBranches...)
  222. }
  223. return branches, totalNumOfBranches - 1
  224. }
  225. func loadOneBranch(ctx *context.Context, rawBranch *git.Branch, protectedBranches []*models.ProtectedBranch,
  226. repoIDToRepo map[int64]*models.Repository,
  227. repoIDToGitRepo map[int64]*git.Repository) *Branch {
  228. log.Trace("loadOneBranch: '%s'", rawBranch.Name)
  229. commit, err := rawBranch.GetCommit()
  230. if err != nil {
  231. ctx.ServerError("GetCommit", err)
  232. return nil
  233. }
  234. branchName := rawBranch.Name
  235. var isProtected bool
  236. for _, b := range protectedBranches {
  237. if b.BranchName == branchName {
  238. isProtected = true
  239. break
  240. }
  241. }
  242. divergence, divergenceError := repofiles.CountDivergingCommits(ctx.Repo.Repository, git.BranchPrefix+branchName)
  243. if divergenceError != nil {
  244. ctx.ServerError("CountDivergingCommits", divergenceError)
  245. return nil
  246. }
  247. pr, err := models.GetLatestPullRequestByHeadInfo(ctx.Repo.Repository.ID, branchName)
  248. if err != nil {
  249. ctx.ServerError("GetLatestPullRequestByHeadInfo", err)
  250. return nil
  251. }
  252. headCommit := commit.ID.String()
  253. mergeMovedOn := false
  254. if pr != nil {
  255. pr.HeadRepo = ctx.Repo.Repository
  256. if err := pr.LoadIssue(); err != nil {
  257. ctx.ServerError("pr.LoadIssue", err)
  258. return nil
  259. }
  260. if repo, ok := repoIDToRepo[pr.BaseRepoID]; ok {
  261. pr.BaseRepo = repo
  262. } else if err := pr.LoadBaseRepo(); err != nil {
  263. ctx.ServerError("pr.LoadBaseRepo", err)
  264. return nil
  265. } else {
  266. repoIDToRepo[pr.BaseRepoID] = pr.BaseRepo
  267. }
  268. pr.Issue.Repo = pr.BaseRepo
  269. if pr.HasMerged {
  270. baseGitRepo, ok := repoIDToGitRepo[pr.BaseRepoID]
  271. if !ok {
  272. baseGitRepo, err = git.OpenRepository(pr.BaseRepo.RepoPath())
  273. if err != nil {
  274. ctx.ServerError("OpenRepository", err)
  275. return nil
  276. }
  277. defer baseGitRepo.Close()
  278. repoIDToGitRepo[pr.BaseRepoID] = baseGitRepo
  279. }
  280. pullCommit, err := baseGitRepo.GetRefCommitID(pr.GetGitRefName())
  281. if err != nil && !git.IsErrNotExist(err) {
  282. ctx.ServerError("GetBranchCommitID", err)
  283. return nil
  284. }
  285. if err == nil && headCommit != pullCommit {
  286. // the head has moved on from the merge - we shouldn't delete
  287. mergeMovedOn = true
  288. }
  289. }
  290. }
  291. isIncluded := divergence.Ahead == 0 && ctx.Repo.Repository.DefaultBranch != branchName
  292. return &Branch{
  293. Name: branchName,
  294. Commit: commit,
  295. IsProtected: isProtected,
  296. IsIncluded: isIncluded,
  297. CommitsAhead: divergence.Ahead,
  298. CommitsBehind: divergence.Behind,
  299. LatestPullRequest: pr,
  300. MergeMovedOn: mergeMovedOn,
  301. }
  302. }
  303. func getDeletedBranches(ctx *context.Context) ([]*Branch, error) {
  304. branches := []*Branch{}
  305. deletedBranches, err := ctx.Repo.Repository.GetDeletedBranches()
  306. if err != nil {
  307. return branches, err
  308. }
  309. for i := range deletedBranches {
  310. deletedBranches[i].LoadUser()
  311. branches = append(branches, &Branch{
  312. Name: deletedBranches[i].Name,
  313. IsDeleted: true,
  314. DeletedBranch: deletedBranches[i],
  315. })
  316. }
  317. return branches, nil
  318. }
  319. // CreateBranch creates new branch in repository
  320. func CreateBranch(ctx *context.Context) {
  321. form := web.GetForm(ctx).(*auth.NewBranchForm)
  322. if !ctx.Repo.CanCreateBranch() {
  323. ctx.NotFound("CreateBranch", nil)
  324. return
  325. }
  326. if ctx.HasError() {
  327. ctx.Flash.Error(ctx.GetErrMsg())
  328. ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL())
  329. return
  330. }
  331. var err error
  332. if ctx.Repo.IsViewBranch {
  333. err = repo_module.CreateNewBranch(ctx.User, ctx.Repo.Repository, ctx.Repo.BranchName, form.NewBranchName)
  334. } else if ctx.Repo.IsViewTag {
  335. err = repo_module.CreateNewBranchFromCommit(ctx.User, ctx.Repo.Repository, ctx.Repo.CommitID, form.NewBranchName)
  336. } else {
  337. err = repo_module.CreateNewBranchFromCommit(ctx.User, ctx.Repo.Repository, ctx.Repo.BranchName, form.NewBranchName)
  338. }
  339. if err != nil {
  340. if models.IsErrTagAlreadyExists(err) {
  341. e := err.(models.ErrTagAlreadyExists)
  342. ctx.Flash.Error(ctx.Tr("repo.branch.tag_collision", e.TagName))
  343. ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL())
  344. return
  345. }
  346. if models.IsErrBranchAlreadyExists(err) || git.IsErrPushOutOfDate(err) {
  347. ctx.Flash.Error(ctx.Tr("repo.branch.branch_already_exists", form.NewBranchName))
  348. ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL())
  349. return
  350. }
  351. if models.IsErrBranchNameConflict(err) {
  352. e := err.(models.ErrBranchNameConflict)
  353. ctx.Flash.Error(ctx.Tr("repo.branch.branch_name_conflict", form.NewBranchName, e.BranchName))
  354. ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL())
  355. return
  356. }
  357. if git.IsErrPushRejected(err) {
  358. e := err.(*git.ErrPushRejected)
  359. if len(e.Message) == 0 {
  360. ctx.Flash.Error(ctx.Tr("repo.editor.push_rejected_no_message"))
  361. } else {
  362. flashError, err := ctx.HTMLString(string(tplAlertDetails), map[string]interface{}{
  363. "Message": ctx.Tr("repo.editor.push_rejected"),
  364. "Summary": ctx.Tr("repo.editor.push_rejected_summary"),
  365. "Details": utils.SanitizeFlashErrorString(e.Message),
  366. })
  367. if err != nil {
  368. ctx.ServerError("UpdatePullRequest.HTMLString", err)
  369. return
  370. }
  371. ctx.Flash.Error(flashError)
  372. }
  373. ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL())
  374. return
  375. }
  376. ctx.ServerError("CreateNewBranch", err)
  377. return
  378. }
  379. ctx.Flash.Success(ctx.Tr("repo.branch.create_success", form.NewBranchName))
  380. ctx.Redirect(ctx.Repo.RepoLink + "/src/branch/" + util.PathEscapeSegments(form.NewBranchName))
  381. }