Merge branch 'master' of https://github.com/go-gitea/gitea
# Conflicts: # models/migrations/migrations.go # models/migrations/v56.go
This commit is contained in:
commit
4d15f28e04
|
|
@ -24,6 +24,7 @@ build: $(THEME)
|
|||
.PHONY: update
|
||||
update: $(THEME)
|
||||
|
||||
$(THEME):
|
||||
mkdir -p $@
|
||||
curl -s $(ARCHIVE) | tar xz -C $@
|
||||
$(THEME): $(THEME)/theme.toml
|
||||
$(THEME)/theme.toml:
|
||||
mkdir -p $$(dirname $@)
|
||||
curl -s $(ARCHIVE) | tar xz -C $$(dirname $@)
|
||||
|
|
|
|||
|
|
@ -101,6 +101,14 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
|||
- `SSL_MODE`: **disable**: For PostgreSQL only.
|
||||
- `PATH`: **data/gitea.db**: For SQLite3 only, the database file path.
|
||||
|
||||
## Indexer (`indexer`)
|
||||
|
||||
- `ISSUE_INDEXER_PATH`: **indexers/issues.bleve**: Index file used for issue search.
|
||||
- `REPO_INDEXER_ENABLED`: **false**: Enables code search (uses a lot of disk space).
|
||||
- `REPO_INDEXER_PATH`: **indexers/repos.bleve**: Index file used for code search.
|
||||
- `UPDATE_BUFFER_LEN`: **20**: Buffer length of index request.
|
||||
- `MAX_FILE_SIZE`: **1048576**: Maximum size in bytes of each index files.
|
||||
|
||||
## Security (`security`)
|
||||
|
||||
- `INSTALL_LOCK`: **false**: Disable to allow accessing the install page.
|
||||
|
|
|
|||
22
integrations/README.md
Normal file
22
integrations/README.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
Integration tests can be run with make commands for the
|
||||
appropriate backends, namely:
|
||||
|
||||
make test-mysql
|
||||
make test-pgsql
|
||||
make test-sqlite
|
||||
|
||||
# Running individual tests
|
||||
|
||||
Example command to run GPG test with sqlite backend:
|
||||
|
||||
```
|
||||
go test -c code.gitea.io/gitea/integrations \
|
||||
-o integrations.sqlite.test -tags 'sqlite' &&
|
||||
GITEA_ROOT="$GOPATH/src/code.gitea.io/gitea" \
|
||||
GITEA_CONF=integrations/sqlite.ini ./integrations.sqlite.test \
|
||||
-test.v -test.run GPG
|
||||
```
|
||||
|
||||
Make sure to perform a clean build before running tests:
|
||||
|
||||
make clean build
|
||||
|
|
@ -56,7 +56,15 @@ func TestPullCreate(t *testing.T) {
|
|||
// check .diff can be accessed and matches performed change
|
||||
req := NewRequest(t, "GET", url+".diff")
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
assert.Regexp(t, "\\+Hello, World \\(Edited\\)", resp.Body)
|
||||
assert.Regexp(t, `\+Hello, World \(Edited\)`, resp.Body)
|
||||
assert.Regexp(t, "^diff", resp.Body)
|
||||
assert.NotRegexp(t, "diff.*diff", resp.Body) // not two diffs, just one
|
||||
|
||||
// check .patch can be accessed and matches performed change
|
||||
req = NewRequest(t, "GET", url+".patch")
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
assert.Regexp(t, `\+Hello, World \(Edited\)`, resp.Body)
|
||||
assert.Regexp(t, "diff", resp.Body)
|
||||
assert.Regexp(t, `Subject: \[PATCH\] Update 'README.md'`, resp.Body)
|
||||
assert.NotRegexp(t, "diff.*diff", resp.Body) // not two diffs, just one
|
||||
}
|
||||
|
|
|
|||
|
|
@ -425,7 +425,7 @@ func TestGetFeeds2(t *testing.T) {
|
|||
// test with an organization user
|
||||
assert.NoError(t, PrepareTestDatabase())
|
||||
org := AssertExistsAndLoadBean(t, &User{ID: 3}).(*User)
|
||||
userID := AssertExistsAndLoadBean(t, &OrgUser{OrgID: org.ID, IsOwner: true}).(*OrgUser).UID
|
||||
const userID = 2 // user2 is an owner of the organization
|
||||
|
||||
actions, err := GetFeeds(GetFeedsOptions{
|
||||
RequestedUser: org,
|
||||
|
|
|
|||
|
|
@ -3,53 +3,39 @@
|
|||
uid: 2
|
||||
org_id: 3
|
||||
is_public: true
|
||||
is_owner: true
|
||||
num_teams: 1
|
||||
|
||||
-
|
||||
id: 2
|
||||
uid: 4
|
||||
org_id: 3
|
||||
is_public: false
|
||||
is_owner: false
|
||||
num_teams: 0
|
||||
|
||||
-
|
||||
id: 3
|
||||
uid: 5
|
||||
org_id: 6
|
||||
is_public: true
|
||||
is_owner: true
|
||||
num_teams: 1
|
||||
|
||||
-
|
||||
id: 4
|
||||
uid: 5
|
||||
org_id: 7
|
||||
is_public: false
|
||||
is_owner: true
|
||||
num_teams: 1
|
||||
|
||||
-
|
||||
id: 5
|
||||
uid: 15
|
||||
org_id: 17
|
||||
is_public: true
|
||||
is_owner: true
|
||||
num_teams: 1
|
||||
|
||||
-
|
||||
id: 6
|
||||
uid: 18
|
||||
org_id: 17
|
||||
is_public: false
|
||||
is_owner: true
|
||||
num_teams: 1
|
||||
|
||||
-
|
||||
id: 7
|
||||
uid: 20
|
||||
org_id: 19
|
||||
is_public: true
|
||||
is_owner: true
|
||||
num_teams: 1
|
||||
|
|
@ -253,14 +253,20 @@ func (c *Comment) LoadAssignees() error {
|
|||
if c.OldAssigneeID > 0 {
|
||||
c.OldAssignee, err = getUserByID(x, c.OldAssigneeID)
|
||||
if err != nil {
|
||||
return err
|
||||
if !IsErrUserNotExist(err) {
|
||||
return err
|
||||
}
|
||||
c.OldAssignee = NewGhostUser()
|
||||
}
|
||||
}
|
||||
|
||||
if c.AssigneeID > 0 {
|
||||
c.Assignee, err = getUserByID(x, c.AssigneeID)
|
||||
if err != nil {
|
||||
return err
|
||||
if !IsErrUserNotExist(err) {
|
||||
return err
|
||||
}
|
||||
c.Assignee = NewGhostUser()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -165,6 +165,8 @@ var migrations = []Migration{
|
|||
// v55 -> v56
|
||||
NewMigration("add writable deploy keys", addModeToDeploKeys),
|
||||
// v56 -> v57
|
||||
NewMigration("remove is_owner, num_teams columns from org_user", removeIsOwnerColumnFromOrgUser),
|
||||
// v57 -> v58
|
||||
NewMigration("add issue_dependencies", addIssueDependencies),
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,56 +5,29 @@
|
|||
package migrations
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"github.com/go-xorm/xorm"
|
||||
"time"
|
||||
)
|
||||
|
||||
func addIssueDependencies(x *xorm.Engine) (err error) {
|
||||
|
||||
type IssueDependency struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
UserID int64 `xorm:"NOT NULL"`
|
||||
IssueID int64 `xorm:"NOT NULL"`
|
||||
DependencyID int64 `xorm:"NOT NULL"`
|
||||
Created time.Time `xorm:"-"`
|
||||
CreatedUnix int64 `xorm:"INDEX created"`
|
||||
Updated time.Time `xorm:"-"`
|
||||
UpdatedUnix int64 `xorm:"updated"`
|
||||
}
|
||||
|
||||
if err = x.Sync(new(IssueDependency)); err != nil {
|
||||
return fmt.Errorf("Error creating issue_dependency_table column definition: %v", err)
|
||||
}
|
||||
|
||||
// RepoUnit describes all units of a repository
|
||||
type RepoUnit struct {
|
||||
ID int64
|
||||
RepoID int64 `xorm:"INDEX(s)"`
|
||||
Type int `xorm:"INDEX(s)"`
|
||||
Config map[string]interface{} `xorm:"JSON"`
|
||||
CreatedUnix int64 `xorm:"INDEX CREATED"`
|
||||
Created time.Time `xorm:"-"`
|
||||
}
|
||||
|
||||
//Updating existing issue units
|
||||
units := make([]*RepoUnit, 0, 100)
|
||||
err = x.Where("`type` = ?", V16UnitTypeIssues).Find(&units)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Query repo units: %v", err)
|
||||
}
|
||||
for _, unit := range units {
|
||||
if unit.Config == nil {
|
||||
unit.Config = make(map[string]interface{})
|
||||
func removeIsOwnerColumnFromOrgUser(x *xorm.Engine) (err error) {
|
||||
switch {
|
||||
case setting.UseSQLite3:
|
||||
log.Warn("Unable to drop columns in SQLite")
|
||||
case setting.UseMySQL, setting.UseTiDB, setting.UsePostgreSQL:
|
||||
if _, err := x.Exec("ALTER TABLE org_user DROP COLUMN is_owner, DROP COLUMN num_teams"); err != nil {
|
||||
return fmt.Errorf("DROP COLUMN org_user.is_owner, org_user.num_teams: %v", err)
|
||||
}
|
||||
if _, ok := unit.Config["EnableDependencies"]; !ok {
|
||||
unit.Config["EnableDependencies"] = setting.Service.DefaultEnableDependencies
|
||||
}
|
||||
if _, err := x.ID(unit.ID).Cols("config").Update(unit); err != nil {
|
||||
return err
|
||||
case setting.UseMSSQL:
|
||||
if _, err := x.Exec("ALTER TABLE org_user DROP COLUMN is_owner, num_teams"); err != nil {
|
||||
return fmt.Errorf("DROP COLUMN org_user.is_owner, org_user.num_teams: %v", err)
|
||||
}
|
||||
default:
|
||||
log.Fatal(4, "Unrecognized DB")
|
||||
}
|
||||
|
||||
return err
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
1
models/migrations/v57.go
Normal file
1
models/migrations/v57.go
Normal file
|
|
@ -0,0 +1 @@
|
|||
package migrations
|
||||
|
|
@ -165,7 +165,7 @@ func LoadConfigs() {
|
|||
setting.Indexer.RepoPath = path.Join(setting.AppWorkPath, setting.Indexer.RepoPath)
|
||||
}
|
||||
setting.Indexer.UpdateQueueLength = sec.Key("UPDATE_BUFFER_LEN").MustInt(20)
|
||||
setting.Indexer.MaxIndexerFileSize = sec.Key("MAX_FILE_SIZE").MustInt64(512 * 1024 * 1024)
|
||||
setting.Indexer.MaxIndexerFileSize = sec.Key("MAX_FILE_SIZE").MustInt64(1024 * 1024)
|
||||
}
|
||||
|
||||
// parsePostgreSQLHostPort parses given input in various forms defined in
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
"github.com/go-xorm/builder"
|
||||
"github.com/go-xorm/xorm"
|
||||
|
|
@ -139,10 +141,8 @@ func CreateOrganization(org, owner *User) (err error) {
|
|||
|
||||
// Add initial creator to organization and owner team.
|
||||
if _, err = sess.Insert(&OrgUser{
|
||||
UID: owner.ID,
|
||||
OrgID: org.ID,
|
||||
IsOwner: true,
|
||||
NumTeams: 1,
|
||||
UID: owner.ID,
|
||||
OrgID: org.ID,
|
||||
}); err != nil {
|
||||
return fmt.Errorf("insert org-user relation: %v", err)
|
||||
}
|
||||
|
|
@ -280,18 +280,25 @@ type OrgUser struct {
|
|||
UID int64 `xorm:"INDEX UNIQUE(s)"`
|
||||
OrgID int64 `xorm:"INDEX UNIQUE(s)"`
|
||||
IsPublic bool `xorm:"INDEX"`
|
||||
IsOwner bool
|
||||
NumTeams int
|
||||
}
|
||||
|
||||
func isOrganizationOwner(e Engine, orgID, uid int64) (bool, error) {
|
||||
ownerTeam := &Team{
|
||||
OrgID: orgID,
|
||||
Name: ownerTeamName,
|
||||
}
|
||||
if has, err := e.Get(ownerTeam); err != nil {
|
||||
return false, err
|
||||
} else if !has {
|
||||
log.Error(4, "Organization does not have owner team: %d", orgID)
|
||||
return false, nil
|
||||
}
|
||||
return isTeamMember(e, orgID, ownerTeam.ID, uid)
|
||||
}
|
||||
|
||||
// IsOrganizationOwner returns true if given user is in the owner team.
|
||||
func IsOrganizationOwner(orgID, uid int64) (bool, error) {
|
||||
return x.
|
||||
Where("is_owner=?", true).
|
||||
And("uid=?", uid).
|
||||
And("org_id=?", orgID).
|
||||
Table("org_user").
|
||||
Exist()
|
||||
return isOrganizationOwner(x, orgID, uid)
|
||||
}
|
||||
|
||||
// IsOrganizationMember returns true if given user is member of organization.
|
||||
|
|
@ -336,9 +343,10 @@ func GetOrgsByUserID(userID int64, showAll bool) ([]*User, error) {
|
|||
func getOwnedOrgsByUserID(sess *xorm.Session, userID int64) ([]*User, error) {
|
||||
orgs := make([]*User, 0, 10)
|
||||
return orgs, sess.
|
||||
Where("`org_user`.uid=?", userID).
|
||||
And("`org_user`.is_owner=?", true).
|
||||
Join("INNER", "`org_user`", "`org_user`.org_id=`user`.id").
|
||||
Join("INNER", "`team_user`", "`team_user`.org_id=`user`.id").
|
||||
Join("INNER", "`team`", "`team`.id=`team_user`.team_id").
|
||||
Where("`team_user`.uid=?", userID).
|
||||
And("`team`.authorize=?", AccessModeOwner).
|
||||
Asc("`user`.name").
|
||||
Find(&orgs)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -518,22 +518,6 @@ func AddTeamMember(team *Team, userID int64) error {
|
|||
}
|
||||
}
|
||||
|
||||
// We make sure it exists before.
|
||||
ou := new(OrgUser)
|
||||
if _, err := sess.
|
||||
Where("uid = ?", userID).
|
||||
And("org_id = ?", team.OrgID).
|
||||
Get(ou); err != nil {
|
||||
return err
|
||||
}
|
||||
ou.NumTeams++
|
||||
if team.IsOwnerTeam() {
|
||||
ou.IsOwner = true
|
||||
}
|
||||
if _, err := sess.ID(ou.ID).Cols("num_teams, is_owner").Update(ou); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
|
|
@ -574,25 +558,6 @@ func removeTeamMember(e Engine, team *Team, userID int64) error {
|
|||
}
|
||||
}
|
||||
|
||||
// This must exist.
|
||||
ou := new(OrgUser)
|
||||
_, err = e.
|
||||
Where("uid = ?", userID).
|
||||
And("org_id = ?", team.OrgID).
|
||||
Get(ou)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ou.NumTeams--
|
||||
if team.IsOwnerTeam() {
|
||||
ou.IsOwner = false
|
||||
}
|
||||
if _, err = e.
|
||||
ID(ou.ID).
|
||||
Cols("num_teams").
|
||||
Update(ou); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -368,16 +368,12 @@ func TestGetOrgUsersByUserID(t *testing.T) {
|
|||
ID: orgUsers[0].ID,
|
||||
OrgID: 6,
|
||||
UID: 5,
|
||||
IsOwner: true,
|
||||
IsPublic: true,
|
||||
NumTeams: 1}, *orgUsers[0])
|
||||
IsPublic: true}, *orgUsers[0])
|
||||
assert.Equal(t, OrgUser{
|
||||
ID: orgUsers[1].ID,
|
||||
OrgID: 7,
|
||||
UID: 5,
|
||||
IsOwner: true,
|
||||
IsPublic: false,
|
||||
NumTeams: 1}, *orgUsers[1])
|
||||
IsPublic: false}, *orgUsers[1])
|
||||
}
|
||||
|
||||
publicOrgUsers, err := GetOrgUsersByUserID(5, false)
|
||||
|
|
@ -400,16 +396,12 @@ func TestGetOrgUsersByOrgID(t *testing.T) {
|
|||
ID: orgUsers[0].ID,
|
||||
OrgID: 3,
|
||||
UID: 2,
|
||||
IsOwner: true,
|
||||
IsPublic: true,
|
||||
NumTeams: 1}, *orgUsers[0])
|
||||
IsPublic: true}, *orgUsers[0])
|
||||
assert.Equal(t, OrgUser{
|
||||
ID: orgUsers[1].ID,
|
||||
OrgID: 3,
|
||||
UID: 4,
|
||||
IsOwner: false,
|
||||
IsPublic: false,
|
||||
NumTeams: 0}, *orgUsers[1])
|
||||
IsPublic: false}, *orgUsers[1])
|
||||
}
|
||||
|
||||
orgUsers, err = GetOrgUsersByOrgID(NonexistentID)
|
||||
|
|
|
|||
|
|
@ -1038,7 +1038,7 @@ func NewContext() {
|
|||
GravatarSource = source
|
||||
}
|
||||
DisableGravatar = sec.Key("DISABLE_GRAVATAR").MustBool()
|
||||
EnableFederatedAvatar = sec.Key("ENABLE_FEDERATED_AVATAR").MustBool()
|
||||
EnableFederatedAvatar = sec.Key("ENABLE_FEDERATED_AVATAR").MustBool(!InstallLock)
|
||||
if OfflineMode {
|
||||
DisableGravatar = true
|
||||
EnableFederatedAvatar = false
|
||||
|
|
|
|||
|
|
@ -401,6 +401,8 @@ valid_until=Érvényesség vége:
|
|||
valid_forever=Érvényes örökre
|
||||
last_used=Utolsó használat:
|
||||
no_activity=Mostanság nem aktívan használt
|
||||
can_read_info=Csak olvasásra
|
||||
can_write_info=Írásra is
|
||||
key_state_desc=Ezt a kulcsot már használta az elmúlt 7 napban
|
||||
token_state_desc=Ez a token volt használva az elmúlt 7 napban
|
||||
show_openid=Megjelenítés a profilon
|
||||
|
|
@ -995,6 +997,8 @@ settings.add_dingtalk_hook_desc=<a href="%s">Dingtalk</a> integráció hozzáad
|
|||
settings.deploy_keys=Telepítési kulcsok
|
||||
settings.add_deploy_key=Telepítési kulcs hozzáadása
|
||||
settings.deploy_key_desc=A Deploy kulcsoknak csak olvasási joga van. Nem ugyan azok mint a személyes SSH kulcsok.
|
||||
settings.is_writable=Írási hozzáférés engedélyezése
|
||||
settings.is_writable_info=Használható ez a kulcs a tárolóba <strong>írásra</strong> is? A telepítési kulcsok olvasásra mindig használhatóak.
|
||||
settings.no_deploy_keys=Még nem adott hozzá egyetlen Deploy kulcsot sem.
|
||||
settings.title=Cím
|
||||
settings.deploy_key_content=Tartalom
|
||||
|
|
|
|||
|
|
@ -401,6 +401,8 @@ valid_until=Derīga līdz
|
|||
valid_forever=Derīgs mūžīgi
|
||||
last_used=Pēdējo reizi izmantota
|
||||
no_activity=Nav nesenas aktivitātes
|
||||
can_read_info=Lasīt
|
||||
can_write_info=Rakstīt
|
||||
key_state_desc=Šī atslēga ir izmantota pēdējo 7 dienu laikā
|
||||
token_state_desc=Šis talons ir izmantots pēdējo 7 dienu laikā
|
||||
show_openid=Rādīt profilā
|
||||
|
|
@ -638,7 +640,7 @@ issues.change_milestone_at=`nomainīja atskaites punktu no <b>%s</b> uz <b>%s</b
|
|||
issues.remove_milestone_at=`noņēma atskaites punktu <b>%s</b> %s`
|
||||
issues.deleted_milestone=`(dzēsts)`
|
||||
issues.self_assign_at=`piešķīra sev %s`
|
||||
issues.add_assignee_at=`piešķīra problēmu <b>%s</b> %s`
|
||||
issues.add_assignee_at=`tika piešķirta problēma no <b>%s</b> %s`
|
||||
issues.remove_assignee_at=`tika noņemta problēma %s`
|
||||
issues.change_title_at=`nomainīts virsraksts no <b>%s</b> uz <b>%s</b> %s`
|
||||
issues.delete_branch_at=`izdzēsts atzars <b>%s</b> %s`
|
||||
|
|
@ -995,6 +997,8 @@ settings.add_dingtalk_hook_desc=Pievienot <a href="%s">Dingtalk</a> integrāciju
|
|||
settings.deploy_keys=Izvietot atslēgas
|
||||
settings.add_deploy_key=Pievienot izvietošanas atslēgu
|
||||
settings.deploy_key_desc=Izvietošanas atslēgai ir tikai lasīšanas piekļuve. Tā nav tā pati kā Jūsu personīgā konta SSH atslēga.
|
||||
settings.is_writable=Atļaut rakstīt
|
||||
settings.is_writable_info=Vai šī atslēga var tikt izmantota, lai <strong>nosūtītu</strong> izmaiņas uz šo repozitoriju? Izvietošanas atslēgām vienmēr ir tiesības saņemt izmaiņas.
|
||||
settings.no_deploy_keys=Nav pievienota neviena izvietošanas atslēga.
|
||||
settings.title=Virsraksts
|
||||
settings.deploy_key_content=Saturs
|
||||
|
|
|
|||
|
|
@ -401,6 +401,8 @@ valid_until=Действителен до
|
|||
valid_forever=Действителен навсегда
|
||||
last_used=Последний раз использовался
|
||||
no_activity=Еще не применялся
|
||||
can_read_info=Чтение
|
||||
can_write_info=Запись
|
||||
key_state_desc=Этот ключ использовался в течение последних 7 дней
|
||||
token_state_desc=Этот токен использовался в течение последних 7 дней
|
||||
show_openid=Показывать в профиле
|
||||
|
|
@ -995,6 +997,8 @@ settings.add_dingtalk_hook_desc=Добавить интеграцию с <a href
|
|||
settings.deploy_keys=Ключи развертывания
|
||||
settings.add_deploy_key=Добавить ключ развертывания
|
||||
settings.deploy_key_desc=Ключи развёртывания доступны только для чтения. Это не то же самое что и SSH-ключи аккаунта.
|
||||
settings.is_writable=Разрешить доступ на запись
|
||||
settings.is_writable_info=Может ли этот ключ быть использован для выполнения <strong>push</strong> в репозиторий? Ключи развёртывания всегда имеют доступ на pull.
|
||||
settings.no_deploy_keys=Вы не добавляли ключи развертывания.
|
||||
settings.title=Заголовок
|
||||
settings.deploy_key_content=Содержимое
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ package repo
|
|||
import (
|
||||
"container/list"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
|
|
@ -580,7 +582,19 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
|
|||
// format: <base branch>...[<head repo>:]<head branch>
|
||||
// base<-head: master...head:feature
|
||||
// same repo: master...feature
|
||||
infos := strings.Split(ctx.Params("*"), "...")
|
||||
|
||||
var (
|
||||
headUser *models.User
|
||||
headBranch string
|
||||
isSameRepo bool
|
||||
infoPath string
|
||||
err error
|
||||
)
|
||||
infoPath, err = url.QueryUnescape(ctx.Params("*"))
|
||||
if err != nil {
|
||||
ctx.Handle(404, "QueryUnescape", err)
|
||||
}
|
||||
infos := strings.Split(infoPath, "...")
|
||||
if len(infos) != 2 {
|
||||
log.Trace("ParseCompareInfo[%d]: not enough compared branches information %s", baseRepo.ID, infos)
|
||||
ctx.Handle(404, "CompareAndPullRequest", nil)
|
||||
|
|
@ -590,13 +604,6 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
|
|||
baseBranch := infos[0]
|
||||
ctx.Data["BaseBranch"] = baseBranch
|
||||
|
||||
var (
|
||||
headUser *models.User
|
||||
headBranch string
|
||||
isSameRepo bool
|
||||
err error
|
||||
)
|
||||
|
||||
// If there is no head repository, it means pull request between same repository.
|
||||
headInfos := strings.Split(infos[1], ":")
|
||||
if len(headInfos) == 1 {
|
||||
|
|
@ -1045,7 +1052,7 @@ func DownloadPullDiff(ctx *context.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
// Redirect elsewhere if it's not a pull request
|
||||
// Return not found if it's not a pull request
|
||||
if !issue.IsPull {
|
||||
ctx.Handle(404, "DownloadPullDiff",
|
||||
fmt.Errorf("Issue is not a pull request"))
|
||||
|
|
@ -1066,3 +1073,48 @@ func DownloadPullDiff(ctx *context.Context) {
|
|||
|
||||
ctx.ServeFileContent(patch)
|
||||
}
|
||||
|
||||
// DownloadPullPatch render a pull's raw patch
|
||||
func DownloadPullPatch(ctx *context.Context) {
|
||||
issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
|
||||
if err != nil {
|
||||
if models.IsErrIssueNotExist(err) {
|
||||
ctx.Handle(404, "GetIssueByIndex", err)
|
||||
} else {
|
||||
ctx.Handle(500, "GetIssueByIndex", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Return not found if it's not a pull request
|
||||
if !issue.IsPull {
|
||||
ctx.Handle(404, "DownloadPullDiff",
|
||||
fmt.Errorf("Issue is not a pull request"))
|
||||
return
|
||||
}
|
||||
|
||||
pr := issue.PullRequest
|
||||
|
||||
if err = pr.GetHeadRepo(); err != nil {
|
||||
ctx.Handle(500, "GetHeadRepo", err)
|
||||
return
|
||||
}
|
||||
|
||||
headGitRepo, err := git.OpenRepository(pr.HeadRepo.RepoPath())
|
||||
if err != nil {
|
||||
ctx.Handle(500, "OpenRepository", err)
|
||||
return
|
||||
}
|
||||
|
||||
patch, err := headGitRepo.GetFormatPatch(pr.MergeBase, pr.HeadBranch)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "GetFormatPatch", err)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = io.Copy(ctx, patch)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "io.Copy", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -629,6 +629,7 @@ func RegisterRoutes(m *macaron.Macaron) {
|
|||
|
||||
m.Group("/pulls/:index", func() {
|
||||
m.Get(".diff", repo.DownloadPullDiff)
|
||||
m.Get(".patch", repo.DownloadPullPatch)
|
||||
m.Get("/commits", context.RepoRef(), repo.ViewPullCommits)
|
||||
m.Get("/files", context.RepoRef(), repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.ViewPullFiles)
|
||||
m.Post("/merge", reqRepoWriter, bindIgnErr(auth.MergePullRequestForm{}), repo.MergePullRequest)
|
||||
|
|
|
|||
1
vendor/code.gitea.io/git/MAINTAINERS
generated
vendored
1
vendor/code.gitea.io/git/MAINTAINERS
generated
vendored
|
|
@ -7,6 +7,7 @@ Kim Carlbäcker <kim.carlbacker@gmail.com> (@bkcsoft)
|
|||
LefsFlare <nobody@nobody.tld> (@LefsFlarey)
|
||||
Lunny Xiao <xiaolunwen@gmail.com> (@lunny)
|
||||
Matthias Loibl <mail@matthiasloibl.com> (@metalmatze)
|
||||
Morgan Bazalgette <the@howl.moe> (@thehowl)
|
||||
Rachid Zarouali <nobody@nobody.tld> (@xinity)
|
||||
Rémy Boulanouar <admin@dblk.org> (@DblK)
|
||||
Sandro Santilli <strk@kbt.io> (@strk)
|
||||
|
|
|
|||
5
vendor/code.gitea.io/git/command.go
generated
vendored
5
vendor/code.gitea.io/git/command.go
generated
vendored
|
|
@ -17,6 +17,9 @@ import (
|
|||
var (
|
||||
// GlobalCommandArgs global command args for external package setting
|
||||
GlobalCommandArgs []string
|
||||
|
||||
// DefaultCommandExecutionTimeout default command execution timeout duration
|
||||
DefaultCommandExecutionTimeout = 60 * time.Second
|
||||
)
|
||||
|
||||
// Command represents a command with its subcommands or arguments.
|
||||
|
|
@ -50,7 +53,7 @@ func (c *Command) AddArguments(args ...string) *Command {
|
|||
// it pipes stdout and stderr to given io.Writer.
|
||||
func (c *Command) RunInDirTimeoutPipeline(timeout time.Duration, dir string, stdout, stderr io.Writer) error {
|
||||
if timeout == -1 {
|
||||
timeout = 60 * time.Second
|
||||
timeout = DefaultCommandExecutionTimeout
|
||||
}
|
||||
|
||||
if len(dir) == 0 {
|
||||
|
|
|
|||
14
vendor/code.gitea.io/git/repo_pull.go
generated
vendored
14
vendor/code.gitea.io/git/repo_pull.go
generated
vendored
|
|
@ -5,8 +5,10 @@
|
|||
package git
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"container/list"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
|
@ -73,3 +75,15 @@ func (repo *Repository) GetPullRequestInfo(basePath, baseBranch, headBranch stri
|
|||
func (repo *Repository) GetPatch(base, head string) ([]byte, error) {
|
||||
return NewCommand("diff", "-p", "--binary", base, head).RunInDirBytes(repo.Path)
|
||||
}
|
||||
|
||||
// GetFormatPatch generates and returns format-patch data between given revisions.
|
||||
func (repo *Repository) GetFormatPatch(base, head string) (io.Reader, error) {
|
||||
stdout := new(bytes.Buffer)
|
||||
stderr := new(bytes.Buffer)
|
||||
|
||||
if err := NewCommand("format-patch", "--binary", "--stdout", base+"..."+head).
|
||||
RunInDirPipeline(repo.Path, stdout, stderr); err != nil {
|
||||
return nil, concatenateError(err, stderr.String())
|
||||
}
|
||||
return stdout, nil
|
||||
}
|
||||
|
|
|
|||
6
vendor/vendor.json
vendored
6
vendor/vendor.json
vendored
|
|
@ -3,10 +3,10 @@
|
|||
"ignore": "test appengine",
|
||||
"package": [
|
||||
{
|
||||
"checksumSHA1": "Em29XiKkOh5rFFXdkCjqqsQ7fe4=",
|
||||
"checksumSHA1": "1WHdGmDRsFRTD5N69l+MEbZr+nM=",
|
||||
"path": "code.gitea.io/git",
|
||||
"revision": "4ec3654064ef7eef4f05f891073a38039ad8d0f7",
|
||||
"revisionTime": "2017-12-22T02:43:26Z"
|
||||
"revision": "f4a91053671bee69f1995e456c1541668717c19d",
|
||||
"revisionTime": "2018-01-07T06:11:05Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "Qtq0kW+BnpYMOriaoCjMa86WGG8=",
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user