diff --git a/docs/Makefile b/docs/Makefile
index e5f8d9c6e..78de2d396 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -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 $@)
diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md
index fd385a82a..e0d761bd4 100644
--- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md
+++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md
@@ -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.
diff --git a/integrations/README.md b/integrations/README.md
new file mode 100644
index 000000000..25028fd2b
--- /dev/null
+++ b/integrations/README.md
@@ -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
diff --git a/integrations/pull_create_test.go b/integrations/pull_create_test.go
index 00a23a29e..89abccf88 100644
--- a/integrations/pull_create_test.go
+++ b/integrations/pull_create_test.go
@@ -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
}
diff --git a/models/action_test.go b/models/action_test.go
index 016917905..e0a3e2123 100644
--- a/models/action_test.go
+++ b/models/action_test.go
@@ -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,
diff --git a/models/fixtures/org_user.yml b/models/fixtures/org_user.yml
index 709a1997b..5bb23571f 100644
--- a/models/fixtures/org_user.yml
+++ b/models/fixtures/org_user.yml
@@ -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
\ No newline at end of file
diff --git a/models/issue_comment.go b/models/issue_comment.go
index 305218156..88e72e818 100644
--- a/models/issue_comment.go
+++ b/models/issue_comment.go
@@ -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
diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go
index 51f9c73b1..53f9beac9 100644
--- a/models/migrations/migrations.go
+++ b/models/migrations/migrations.go
@@ -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),
}
diff --git a/models/migrations/v56.go b/models/migrations/v56.go
index 796f9a103..bbaee28a9 100644
--- a/models/migrations/v56.go
+++ b/models/migrations/v56.go
@@ -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
}
diff --git a/models/migrations/v57.go b/models/migrations/v57.go
new file mode 100644
index 000000000..a6ea3eef7
--- /dev/null
+++ b/models/migrations/v57.go
@@ -0,0 +1 @@
+package migrations
diff --git a/models/models.go b/models/models.go
index 8b0dcccb7..f903c25f0 100644
--- a/models/models.go
+++ b/models/models.go
@@ -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
diff --git a/models/org.go b/models/org.go
index a28a8e28e..095265a12 100644
--- a/models/org.go
+++ b/models/org.go
@@ -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)
}
diff --git a/models/org_team.go b/models/org_team.go
index c667cfb8e..941b7ed2a 100644
--- a/models/org_team.go
+++ b/models/org_team.go
@@ -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
}
diff --git a/models/org_test.go b/models/org_test.go
index aef313d05..42ab4a2a4 100644
--- a/models/org_test.go
+++ b/models/org_test.go
@@ -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)
diff --git a/modules/setting/setting.go b/modules/setting/setting.go
index c701a0882..420acd8f1 100644
--- a/modules/setting/setting.go
+++ b/modules/setting/setting.go
@@ -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
diff --git a/options/locale/locale_hu-HU.ini b/options/locale/locale_hu-HU.ini
index d2bb14516..25e7a21c9 100644
--- a/options/locale/locale_hu-HU.ini
+++ b/options/locale/locale_hu-HU.ini
@@ -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=Dingtalk 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 írásra 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
diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini
index 78bf969a5..ed0904b23 100644
--- a/options/locale/locale_lv-LV.ini
+++ b/options/locale/locale_lv-LV.ini
@@ -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 %s uz %s%s %s`
issues.deleted_milestone=`(dzēsts)`
issues.self_assign_at=`piešķīra sev %s`
-issues.add_assignee_at=`piešķīra problēmu %s %s`
+issues.add_assignee_at=`tika piešķirta problēma no %s %s`
issues.remove_assignee_at=`tika noņemta problēma %s`
issues.change_title_at=`nomainīts virsraksts no %s uz %s %s`
issues.delete_branch_at=`izdzēsts atzars %s %s`
@@ -995,6 +997,8 @@ settings.add_dingtalk_hook_desc=Pievienot Dingtalk 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 nosūtītu 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
diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini
index 3e2304f7d..9a541ab77 100644
--- a/options/locale/locale_ru-RU.ini
+++ b/options/locale/locale_ru-RU.ini
@@ -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=Добавить интеграцию с push в репозиторий? Ключи развёртывания всегда имеют доступ на pull.
settings.no_deploy_keys=Вы не добавляли ключи развертывания.
settings.title=Заголовок
settings.deploy_key_content=Содержимое
diff --git a/routers/repo/pull.go b/routers/repo/pull.go
index 26781a2a6..0f6b623ba 100644
--- a/routers/repo/pull.go
+++ b/routers/repo/pull.go
@@ -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<-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
+ }
+}
diff --git a/routers/routes/routes.go b/routers/routes/routes.go
index 5699e3a62..776ac5d09 100644
--- a/routers/routes/routes.go
+++ b/routers/routes/routes.go
@@ -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)
diff --git a/vendor/code.gitea.io/git/MAINTAINERS b/vendor/code.gitea.io/git/MAINTAINERS
index 2ad3f01f5..4f3aab318 100644
--- a/vendor/code.gitea.io/git/MAINTAINERS
+++ b/vendor/code.gitea.io/git/MAINTAINERS
@@ -7,6 +7,7 @@ Kim Carlbäcker (@bkcsoft)
LefsFlare (@LefsFlarey)
Lunny Xiao (@lunny)
Matthias Loibl (@metalmatze)
+Morgan Bazalgette (@thehowl)
Rachid Zarouali (@xinity)
Rémy Boulanouar (@DblK)
Sandro Santilli (@strk)
diff --git a/vendor/code.gitea.io/git/command.go b/vendor/code.gitea.io/git/command.go
index 06722c213..8ca99fd6d 100644
--- a/vendor/code.gitea.io/git/command.go
+++ b/vendor/code.gitea.io/git/command.go
@@ -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 {
diff --git a/vendor/code.gitea.io/git/repo_pull.go b/vendor/code.gitea.io/git/repo_pull.go
index 1c45a4e02..c6d97a6fd 100644
--- a/vendor/code.gitea.io/git/repo_pull.go
+++ b/vendor/code.gitea.io/git/repo_pull.go
@@ -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
+}
diff --git a/vendor/vendor.json b/vendor/vendor.json
index 828bdd4e4..51f758fd2 100644
--- a/vendor/vendor.json
+++ b/vendor/vendor.json
@@ -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=",