mirror of
https://github.com/go-gitea/gitea.git
synced 2025-11-13 02:02:53 +09:00
Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f73fff053 | ||
|
|
fb5af37b3e | ||
|
|
2ef37522b6 | ||
|
|
46ff639a13 | ||
|
|
0b91aaf62a | ||
|
|
4a08d574cf | ||
|
|
f104898989 | ||
|
|
83d04df365 | ||
|
|
9614bb1b9f | ||
|
|
b2c3a7d79f | ||
|
|
76bbcf1387 | ||
|
|
1bcbc02045 | ||
|
|
66ceee08dc | ||
|
|
ffff835b73 | ||
|
|
63c54f7e1f | ||
|
|
f9845454cf | ||
|
|
1e1211c194 | ||
|
|
10e549df7d | ||
|
|
519f69eb41 | ||
|
|
d4501ece55 | ||
|
|
c1152b15fe | ||
|
|
cb31f88383 | ||
|
|
6cb9ce1367 | ||
|
|
d93d5d7906 | ||
|
|
5c3863c319 | ||
|
|
80b50afe1f | ||
|
|
20a28b785a | ||
|
|
d330b2f52b |
32
CHANGELOG.md
32
CHANGELOG.md
@@ -4,6 +4,38 @@ This changelog goes through all the changes that have been made in each release
|
|||||||
without substantial changes to our git log; to see the highlights of what has
|
without substantial changes to our git log; to see the highlights of what has
|
||||||
been added to each release, please refer to the [blog](https://blog.gitea.io).
|
been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||||
|
|
||||||
|
## [1.9.6](https://github.com/go-gitea/gitea/releases/tag/v1.9.6) - 2019-11-13
|
||||||
|
* BUGFIXES
|
||||||
|
* Allow to merge if file path contains " or \ (#8629) (#8772)
|
||||||
|
* Fix 500 when edit hook (#8782) (#8790)
|
||||||
|
* Fix issue with user.fullname (#8904)
|
||||||
|
* Update Github Migration Test (#8897) (#8946)
|
||||||
|
* Add Close() method to gogitRepository (#8901) (#8958)
|
||||||
|
|
||||||
|
## [1.9.5](https://github.com/go-gitea/gitea/releases/tag/v1.9.5) - 2019-10-30
|
||||||
|
* BREAKING
|
||||||
|
* Hide some user information via API if user doesn't have enough permission (#8655) (#8658)
|
||||||
|
* BUGFIXES
|
||||||
|
* Fix milestone close timestamp (#8728) (#8731)
|
||||||
|
* Fix deadline on update issue or PR via API (#8699)
|
||||||
|
* Fix 'New Issue Missing Milestone Comment' (#8678) (#8682)
|
||||||
|
* Fix 500 when getting user as unauthenticated user (#8653) (#8662)
|
||||||
|
* Use AppSubUrl for more redirections (#8647) (#8652)
|
||||||
|
* Add SubURL to redirect path (#8632) (#8634) (#8640)
|
||||||
|
* Fix #8582 by handling empty repos (#8587) (#8593)
|
||||||
|
* Fix bug on pull requests when transfer head repository (#8571)
|
||||||
|
* Add missed close in ServeBlobLFS (#8527) (#8543)
|
||||||
|
* Return false if provided branch name is empty for IsBranchExist (#8485) (#8492)
|
||||||
|
* Create .ssh dir as necessary (#8369) (#8486) (#8489)
|
||||||
|
* Restore functionality for early gits (#7775) (#8476)
|
||||||
|
* Add check for empty set when dropping indexes during migration (#8475)
|
||||||
|
* Ensure Request Body Readers are closed in LFS server (#8454) (#8459)
|
||||||
|
* Ensure that LFS files are relative to the LFS content path (#8455) (#8458)
|
||||||
|
* SECURITY
|
||||||
|
* Ignore mentions for users with no access (#8395) (#8484)
|
||||||
|
* TESTING
|
||||||
|
* Update heatmap fixtures to restore tests (#8615) (#8617)
|
||||||
|
|
||||||
## [1.9.4](https://github.com/go-gitea/gitea/releases/tag/v1.9.4) - 2019-10-08
|
## [1.9.4](https://github.com/go-gitea/gitea/releases/tag/v1.9.4) - 2019-10-08
|
||||||
* BUGFIXES
|
* BUGFIXES
|
||||||
* Highlight issue references (#8101) (#8404)
|
* Highlight issue references (#8101) (#8404)
|
||||||
|
|||||||
@@ -374,17 +374,20 @@ func runRepoSyncReleases(c *cli.Context) error {
|
|||||||
|
|
||||||
if err = models.SyncReleasesWithTags(repo, gitRepo); err != nil {
|
if err = models.SyncReleasesWithTags(repo, gitRepo); err != nil {
|
||||||
log.Warn(" SyncReleasesWithTags: %v", err)
|
log.Warn(" SyncReleasesWithTags: %v", err)
|
||||||
|
gitRepo.Close()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
count, err = getReleaseCount(repo.ID)
|
count, err = getReleaseCount(repo.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn(" GetReleaseCountByRepoID: %v", err)
|
log.Warn(" GetReleaseCountByRepoID: %v", err)
|
||||||
|
gitRepo.Close()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Trace(" repo %s releases synchronized to tags: from %d to %d",
|
log.Trace(" repo %s releases synchronized to tags: from %d to %d",
|
||||||
repo.FullName(), oldnum, count)
|
repo.FullName(), oldnum, count)
|
||||||
|
gitRepo.Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ type Uploader interface {
|
|||||||
CreateComment(issueNumber int64, comment *Comment) error
|
CreateComment(issueNumber int64, comment *Comment) error
|
||||||
CreatePullRequest(pr *PullRequest) error
|
CreatePullRequest(pr *PullRequest) error
|
||||||
Rollback() error
|
Rollback() error
|
||||||
|
Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
2
go.mod
2
go.mod
@@ -83,8 +83,6 @@ require (
|
|||||||
github.com/mattn/go-sqlite3 v1.11.0
|
github.com/mattn/go-sqlite3 v1.11.0
|
||||||
github.com/mcuadros/go-version v0.0.0-20190308113854-92cdf37c5b75
|
github.com/mcuadros/go-version v0.0.0-20190308113854-92cdf37c5b75
|
||||||
github.com/microcosm-cc/bluemonday v0.0.0-20161012083705-f77f16ffc87a
|
github.com/microcosm-cc/bluemonday v0.0.0-20161012083705-f77f16ffc87a
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
|
||||||
github.com/modern-go/reflect2 v1.0.1 // indirect
|
|
||||||
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae // indirect
|
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae // indirect
|
||||||
github.com/msteinert/pam v0.0.0-20151204160544-02ccfbfaf0cc
|
github.com/msteinert/pam v0.0.0-20151204160544-02ccfbfaf0cc
|
||||||
github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5
|
github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ func TestAPICreateAndUpdateRelease(t *testing.T) {
|
|||||||
|
|
||||||
gitRepo, err := git.OpenRepository(repo.RepoPath())
|
gitRepo, err := git.OpenRepository(repo.RepoPath())
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
err = gitRepo.CreateTag("v0.0.1", "master")
|
err = gitRepo.CreateTag("v0.0.1", "master")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
@@ -112,6 +113,7 @@ func TestAPICreateReleaseToDefaultBranchOnExistingTag(t *testing.T) {
|
|||||||
|
|
||||||
gitRepo, err := git.OpenRepository(repo.RepoPath())
|
gitRepo, err := git.OpenRepository(repo.RepoPath())
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
err = gitRepo.CreateTag("v0.0.1", "master")
|
err = gitRepo.CreateTag("v0.0.1", "master")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|||||||
@@ -139,6 +139,7 @@ func TestAPICreateFile(t *testing.T) {
|
|||||||
assert.EqualValues(t, expectedFileResponse.Commit.HTMLURL, fileResponse.Commit.HTMLURL)
|
assert.EqualValues(t, expectedFileResponse.Commit.HTMLURL, fileResponse.Commit.HTMLURL)
|
||||||
assert.EqualValues(t, expectedFileResponse.Commit.Author.Email, fileResponse.Commit.Author.Email)
|
assert.EqualValues(t, expectedFileResponse.Commit.Author.Email, fileResponse.Commit.Author.Email)
|
||||||
assert.EqualValues(t, expectedFileResponse.Commit.Author.Name, fileResponse.Commit.Author.Name)
|
assert.EqualValues(t, expectedFileResponse.Commit.Author.Name, fileResponse.Commit.Author.Name)
|
||||||
|
gitRepo.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test creating a file in a new branch
|
// Test creating a file in a new branch
|
||||||
|
|||||||
@@ -143,6 +143,7 @@ func TestAPIUpdateFile(t *testing.T) {
|
|||||||
assert.EqualValues(t, expectedFileResponse.Commit.HTMLURL, fileResponse.Commit.HTMLURL)
|
assert.EqualValues(t, expectedFileResponse.Commit.HTMLURL, fileResponse.Commit.HTMLURL)
|
||||||
assert.EqualValues(t, expectedFileResponse.Commit.Author.Email, fileResponse.Commit.Author.Email)
|
assert.EqualValues(t, expectedFileResponse.Commit.Author.Email, fileResponse.Commit.Author.Email)
|
||||||
assert.EqualValues(t, expectedFileResponse.Commit.Author.Name, fileResponse.Commit.Author.Name)
|
assert.EqualValues(t, expectedFileResponse.Commit.Author.Name, fileResponse.Commit.Author.Name)
|
||||||
|
gitRepo.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test updating a file in a new branch
|
// Test updating a file in a new branch
|
||||||
|
|||||||
@@ -74,6 +74,8 @@ func testAPIGetContentsList(t *testing.T, u *url.URL) {
|
|||||||
repo1.CreateNewBranch(user2, repo1.DefaultBranch, newBranch)
|
repo1.CreateNewBranch(user2, repo1.DefaultBranch, newBranch)
|
||||||
// Get the commit ID of the default branch
|
// Get the commit ID of the default branch
|
||||||
gitRepo, _ := git.OpenRepository(repo1.RepoPath())
|
gitRepo, _ := git.OpenRepository(repo1.RepoPath())
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
commitID, _ := gitRepo.GetBranchCommitID(repo1.DefaultBranch)
|
commitID, _ := gitRepo.GetBranchCommitID(repo1.DefaultBranch)
|
||||||
// Make a new tag in repo1
|
// Make a new tag in repo1
|
||||||
newTag := "test_tag"
|
newTag := "test_tag"
|
||||||
|
|||||||
@@ -75,6 +75,8 @@ func testAPIGetContents(t *testing.T, u *url.URL) {
|
|||||||
repo1.CreateNewBranch(user2, repo1.DefaultBranch, newBranch)
|
repo1.CreateNewBranch(user2, repo1.DefaultBranch, newBranch)
|
||||||
// Get the commit ID of the default branch
|
// Get the commit ID of the default branch
|
||||||
gitRepo, _ := git.OpenRepository(repo1.RepoPath())
|
gitRepo, _ := git.OpenRepository(repo1.RepoPath())
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
commitID, _ := gitRepo.GetBranchCommitID(repo1.DefaultBranch)
|
commitID, _ := gitRepo.GetBranchCommitID(repo1.DefaultBranch)
|
||||||
// Make a new tag in repo1
|
// Make a new tag in repo1
|
||||||
newTag := "test_tag"
|
newTag := "test_tag"
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ func TestAPIGitTags(t *testing.T) {
|
|||||||
git.NewCommand("config", "user.email", user.Email).RunInDir(repo.RepoPath())
|
git.NewCommand("config", "user.email", user.Email).RunInDir(repo.RepoPath())
|
||||||
|
|
||||||
gitRepo, _ := git.OpenRepository(repo.RepoPath())
|
gitRepo, _ := git.OpenRepository(repo.RepoPath())
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
commit, _ := gitRepo.GetBranchCommit("master")
|
commit, _ := gitRepo.GetBranchCommit("master")
|
||||||
lTagName := "lightweightTag"
|
lTagName := "lightweightTag"
|
||||||
gitRepo.CreateTag(lTagName, commit.ID.String())
|
gitRepo.CreateTag(lTagName, commit.ID.String())
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ func TestAPITeamUser(t *testing.T) {
|
|||||||
var user2 *api.User
|
var user2 *api.User
|
||||||
DecodeJSON(t, resp, &user2)
|
DecodeJSON(t, resp, &user2)
|
||||||
user2.Created = user2.Created.In(time.Local)
|
user2.Created = user2.Created.In(time.Local)
|
||||||
user2.LastLogin = user2.LastLogin.In(time.Local)
|
|
||||||
user := models.AssertExistsAndLoadBean(t, &models.User{Name: "user2"}).(*models.User)
|
user := models.AssertExistsAndLoadBean(t, &models.User{Name: "user2"}).(*models.User)
|
||||||
|
|
||||||
assert.Equal(t, convert.ToUser(user, true, false), user2)
|
assert.Equal(t, convert.ToUser(user, true, false), user2)
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ func TestUserHeatmap(t *testing.T) {
|
|||||||
var heatmap []*models.UserHeatmapData
|
var heatmap []*models.UserHeatmapData
|
||||||
DecodeJSON(t, resp, &heatmap)
|
DecodeJSON(t, resp, &heatmap)
|
||||||
var dummyheatmap []*models.UserHeatmapData
|
var dummyheatmap []*models.UserHeatmapData
|
||||||
dummyheatmap = append(dummyheatmap, &models.UserHeatmapData{Timestamp: 1540080000, Contributions: 1})
|
dummyheatmap = append(dummyheatmap, &models.UserHeatmapData{Timestamp: 1571616000, Contributions: 1})
|
||||||
|
|
||||||
assert.Equal(t, dummyheatmap, heatmap)
|
assert.Equal(t, dummyheatmap, heatmap)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -36,7 +38,12 @@ func withKeyFile(t *testing.T, keyname string, callback func(string)) {
|
|||||||
err = ssh.GenKeyPair(keyFile)
|
err = ssh.GenKeyPair(keyFile)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
err = ioutil.WriteFile(path.Join(tmpDir, "ssh"), []byte("#!/bin/bash\n"+
|
||||||
|
"ssh -o \"UserKnownHostsFile=/dev/null\" -o \"StrictHostKeyChecking=no\" -o \"IdentitiesOnly=yes\" -i \""+keyFile+"\" \"$@\""), 0700)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
//Setup ssh wrapper
|
//Setup ssh wrapper
|
||||||
|
os.Setenv("GIT_SSH", path.Join(tmpDir, "ssh"))
|
||||||
os.Setenv("GIT_SSH_COMMAND",
|
os.Setenv("GIT_SSH_COMMAND",
|
||||||
"ssh -o \"UserKnownHostsFile=/dev/null\" -o \"StrictHostKeyChecking=no\" -o \"IdentitiesOnly=yes\" -i \""+keyFile+"\"")
|
"ssh -o \"UserKnownHostsFile=/dev/null\" -o \"StrictHostKeyChecking=no\" -o \"IdentitiesOnly=yes\" -i \""+keyFile+"\"")
|
||||||
os.Setenv("GIT_SSH_VARIANT", "ssh")
|
os.Setenv("GIT_SSH_VARIANT", "ssh")
|
||||||
@@ -53,6 +60,24 @@ func createSSHUrl(gitPath string, u *url.URL) *url.URL {
|
|||||||
return &u2
|
return &u2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func allowLFSFilters() []string {
|
||||||
|
// Now here we should explicitly allow lfs filters to run
|
||||||
|
globalArgs := git.GlobalCommandArgs
|
||||||
|
filteredLFSGlobalArgs := make([]string, len(git.GlobalCommandArgs))
|
||||||
|
j := 0
|
||||||
|
for _, arg := range git.GlobalCommandArgs {
|
||||||
|
if strings.Contains(arg, "lfs") {
|
||||||
|
j--
|
||||||
|
} else {
|
||||||
|
filteredLFSGlobalArgs[j] = arg
|
||||||
|
j++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
filteredLFSGlobalArgs = filteredLFSGlobalArgs[:j]
|
||||||
|
git.GlobalCommandArgs = filteredLFSGlobalArgs
|
||||||
|
return globalArgs
|
||||||
|
}
|
||||||
|
|
||||||
func onGiteaRun(t *testing.T, callback func(*testing.T, *url.URL)) {
|
func onGiteaRun(t *testing.T, callback func(*testing.T, *url.URL)) {
|
||||||
prepareTestEnv(t, 1)
|
prepareTestEnv(t, 1)
|
||||||
s := http.Server{
|
s := http.Server{
|
||||||
@@ -78,7 +103,9 @@ func onGiteaRun(t *testing.T, callback func(*testing.T, *url.URL)) {
|
|||||||
|
|
||||||
func doGitClone(dstLocalPath string, u *url.URL) func(*testing.T) {
|
func doGitClone(dstLocalPath string, u *url.URL) func(*testing.T) {
|
||||||
return func(t *testing.T) {
|
return func(t *testing.T) {
|
||||||
|
oldGlobals := allowLFSFilters()
|
||||||
assert.NoError(t, git.Clone(u.String(), dstLocalPath, git.CloneRepoOptions{}))
|
assert.NoError(t, git.Clone(u.String(), dstLocalPath, git.CloneRepoOptions{}))
|
||||||
|
git.GlobalCommandArgs = oldGlobals
|
||||||
assert.True(t, com.IsExist(filepath.Join(dstLocalPath, "README.md")))
|
assert.True(t, com.IsExist(filepath.Join(dstLocalPath, "README.md")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -139,7 +166,9 @@ func doGitCreateBranch(dstPath, branch string) func(*testing.T) {
|
|||||||
|
|
||||||
func doGitCheckoutBranch(dstPath string, args ...string) func(*testing.T) {
|
func doGitCheckoutBranch(dstPath string, args ...string) func(*testing.T) {
|
||||||
return func(t *testing.T) {
|
return func(t *testing.T) {
|
||||||
|
oldGlobals := allowLFSFilters()
|
||||||
_, err := git.NewCommand(append([]string{"checkout"}, args...)...).RunInDir(dstPath)
|
_, err := git.NewCommand(append([]string{"checkout"}, args...)...).RunInDir(dstPath)
|
||||||
|
git.GlobalCommandArgs = oldGlobals
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -153,7 +182,9 @@ func doGitMerge(dstPath string, args ...string) func(*testing.T) {
|
|||||||
|
|
||||||
func doGitPull(dstPath string, args ...string) func(*testing.T) {
|
func doGitPull(dstPath string, args ...string) func(*testing.T) {
|
||||||
return func(t *testing.T) {
|
return func(t *testing.T) {
|
||||||
|
oldGlobals := allowLFSFilters()
|
||||||
_, err := git.NewCommand(append([]string{"pull"}, args...)...).RunInDir(dstPath)
|
_, err := git.NewCommand(append([]string{"pull"}, args...)...).RunInDir(dstPath)
|
||||||
|
git.GlobalCommandArgs = oldGlobals
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import (
|
|||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@@ -135,6 +136,11 @@ func standardCommitAndPushTest(t *testing.T, dstPath string) (little, big string
|
|||||||
func lfsCommitAndPushTest(t *testing.T, dstPath string) (littleLFS, bigLFS string) {
|
func lfsCommitAndPushTest(t *testing.T, dstPath string) (littleLFS, bigLFS string) {
|
||||||
t.Run("LFS", func(t *testing.T) {
|
t.Run("LFS", func(t *testing.T) {
|
||||||
PrintCurrentTest(t)
|
PrintCurrentTest(t)
|
||||||
|
setting.CheckLFSVersion()
|
||||||
|
if !setting.LFS.StartServer {
|
||||||
|
t.Skip()
|
||||||
|
return
|
||||||
|
}
|
||||||
prefix := "lfs-data-file-"
|
prefix := "lfs-data-file-"
|
||||||
_, err := git.NewCommand("lfs").AddArguments("install").RunInDir(dstPath)
|
_, err := git.NewCommand("lfs").AddArguments("install").RunInDir(dstPath)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
@@ -142,6 +148,21 @@ func lfsCommitAndPushTest(t *testing.T, dstPath string) (littleLFS, bigLFS strin
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
err = git.AddChanges(dstPath, false, ".gitattributes")
|
err = git.AddChanges(dstPath, false, ".gitattributes")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
oldGlobals := allowLFSFilters()
|
||||||
|
err = git.CommitChanges(dstPath, git.CommitChangesOptions{
|
||||||
|
Committer: &git.Signature{
|
||||||
|
Email: "user2@example.com",
|
||||||
|
Name: "User Two",
|
||||||
|
When: time.Now(),
|
||||||
|
},
|
||||||
|
Author: &git.Signature{
|
||||||
|
Email: "user2@example.com",
|
||||||
|
Name: "User Two",
|
||||||
|
When: time.Now(),
|
||||||
|
},
|
||||||
|
Message: fmt.Sprintf("Testing commit @ %v", time.Now()),
|
||||||
|
})
|
||||||
|
git.GlobalCommandArgs = oldGlobals
|
||||||
|
|
||||||
littleLFS, bigLFS = commitAndPushTest(t, dstPath, prefix)
|
littleLFS, bigLFS = commitAndPushTest(t, dstPath, prefix)
|
||||||
|
|
||||||
@@ -185,21 +206,26 @@ func rawTest(t *testing.T, ctx *APITestContext, little, big, littleLFS, bigLFS s
|
|||||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||||
assert.Equal(t, littleSize, resp.Body.Len())
|
assert.Equal(t, littleSize, resp.Body.Len())
|
||||||
|
|
||||||
|
setting.CheckLFSVersion()
|
||||||
|
if setting.LFS.StartServer {
|
||||||
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", littleLFS))
|
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", littleLFS))
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
assert.NotEqual(t, littleSize, resp.Body.Len())
|
assert.NotEqual(t, littleSize, resp.Body.Len())
|
||||||
assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier)
|
assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier)
|
||||||
|
}
|
||||||
|
|
||||||
if !testing.Short() {
|
if !testing.Short() {
|
||||||
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", big))
|
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", big))
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
assert.Equal(t, bigSize, resp.Body.Len())
|
assert.Equal(t, bigSize, resp.Body.Len())
|
||||||
|
|
||||||
|
if setting.LFS.StartServer {
|
||||||
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", bigLFS))
|
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", bigLFS))
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
assert.NotEqual(t, bigSize, resp.Body.Len())
|
assert.NotEqual(t, bigSize, resp.Body.Len())
|
||||||
assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier)
|
assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,19 +243,24 @@ func mediaTest(t *testing.T, ctx *APITestContext, little, big, littleLFS, bigLFS
|
|||||||
resp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
resp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
||||||
assert.Equal(t, littleSize, resp.Length)
|
assert.Equal(t, littleSize, resp.Length)
|
||||||
|
|
||||||
|
setting.CheckLFSVersion()
|
||||||
|
if setting.LFS.StartServer {
|
||||||
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", littleLFS))
|
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", littleLFS))
|
||||||
resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
||||||
assert.Equal(t, littleSize, resp.Length)
|
assert.Equal(t, littleSize, resp.Length)
|
||||||
|
}
|
||||||
|
|
||||||
if !testing.Short() {
|
if !testing.Short() {
|
||||||
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", big))
|
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", big))
|
||||||
resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
||||||
assert.Equal(t, bigSize, resp.Length)
|
assert.Equal(t, bigSize, resp.Length)
|
||||||
|
|
||||||
|
if setting.LFS.StartServer {
|
||||||
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", bigLFS))
|
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", bigLFS))
|
||||||
resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
||||||
assert.Equal(t, bigSize, resp.Length)
|
assert.Equal(t, bigSize, resp.Length)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,6 +305,8 @@ func generateCommitWithNewData(size int, repoPath, email, fullName, prefix strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Commit
|
//Commit
|
||||||
|
// Now here we should explicitly allow lfs filters to run
|
||||||
|
oldGlobals := allowLFSFilters()
|
||||||
err = git.AddChanges(repoPath, false, filepath.Base(tmpFile.Name()))
|
err = git.AddChanges(repoPath, false, filepath.Base(tmpFile.Name()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@@ -291,6 +324,7 @@ func generateCommitWithNewData(size int, repoPath, email, fullName, prefix strin
|
|||||||
},
|
},
|
||||||
Message: fmt.Sprintf("Testing commit @ %v", time.Now()),
|
Message: fmt.Sprintf("Testing commit @ %v", time.Now()),
|
||||||
})
|
})
|
||||||
|
git.GlobalCommandArgs = oldGlobals
|
||||||
return filepath.Base(tmpFile.Name()), err
|
return filepath.Base(tmpFile.Name()), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,11 @@ func storeObjectInRepo(t *testing.T, repositoryID int64, content *[]byte) string
|
|||||||
|
|
||||||
func doLfs(t *testing.T, content *[]byte, expectGzip bool) {
|
func doLfs(t *testing.T, content *[]byte, expectGzip bool) {
|
||||||
prepareTestEnv(t)
|
prepareTestEnv(t)
|
||||||
|
setting.CheckLFSVersion()
|
||||||
|
if !setting.LFS.StartServer {
|
||||||
|
t.Skip()
|
||||||
|
return
|
||||||
|
}
|
||||||
repo, err := models.GetRepositoryByOwnerAndName("user2", "repo1")
|
repo, err := models.GetRepositoryByOwnerAndName("user2", "repo1")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
oid := storeObjectInRepo(t, repo.ID, content)
|
oid := storeObjectInRepo(t, repo.ID, content)
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ func testDeleteRepoFile(t *testing.T, u *url.URL) {
|
|||||||
test.LoadRepoCommit(t, ctx)
|
test.LoadRepoCommit(t, ctx)
|
||||||
test.LoadUser(t, ctx, 2)
|
test.LoadUser(t, ctx, 2)
|
||||||
test.LoadGitRepo(t, ctx)
|
test.LoadGitRepo(t, ctx)
|
||||||
|
defer ctx.Repo.GitRepo.Close()
|
||||||
repo := ctx.Repo.Repository
|
repo := ctx.Repo.Repository
|
||||||
doer := ctx.User
|
doer := ctx.User
|
||||||
opts := getDeleteRepoFileOptions(repo)
|
opts := getDeleteRepoFileOptions(repo)
|
||||||
@@ -111,6 +112,8 @@ func testDeleteRepoFileWithoutBranchNames(t *testing.T, u *url.URL) {
|
|||||||
test.LoadRepoCommit(t, ctx)
|
test.LoadRepoCommit(t, ctx)
|
||||||
test.LoadUser(t, ctx, 2)
|
test.LoadUser(t, ctx, 2)
|
||||||
test.LoadGitRepo(t, ctx)
|
test.LoadGitRepo(t, ctx)
|
||||||
|
defer ctx.Repo.GitRepo.Close()
|
||||||
|
|
||||||
repo := ctx.Repo.Repository
|
repo := ctx.Repo.Repository
|
||||||
doer := ctx.User
|
doer := ctx.User
|
||||||
opts := getDeleteRepoFileOptions(repo)
|
opts := getDeleteRepoFileOptions(repo)
|
||||||
@@ -139,6 +142,8 @@ func TestDeleteRepoFileErrors(t *testing.T) {
|
|||||||
test.LoadRepoCommit(t, ctx)
|
test.LoadRepoCommit(t, ctx)
|
||||||
test.LoadUser(t, ctx, 2)
|
test.LoadUser(t, ctx, 2)
|
||||||
test.LoadGitRepo(t, ctx)
|
test.LoadGitRepo(t, ctx)
|
||||||
|
defer ctx.Repo.GitRepo.Close()
|
||||||
|
|
||||||
repo := ctx.Repo.Repository
|
repo := ctx.Repo.Repository
|
||||||
doer := ctx.User
|
doer := ctx.User
|
||||||
|
|
||||||
|
|||||||
@@ -191,6 +191,8 @@ func TestCreateOrUpdateRepoFileForCreate(t *testing.T) {
|
|||||||
test.LoadRepoCommit(t, ctx)
|
test.LoadRepoCommit(t, ctx)
|
||||||
test.LoadUser(t, ctx, 2)
|
test.LoadUser(t, ctx, 2)
|
||||||
test.LoadGitRepo(t, ctx)
|
test.LoadGitRepo(t, ctx)
|
||||||
|
defer ctx.Repo.GitRepo.Close()
|
||||||
|
|
||||||
repo := ctx.Repo.Repository
|
repo := ctx.Repo.Repository
|
||||||
doer := ctx.User
|
doer := ctx.User
|
||||||
opts := getCreateRepoFileOptions(repo)
|
opts := getCreateRepoFileOptions(repo)
|
||||||
@@ -201,6 +203,8 @@ func TestCreateOrUpdateRepoFileForCreate(t *testing.T) {
|
|||||||
// asserts
|
// asserts
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
gitRepo, _ := git.OpenRepository(repo.RepoPath())
|
gitRepo, _ := git.OpenRepository(repo.RepoPath())
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
commitID, _ := gitRepo.GetBranchCommitID(opts.NewBranch)
|
commitID, _ := gitRepo.GetBranchCommitID(opts.NewBranch)
|
||||||
expectedFileResponse := getExpectedFileResponseForRepofilesCreate(commitID)
|
expectedFileResponse := getExpectedFileResponseForRepofilesCreate(commitID)
|
||||||
assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content)
|
assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content)
|
||||||
@@ -220,6 +224,8 @@ func TestCreateOrUpdateRepoFileForUpdate(t *testing.T) {
|
|||||||
test.LoadRepoCommit(t, ctx)
|
test.LoadRepoCommit(t, ctx)
|
||||||
test.LoadUser(t, ctx, 2)
|
test.LoadUser(t, ctx, 2)
|
||||||
test.LoadGitRepo(t, ctx)
|
test.LoadGitRepo(t, ctx)
|
||||||
|
defer ctx.Repo.GitRepo.Close()
|
||||||
|
|
||||||
repo := ctx.Repo.Repository
|
repo := ctx.Repo.Repository
|
||||||
doer := ctx.User
|
doer := ctx.User
|
||||||
opts := getUpdateRepoFileOptions(repo)
|
opts := getUpdateRepoFileOptions(repo)
|
||||||
@@ -230,6 +236,8 @@ func TestCreateOrUpdateRepoFileForUpdate(t *testing.T) {
|
|||||||
// asserts
|
// asserts
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
gitRepo, _ := git.OpenRepository(repo.RepoPath())
|
gitRepo, _ := git.OpenRepository(repo.RepoPath())
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
commitID, _ := gitRepo.GetBranchCommitID(opts.NewBranch)
|
commitID, _ := gitRepo.GetBranchCommitID(opts.NewBranch)
|
||||||
expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commitID, opts.TreePath)
|
expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commitID, opts.TreePath)
|
||||||
assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content)
|
assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content)
|
||||||
@@ -249,6 +257,8 @@ func TestCreateOrUpdateRepoFileForUpdateWithFileMove(t *testing.T) {
|
|||||||
test.LoadRepoCommit(t, ctx)
|
test.LoadRepoCommit(t, ctx)
|
||||||
test.LoadUser(t, ctx, 2)
|
test.LoadUser(t, ctx, 2)
|
||||||
test.LoadGitRepo(t, ctx)
|
test.LoadGitRepo(t, ctx)
|
||||||
|
defer ctx.Repo.GitRepo.Close()
|
||||||
|
|
||||||
repo := ctx.Repo.Repository
|
repo := ctx.Repo.Repository
|
||||||
doer := ctx.User
|
doer := ctx.User
|
||||||
opts := getUpdateRepoFileOptions(repo)
|
opts := getUpdateRepoFileOptions(repo)
|
||||||
@@ -261,6 +271,8 @@ func TestCreateOrUpdateRepoFileForUpdateWithFileMove(t *testing.T) {
|
|||||||
// asserts
|
// asserts
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
gitRepo, _ := git.OpenRepository(repo.RepoPath())
|
gitRepo, _ := git.OpenRepository(repo.RepoPath())
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
commit, _ := gitRepo.GetBranchCommit(opts.NewBranch)
|
commit, _ := gitRepo.GetBranchCommit(opts.NewBranch)
|
||||||
expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commit.ID.String(), opts.TreePath)
|
expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commit.ID.String(), opts.TreePath)
|
||||||
// assert that the old file no longer exists in the last commit of the branch
|
// assert that the old file no longer exists in the last commit of the branch
|
||||||
@@ -288,6 +300,8 @@ func TestCreateOrUpdateRepoFileWithoutBranchNames(t *testing.T) {
|
|||||||
test.LoadRepoCommit(t, ctx)
|
test.LoadRepoCommit(t, ctx)
|
||||||
test.LoadUser(t, ctx, 2)
|
test.LoadUser(t, ctx, 2)
|
||||||
test.LoadGitRepo(t, ctx)
|
test.LoadGitRepo(t, ctx)
|
||||||
|
defer ctx.Repo.GitRepo.Close()
|
||||||
|
|
||||||
repo := ctx.Repo.Repository
|
repo := ctx.Repo.Repository
|
||||||
doer := ctx.User
|
doer := ctx.User
|
||||||
opts := getUpdateRepoFileOptions(repo)
|
opts := getUpdateRepoFileOptions(repo)
|
||||||
@@ -300,6 +314,8 @@ func TestCreateOrUpdateRepoFileWithoutBranchNames(t *testing.T) {
|
|||||||
// asserts
|
// asserts
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
gitRepo, _ := git.OpenRepository(repo.RepoPath())
|
gitRepo, _ := git.OpenRepository(repo.RepoPath())
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
commitID, _ := gitRepo.GetBranchCommitID(repo.DefaultBranch)
|
commitID, _ := gitRepo.GetBranchCommitID(repo.DefaultBranch)
|
||||||
expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commitID, opts.TreePath)
|
expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commitID, opts.TreePath)
|
||||||
assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content)
|
assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content)
|
||||||
@@ -315,6 +331,8 @@ func TestCreateOrUpdateRepoFileErrors(t *testing.T) {
|
|||||||
test.LoadRepoCommit(t, ctx)
|
test.LoadRepoCommit(t, ctx)
|
||||||
test.LoadUser(t, ctx, 2)
|
test.LoadUser(t, ctx, 2)
|
||||||
test.LoadGitRepo(t, ctx)
|
test.LoadGitRepo(t, ctx)
|
||||||
|
defer ctx.Repo.GitRepo.Close()
|
||||||
|
|
||||||
repo := ctx.Repo.Repository
|
repo := ctx.Repo.Repository
|
||||||
doer := ctx.User
|
doer := ctx.User
|
||||||
|
|
||||||
|
|||||||
@@ -762,6 +762,7 @@ func CommitRepoAction(opts CommitRepoActionOptions) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetBranchCommitID[%s]: %v", opts.RefFullName, err)
|
log.Error("GetBranchCommitID[%s]: %v", opts.RefFullName, err)
|
||||||
}
|
}
|
||||||
|
gitRepo.Close()
|
||||||
if err = PrepareWebhooks(repo, HookEventCreate, &api.CreatePayload{
|
if err = PrepareWebhooks(repo, HookEventCreate, &api.CreatePayload{
|
||||||
Ref: refName,
|
Ref: refName,
|
||||||
Sha: shaSum,
|
Sha: shaSum,
|
||||||
@@ -797,6 +798,8 @@ func CommitRepoAction(opts CommitRepoActionOptions) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetTagCommitID[%s]: %v", opts.RefFullName, err)
|
log.Error("GetTagCommitID[%s]: %v", opts.RefFullName, err)
|
||||||
}
|
}
|
||||||
|
gitRepo.Close()
|
||||||
|
|
||||||
if err = PrepareWebhooks(repo, HookEventCreate, &api.CreatePayload{
|
if err = PrepareWebhooks(repo, HookEventCreate, &api.CreatePayload{
|
||||||
Ref: refName,
|
Ref: refName,
|
||||||
Sha: shaSum,
|
Sha: shaSum,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
act_user_id: 2
|
act_user_id: 2
|
||||||
repo_id: 2
|
repo_id: 2
|
||||||
is_private: true
|
is_private: true
|
||||||
created_unix: 1540139562
|
created_unix: 1571686356
|
||||||
|
|
||||||
-
|
-
|
||||||
id: 2
|
id: 2
|
||||||
|
|||||||
@@ -675,6 +675,7 @@ func GetDiffRangeWithWhitespaceBehavior(repoPath, beforeCommitID, afterCommitID
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
commit, err := gitRepo.GetCommit(afterCommitID)
|
commit, err := gitRepo.GetCommit(afterCommitID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -747,6 +748,7 @@ func GetRawDiffForFile(repoPath, startCommit, endCommit string, diffType RawDiff
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("OpenRepository: %v", err)
|
return fmt.Errorf("OpenRepository: %v", err)
|
||||||
}
|
}
|
||||||
|
defer repo.Close()
|
||||||
|
|
||||||
commit, err := repo.GetCommit(endCommit)
|
commit, err := repo.GetCommit(endCommit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ func BenchmarkGetCommitGraph(b *testing.B) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
b.Error("Could not open repository")
|
b.Error("Could not open repository")
|
||||||
}
|
}
|
||||||
|
defer currentRepo.Close()
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
graph, err := GetCommitGraph(currentRepo)
|
graph, err := GetCommitGraph(currentRepo)
|
||||||
|
|||||||
159
models/issue.go
159
models/issue.go
@@ -1102,6 +1102,10 @@ func newIssue(e *xorm.Session, doer *User, opts NewIssueOptions) (err error) {
|
|||||||
if _, err = e.Exec("UPDATE `milestone` SET num_issues=num_issues+1 WHERE id=?", opts.Issue.MilestoneID); err != nil {
|
if _, err = e.Exec("UPDATE `milestone` SET num_issues=num_issues+1 WHERE id=?", opts.Issue.MilestoneID); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if _, err = createMilestoneComment(e, doer, opts.Repo, opts.Issue, 0, opts.Issue.MilestoneID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert the assignees
|
// Insert the assignees
|
||||||
@@ -1462,46 +1466,18 @@ func getParticipantsByIssueID(e Engine, issueID int64) ([]*User, error) {
|
|||||||
return users, e.In("id", userIDs).Find(&users)
|
return users, e.In("id", userIDs).Find(&users)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateIssueMentions extracts mentioned people from content and
|
// UpdateIssueMentions updates issue-user relations for mentioned users.
|
||||||
// updates issue-user relations for them.
|
func UpdateIssueMentions(e Engine, issueID int64, mentions []*User) error {
|
||||||
func UpdateIssueMentions(e Engine, issueID int64, mentions []string) error {
|
|
||||||
if len(mentions) == 0 {
|
if len(mentions) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
ids := make([]int64, len(mentions))
|
||||||
for i := range mentions {
|
for i, u := range mentions {
|
||||||
mentions[i] = strings.ToLower(mentions[i])
|
ids[i] = u.ID
|
||||||
}
|
}
|
||||||
users := make([]*User, 0, len(mentions))
|
|
||||||
|
|
||||||
if err := e.In("lower_name", mentions).Asc("lower_name").Find(&users); err != nil {
|
|
||||||
return fmt.Errorf("find mentioned users: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
ids := make([]int64, 0, len(mentions))
|
|
||||||
for _, user := range users {
|
|
||||||
ids = append(ids, user.ID)
|
|
||||||
if !user.IsOrganization() || user.NumMembers == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
memberIDs := make([]int64, 0, user.NumMembers)
|
|
||||||
orgUsers, err := getOrgUsersByOrgID(e, user.ID)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("GetOrgUsersByOrgID [%d]: %v", user.ID, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, orgUser := range orgUsers {
|
|
||||||
memberIDs = append(memberIDs, orgUser.ID)
|
|
||||||
}
|
|
||||||
|
|
||||||
ids = append(ids, memberIDs...)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := UpdateIssueUsersByMentions(e, issueID, ids); err != nil {
|
if err := UpdateIssueUsersByMentions(e, issueID, ids); err != nil {
|
||||||
return fmt.Errorf("UpdateIssueUsersByMentions: %v", err)
|
return fmt.Errorf("UpdateIssueUsersByMentions: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1854,3 +1830,120 @@ func (issue *Issue) updateClosedNum(e Engine) (err error) {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ResolveMentionsByVisibility returns the users mentioned in an issue, removing those that
|
||||||
|
// don't have access to reading it. Teams are expanded into their users, but organizations are ignored.
|
||||||
|
func (issue *Issue) ResolveMentionsByVisibility(e Engine, doer *User, mentions []string) (users []*User, err error) {
|
||||||
|
if len(mentions) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err = issue.loadRepo(e); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resolved := make(map[string]bool, 20)
|
||||||
|
names := make([]string, 0, 20)
|
||||||
|
resolved[doer.LowerName] = true
|
||||||
|
for _, name := range mentions {
|
||||||
|
name := strings.ToLower(name)
|
||||||
|
if _, ok := resolved[name]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
resolved[name] = false
|
||||||
|
names = append(names, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := issue.Repo.getOwner(e); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if issue.Repo.Owner.IsOrganization() {
|
||||||
|
// Since there can be users with names that match the name of a team,
|
||||||
|
// if the team exists and can read the issue, the team takes precedence.
|
||||||
|
teams := make([]*Team, 0, len(names))
|
||||||
|
if err := e.
|
||||||
|
Join("INNER", "team_repo", "team_repo.team_id = team.id").
|
||||||
|
Where("team_repo.repo_id=?", issue.Repo.ID).
|
||||||
|
In("team.lower_name", names).
|
||||||
|
Find(&teams); err != nil {
|
||||||
|
return nil, fmt.Errorf("find mentioned teams: %v", err)
|
||||||
|
}
|
||||||
|
if len(teams) != 0 {
|
||||||
|
checked := make([]int64, 0, len(teams))
|
||||||
|
unittype := UnitTypeIssues
|
||||||
|
if issue.IsPull {
|
||||||
|
unittype = UnitTypePullRequests
|
||||||
|
}
|
||||||
|
for _, team := range teams {
|
||||||
|
if team.Authorize >= AccessModeOwner {
|
||||||
|
checked = append(checked, team.ID)
|
||||||
|
resolved[team.LowerName] = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
has, err := e.Get(&TeamUnit{OrgID: issue.Repo.Owner.ID, TeamID: team.ID, Type: unittype})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("get team units (%d): %v", team.ID, err)
|
||||||
|
}
|
||||||
|
if has {
|
||||||
|
checked = append(checked, team.ID)
|
||||||
|
resolved[team.LowerName] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(checked) != 0 {
|
||||||
|
teamusers := make([]*User, 0, 20)
|
||||||
|
if err := e.
|
||||||
|
Join("INNER", "team_user", "team_user.uid = `user`.id").
|
||||||
|
In("`team_user`.team_id", checked).
|
||||||
|
And("`user`.is_active = ?", true).
|
||||||
|
And("`user`.prohibit_login = ?", false).
|
||||||
|
Find(&teamusers); err != nil {
|
||||||
|
return nil, fmt.Errorf("get teams users: %v", err)
|
||||||
|
}
|
||||||
|
if len(teamusers) > 0 {
|
||||||
|
users = make([]*User, 0, len(teamusers))
|
||||||
|
for _, user := range teamusers {
|
||||||
|
if already, ok := resolved[user.LowerName]; !ok || !already {
|
||||||
|
users = append(users, user)
|
||||||
|
resolved[user.LowerName] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove names already in the list to avoid querying the database if pending names remain
|
||||||
|
names = make([]string, 0, len(resolved))
|
||||||
|
for name, already := range resolved {
|
||||||
|
if !already {
|
||||||
|
names = append(names, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(names) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unchecked := make([]*User, 0, len(names))
|
||||||
|
if err := e.
|
||||||
|
Where("`user`.is_active = ?", true).
|
||||||
|
And("`user`.prohibit_login = ?", false).
|
||||||
|
In("`user`.lower_name", names).
|
||||||
|
Find(&unchecked); err != nil {
|
||||||
|
return nil, fmt.Errorf("find mentioned users: %v", err)
|
||||||
|
}
|
||||||
|
for _, user := range unchecked {
|
||||||
|
if already := resolved[user.LowerName]; already || user.IsOrganization() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Normal users must have read access to the referencing issue
|
||||||
|
perm, err := getUserRepoPermission(e, issue.Repo, user)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("getUserRepoPermission [%d]: %v", user.ID, err)
|
||||||
|
}
|
||||||
|
if !perm.CanReadIssuesOrPulls(issue.IsPull) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
users = append(users, user)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|||||||
@@ -387,11 +387,18 @@ func (c *Comment) MailParticipants(opType ActionType, issue *Issue) (err error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Comment) mailParticipants(e Engine, opType ActionType, issue *Issue) (err error) {
|
func (c *Comment) mailParticipants(e Engine, opType ActionType, issue *Issue) (err error) {
|
||||||
mentions := markup.FindAllMentions(c.Content)
|
rawMentions := markup.FindAllMentions(c.Content)
|
||||||
if err = UpdateIssueMentions(e, c.IssueID, mentions); err != nil {
|
userMentions, err := issue.ResolveMentionsByVisibility(e, c.Poster, rawMentions)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("ResolveMentionsByVisibility [%d]: %v", c.IssueID, err)
|
||||||
|
}
|
||||||
|
if err = UpdateIssueMentions(e, c.IssueID, userMentions); err != nil {
|
||||||
return fmt.Errorf("UpdateIssueMentions [%d]: %v", c.IssueID, err)
|
return fmt.Errorf("UpdateIssueMentions [%d]: %v", c.IssueID, err)
|
||||||
}
|
}
|
||||||
|
mentions := make([]string, len(userMentions))
|
||||||
|
for i, u := range userMentions {
|
||||||
|
mentions[i] = u.LowerName
|
||||||
|
}
|
||||||
if len(c.Content) > 0 {
|
if len(c.Content) > 0 {
|
||||||
if err = mailIssueCommentToParticipants(e, issue, c.Poster, c.Content, c, mentions); err != nil {
|
if err = mailIssueCommentToParticipants(e, issue, c.Poster, c.Content, c, mentions); err != nil {
|
||||||
log.Error("mailIssueCommentToParticipants: %v", err)
|
log.Error("mailIssueCommentToParticipants: %v", err)
|
||||||
@@ -886,6 +893,7 @@ func CreateCodeComment(doer *User, repo *Repository, issue *Issue, content, tree
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("OpenRepository: %v", err)
|
return nil, fmt.Errorf("OpenRepository: %v", err)
|
||||||
}
|
}
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
// FIXME validate treePath
|
// FIXME validate treePath
|
||||||
// Get latest commit referencing the commented line
|
// Get latest commit referencing the commented line
|
||||||
|
|||||||
@@ -123,11 +123,18 @@ func (issue *Issue) MailParticipants(doer *User, opType ActionType) (err error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (issue *Issue) mailParticipants(e Engine, doer *User, opType ActionType) (err error) {
|
func (issue *Issue) mailParticipants(e Engine, doer *User, opType ActionType) (err error) {
|
||||||
mentions := markup.FindAllMentions(issue.Content)
|
rawMentions := markup.FindAllMentions(issue.Content)
|
||||||
|
userMentions, err := issue.ResolveMentionsByVisibility(e, doer, rawMentions)
|
||||||
if err = UpdateIssueMentions(e, issue.ID, mentions); err != nil {
|
if err != nil {
|
||||||
|
return fmt.Errorf("ResolveMentionsByVisibility [%d]: %v", issue.ID, err)
|
||||||
|
}
|
||||||
|
if err = UpdateIssueMentions(e, issue.ID, userMentions); err != nil {
|
||||||
return fmt.Errorf("UpdateIssueMentions [%d]: %v", issue.ID, err)
|
return fmt.Errorf("UpdateIssueMentions [%d]: %v", issue.ID, err)
|
||||||
}
|
}
|
||||||
|
mentions := make([]string, len(userMentions))
|
||||||
|
for i, u := range userMentions {
|
||||||
|
mentions[i] = u.LowerName
|
||||||
|
}
|
||||||
|
|
||||||
if len(issue.Content) > 0 {
|
if len(issue.Content) > 0 {
|
||||||
if err = mailIssueCommentToParticipants(e, issue, doer, issue.Content, nil, mentions); err != nil {
|
if err = mailIssueCommentToParticipants(e, issue, doer, issue.Content, nil, mentions); err != nil {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ package models
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
@@ -290,6 +291,10 @@ func ChangeMilestoneStatus(m *Milestone, isClosed bool) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
m.IsClosed = isClosed
|
m.IsClosed = isClosed
|
||||||
|
if isClosed {
|
||||||
|
m.ClosedDateUnix = util.TimeStamp(time.Now().Unix())
|
||||||
|
}
|
||||||
|
|
||||||
if err = updateMilestone(sess, m); err != nil {
|
if err = updateMilestone(sess, m); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -320,3 +320,35 @@ func TestIssue_SearchIssueIDsByKeyword(t *testing.T) {
|
|||||||
assert.EqualValues(t, 1, total)
|
assert.EqualValues(t, 1, total)
|
||||||
assert.EqualValues(t, []int64{1}, ids)
|
assert.EqualValues(t, []int64{1}, ids)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIssue_ResolveMentions(t *testing.T) {
|
||||||
|
assert.NoError(t, PrepareTestDatabase())
|
||||||
|
|
||||||
|
testSuccess := func(owner, repo, doer string, mentions []string, expected []int64) {
|
||||||
|
o := AssertExistsAndLoadBean(t, &User{LowerName: owner}).(*User)
|
||||||
|
r := AssertExistsAndLoadBean(t, &Repository{OwnerID: o.ID, LowerName: repo}).(*Repository)
|
||||||
|
issue := &Issue{RepoID: r.ID}
|
||||||
|
d := AssertExistsAndLoadBean(t, &User{LowerName: doer}).(*User)
|
||||||
|
resolved, err := issue.ResolveMentionsByVisibility(x, d, mentions)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
ids := make([]int64, len(resolved))
|
||||||
|
for i, user := range resolved {
|
||||||
|
ids[i] = user.ID
|
||||||
|
}
|
||||||
|
sort.Slice(ids, func(i, j int) bool { return ids[i] < ids[j] })
|
||||||
|
assert.EqualValues(t, expected, ids)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Public repo, existing user
|
||||||
|
testSuccess("user2", "repo1", "user1", []string{"user5"}, []int64{5})
|
||||||
|
// Public repo, non-existing user
|
||||||
|
testSuccess("user2", "repo1", "user1", []string{"nonexisting"}, []int64{})
|
||||||
|
// Public repo, doer
|
||||||
|
testSuccess("user2", "repo1", "user1", []string{"user1"}, []int64{})
|
||||||
|
// Private repo, team member
|
||||||
|
testSuccess("user17", "big_test_private_4", "user20", []string{"user2"}, []int64{2})
|
||||||
|
// Private repo, not a team member
|
||||||
|
testSuccess("user17", "big_test_private_4", "user20", []string{"user5"}, []int64{})
|
||||||
|
// Private repo, whole team
|
||||||
|
testSuccess("user17", "big_test_private_4", "user15", []string{"owners"}, []int64{18})
|
||||||
|
}
|
||||||
|
|||||||
@@ -384,11 +384,13 @@ func dropTableColumns(sess *xorm.Session, tableName string, columnNames ...strin
|
|||||||
}
|
}
|
||||||
for _, index := range res {
|
for _, index := range res {
|
||||||
indexName := index["column_name"]
|
indexName := index["column_name"]
|
||||||
|
if len(indexName) > 0 {
|
||||||
_, err := sess.Exec(fmt.Sprintf("DROP INDEX `%s` ON `%s`", indexName, tableName))
|
_, err := sess.Exec(fmt.Sprintf("DROP INDEX `%s` ON `%s`", indexName, tableName))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Now drop the columns
|
// Now drop the columns
|
||||||
cols := ""
|
cols := ""
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ func releaseAddColumnIsTagAndSyncTags(x *xorm.Engine) error {
|
|||||||
if err = models.SyncReleasesWithTags(repo, gitRepo); err != nil {
|
if err = models.SyncReleasesWithTags(repo, gitRepo); err != nil {
|
||||||
log.Warn("SyncReleasesWithTags: %v", err)
|
log.Warn("SyncReleasesWithTags: %v", err)
|
||||||
}
|
}
|
||||||
|
gitRepo.Close()
|
||||||
}
|
}
|
||||||
if len(repos) < pageSize {
|
if len(repos) < pageSize {
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ func fixReleaseSha1OnReleaseTable(x *xorm.Engine) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
defer gitRepo.Close()
|
||||||
gitRepoCache[release.RepoID] = gitRepo
|
gitRepoCache[release.RepoID] = gitRepo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -252,7 +252,7 @@ func (t *Team) UnitEnabled(tp UnitType) bool {
|
|||||||
|
|
||||||
func (t *Team) unitEnabled(e Engine, tp UnitType) bool {
|
func (t *Team) unitEnabled(e Engine, tp UnitType) bool {
|
||||||
if err := t.getUnits(e); err != nil {
|
if err := t.getUnits(e); err != nil {
|
||||||
log.Warn("Error loading repository (ID: %d) units: %s", t.ID, err.Error())
|
log.Warn("Error loading team (ID: %d) units: %s", t.ID, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, unit := range t.Units {
|
for _, unit := range t.Units {
|
||||||
|
|||||||
@@ -338,6 +338,7 @@ func (pr *PullRequest) GetLastCommitStatus() (status *CommitStatus, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
defer headGitRepo.Close()
|
||||||
|
|
||||||
lastCommitID, err := headGitRepo.GetBranchCommitID(pr.HeadBranch)
|
lastCommitID, err := headGitRepo.GetBranchCommitID(pr.HeadBranch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -527,6 +528,7 @@ func (pr *PullRequest) getMergeCommit() (*git.Commit, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("OpenRepository: %v", err)
|
return nil, fmt.Errorf("OpenRepository: %v", err)
|
||||||
}
|
}
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
commit, err := gitRepo.GetCommit(mergeCommit[:40])
|
commit, err := gitRepo.GetCommit(mergeCommit[:40])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -920,6 +922,7 @@ func (pr *PullRequest) UpdatePatch() (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("OpenRepository: %v", err)
|
return fmt.Errorf("OpenRepository: %v", err)
|
||||||
}
|
}
|
||||||
|
defer headGitRepo.Close()
|
||||||
|
|
||||||
// Add a temporary remote.
|
// Add a temporary remote.
|
||||||
tmpRemote := com.ToStr(time.Now().UnixNano())
|
tmpRemote := com.ToStr(time.Now().UnixNano())
|
||||||
@@ -961,6 +964,7 @@ func (pr *PullRequest) PushToBaseRepo() (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("OpenRepository: %v", err)
|
return fmt.Errorf("OpenRepository: %v", err)
|
||||||
}
|
}
|
||||||
|
defer headGitRepo.Close()
|
||||||
|
|
||||||
tmpRemoteName := fmt.Sprintf("tmp-pull-%d", pr.ID)
|
tmpRemoteName := fmt.Sprintf("tmp-pull-%d", pr.ID)
|
||||||
if err = headGitRepo.AddRemote(tmpRemoteName, pr.BaseRepo.RepoPath(), false); err != nil {
|
if err = headGitRepo.AddRemote(tmpRemoteName, pr.BaseRepo.RepoPath(), false); err != nil {
|
||||||
@@ -1150,6 +1154,7 @@ func checkForInvalidation(requests PullRequestList, repoID int64, doer *User, br
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("PullRequestList.InvalidateCodeComments: %v", err)
|
log.Error("PullRequestList.InvalidateCodeComments: %v", err)
|
||||||
}
|
}
|
||||||
|
gitRepo.Close()
|
||||||
}()
|
}()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ func TestRelease_Create(t *testing.T) {
|
|||||||
|
|
||||||
gitRepo, err := git.OpenRepository(repoPath)
|
gitRepo, err := git.OpenRepository(repoPath)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
assert.NoError(t, CreateRelease(gitRepo, &Release{
|
assert.NoError(t, CreateRelease(gitRepo, &Release{
|
||||||
RepoID: repo.ID,
|
RepoID: repo.ID,
|
||||||
@@ -115,6 +116,7 @@ func TestRelease_MirrorDelete(t *testing.T) {
|
|||||||
|
|
||||||
gitRepo, err := git.OpenRepository(repoPath)
|
gitRepo, err := git.OpenRepository(repoPath)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
findOptions := FindReleasesOptions{IncludeDrafts: true, IncludeTags: true}
|
findOptions := FindReleasesOptions{IncludeDrafts: true, IncludeTags: true}
|
||||||
initCount, err := GetReleaseCountByRepoID(mirror.ID, findOptions)
|
initCount, err := GetReleaseCountByRepoID(mirror.ID, findOptions)
|
||||||
|
|||||||
@@ -950,6 +950,7 @@ func MigrateRepository(doer, u *User, opts MigrateRepoOptions) (*Repository, err
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return repo, fmt.Errorf("OpenRepository: %v", err)
|
return repo, fmt.Errorf("OpenRepository: %v", err)
|
||||||
}
|
}
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
repo.IsEmpty, err = gitRepo.IsEmpty()
|
repo.IsEmpty, err = gitRepo.IsEmpty()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1063,7 +1064,7 @@ func CleanUpMigrateInfo(repo *Repository) (*Repository, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := git.NewCommand("remote", "remove", "origin").RunInDir(repoPath)
|
_, err := git.NewCommand("remote", "rm", "origin").RunInDir(repoPath)
|
||||||
if err != nil && !strings.HasPrefix(err.Error(), "exit status 128 - fatal: No such remote ") {
|
if err != nil && !strings.HasPrefix(err.Error(), "exit status 128 - fatal: No such remote ") {
|
||||||
return repo, fmt.Errorf("CleanUpMigrateInfo: %v", err)
|
return repo, fmt.Errorf("CleanUpMigrateInfo: %v", err)
|
||||||
}
|
}
|
||||||
@@ -1486,6 +1487,13 @@ func TransferOwnership(doer *User, newOwnerName string, repo *Repository) error
|
|||||||
return fmt.Errorf("update owner: %v", err)
|
return fmt.Errorf("update owner: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update pull request headusername
|
||||||
|
if _, err := sess.Where("head_repo_id = ?", repo.ID).Update(&PullRequest{
|
||||||
|
HeadUserName: newOwner.LowerName,
|
||||||
|
}); err != nil {
|
||||||
|
return fmt.Errorf("update pull request: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// Remove redundant collaborators.
|
// Remove redundant collaborators.
|
||||||
collaborators, err := repo.getCollaborators(sess)
|
collaborators, err := repo.getCollaborators(sess)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1895,12 +1903,11 @@ func DeleteRepository(doer *User, uid, repoID int64) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if count > 1 {
|
if count > 1 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
oidPath := filepath.Join(v.Oid[0:2], v.Oid[2:4], v.Oid[4:len(v.Oid)])
|
oidPath := filepath.Join(setting.LFS.ContentPath, v.Oid[0:2], v.Oid[2:4], v.Oid[4:len(v.Oid)])
|
||||||
removeAllWithNotice(sess, "Delete orphaned LFS file", oidPath)
|
removeAllWithNotice(sess, "Delete orphaned LFS file", oidPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ func GetActivityStats(repo *Repository, timeFrom time.Time, releases, issues, pr
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("OpenRepository: %v", err)
|
return nil, fmt.Errorf("OpenRepository: %v", err)
|
||||||
}
|
}
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
code, err := gitRepo.GetCodeActivityStats(timeFrom, repo.DefaultBranch)
|
code, err := gitRepo.GetCodeActivityStats(timeFrom, repo.DefaultBranch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("FillFromGit: %v", err)
|
return nil, fmt.Errorf("FillFromGit: %v", err)
|
||||||
@@ -79,6 +81,8 @@ func GetActivityStatsTopAuthors(repo *Repository, timeFrom time.Time, count int)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("OpenRepository: %v", err)
|
return nil, fmt.Errorf("OpenRepository: %v", err)
|
||||||
}
|
}
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
code, err := gitRepo.GetCodeActivityStats(timeFrom, "")
|
code, err := gitRepo.GetCodeActivityStats(timeFrom, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("FillFromGit: %v", err)
|
return nil, fmt.Errorf("FillFromGit: %v", err)
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ func (repo *Repository) GetBranch(branch string) (*git.Branch, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
return gitRepo.GetBranch(branch)
|
return gitRepo.GetBranch(branch)
|
||||||
}
|
}
|
||||||
@@ -38,6 +39,7 @@ func (repo *Repository) CheckBranchName(name string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
branches, err := repo.GetBranches()
|
branches, err := repo.GetBranches()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -94,6 +96,7 @@ func (repo *Repository) CreateNewBranch(doer *User, oldBranchName, branchName st
|
|||||||
log.Error("Unable to open temporary repository: %s (%v)", basePath, err)
|
log.Error("Unable to open temporary repository: %s (%v)", basePath, err)
|
||||||
return fmt.Errorf("Failed to open new temporary repository in: %s %v", basePath, err)
|
return fmt.Errorf("Failed to open new temporary repository in: %s %v", basePath, err)
|
||||||
}
|
}
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
if err = gitRepo.CreateBranch(branchName, oldBranchName); err != nil {
|
if err = gitRepo.CreateBranch(branchName, oldBranchName); err != nil {
|
||||||
log.Error("Unable to create branch: %s from %s. (%v)", branchName, oldBranchName, err)
|
log.Error("Unable to create branch: %s from %s. (%v)", branchName, oldBranchName, err)
|
||||||
@@ -140,6 +143,7 @@ func (repo *Repository) CreateNewBranchFromCommit(doer *User, commit, branchName
|
|||||||
log.Error("Unable to open temporary repository: %s (%v)", basePath, err)
|
log.Error("Unable to open temporary repository: %s (%v)", basePath, err)
|
||||||
return fmt.Errorf("Failed to open new temporary repository in: %s %v", basePath, err)
|
return fmt.Errorf("Failed to open new temporary repository in: %s %v", basePath, err)
|
||||||
}
|
}
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
if err = gitRepo.CreateBranch(branchName, commit); err != nil {
|
if err = gitRepo.CreateBranch(branchName, commit); err != nil {
|
||||||
log.Error("Unable to create branch: %s from %s. (%v)", branchName, commit, err)
|
log.Error("Unable to create branch: %s from %s. (%v)", branchName, commit, err)
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ func (m *Mirror) FullAddress() string {
|
|||||||
func (m *Mirror) SaveAddress(addr string) error {
|
func (m *Mirror) SaveAddress(addr string) error {
|
||||||
repoPath := m.Repo.RepoPath()
|
repoPath := m.Repo.RepoPath()
|
||||||
// Remove old origin
|
// Remove old origin
|
||||||
_, err := git.NewCommand("remote", "remove", "origin").RunInDir(repoPath)
|
_, err := git.NewCommand("remote", "rm", "origin").RunInDir(repoPath)
|
||||||
if err != nil && !strings.HasPrefix(err.Error(), "exit status 128 - fatal: No such remote ") {
|
if err != nil && !strings.HasPrefix(err.Error(), "exit status 128 - fatal: No such remote ") {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -242,6 +242,7 @@ func (m *Mirror) runSync() ([]*mirrorSyncResult, bool) {
|
|||||||
if err = SyncReleasesWithTags(m.Repo, gitRepo); err != nil {
|
if err = SyncReleasesWithTags(m.Repo, gitRepo); err != nil {
|
||||||
log.Error("Failed to synchronize tags to releases for repository: %v", err)
|
log.Error("Failed to synchronize tags to releases for repository: %v", err)
|
||||||
}
|
}
|
||||||
|
gitRepo.Close()
|
||||||
|
|
||||||
if err := m.Repo.UpdateSize(); err != nil {
|
if err := m.Repo.UpdateSize(); err != nil {
|
||||||
log.Error("Failed to update size for mirror repository: %v", err)
|
log.Error("Failed to update size for mirror repository: %v", err)
|
||||||
@@ -426,6 +427,8 @@ func SyncMirrors() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gitRepo.Close()
|
||||||
|
|
||||||
// Get latest commit date and update to current repository updated time
|
// Get latest commit date and update to current repository updated time
|
||||||
commitDate, err := git.GetLatestCommitTime(m.Repo.RepoPath())
|
commitDate, err := git.GetLatestCommitTime(m.Repo.RepoPath())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
// Copyright 2019 The Gitea Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a MIT-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"code.gitea.io/gitea/modules/git"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GetTagsByPath returns repo tags by its path
|
|
||||||
func GetTagsByPath(path string) ([]*git.Tag, error) {
|
|
||||||
gitRepo, err := git.OpenRepository(path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return gitRepo.GetTagInfos()
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetTags return repo's tags
|
|
||||||
func (repo *Repository) GetTags() ([]*git.Tag, error) {
|
|
||||||
return GetTagsByPath(repo.RepoPath())
|
|
||||||
}
|
|
||||||
@@ -315,6 +315,18 @@ func appendAuthorizedKeysToFile(keys ...*PublicKey) error {
|
|||||||
sshOpLocker.Lock()
|
sshOpLocker.Lock()
|
||||||
defer sshOpLocker.Unlock()
|
defer sshOpLocker.Unlock()
|
||||||
|
|
||||||
|
if setting.SSH.RootPath != "" {
|
||||||
|
// First of ensure that the RootPath is present, and if not make it with 0700 permissions
|
||||||
|
// This of course doesn't guarantee that this is the right directory for authorized_keys
|
||||||
|
// but at least if it's supposed to be this directory and it doesn't exist and we're the
|
||||||
|
// right user it will at least be created properly.
|
||||||
|
err := os.MkdirAll(setting.SSH.RootPath, 0700)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Unable to MkdirAll(%s): %v", setting.SSH.RootPath, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fPath := filepath.Join(setting.SSH.RootPath, "authorized_keys")
|
fPath := filepath.Join(setting.SSH.RootPath, "authorized_keys")
|
||||||
f, err := os.OpenFile(fPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
|
f, err := os.OpenFile(fPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -602,6 +614,18 @@ func rewriteAllPublicKeys(e Engine) error {
|
|||||||
sshOpLocker.Lock()
|
sshOpLocker.Lock()
|
||||||
defer sshOpLocker.Unlock()
|
defer sshOpLocker.Unlock()
|
||||||
|
|
||||||
|
if setting.SSH.RootPath != "" {
|
||||||
|
// First of ensure that the RootPath is present, and if not make it with 0700 permissions
|
||||||
|
// This of course doesn't guarantee that this is the right directory for authorized_keys
|
||||||
|
// but at least if it's supposed to be this directory and it doesn't exist and we're the
|
||||||
|
// right user it will at least be created properly.
|
||||||
|
err := os.MkdirAll(setting.SSH.RootPath, 0700)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Unable to MkdirAll(%s): %v", setting.SSH.RootPath, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fPath := filepath.Join(setting.SSH.RootPath, "authorized_keys")
|
fPath := filepath.Join(setting.SSH.RootPath, "authorized_keys")
|
||||||
tmpPath := fPath + ".tmp"
|
tmpPath := fPath + ".tmp"
|
||||||
t, err := os.OpenFile(tmpPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
|
t, err := os.OpenFile(tmpPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
|
||||||
|
|||||||
@@ -211,6 +211,7 @@ func pushUpdate(opts PushUpdateOptions) (repo *Repository, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("OpenRepository: %v", err)
|
return nil, fmt.Errorf("OpenRepository: %v", err)
|
||||||
}
|
}
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
if err = repo.UpdateSize(); err != nil {
|
if err = repo.UpdateSize(); err != nil {
|
||||||
log.Error("Failed to update size for repository: %v", err)
|
log.Error("Failed to update size for repository: %v", err)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ func TestGetUserHeatmapDataByUser(t *testing.T) {
|
|||||||
CountResult int
|
CountResult int
|
||||||
JSONResult string
|
JSONResult string
|
||||||
}{
|
}{
|
||||||
{2, 1, `[{"timestamp":1540080000,"contributions":1}]`},
|
{2, 1, `[{"timestamp":1571616000,"contributions":1}]`},
|
||||||
{3, 0, `[]`},
|
{3, 0, `[]`},
|
||||||
}
|
}
|
||||||
// Prepare
|
// Prepare
|
||||||
@@ -41,7 +41,7 @@ func TestGetUserHeatmapDataByUser(t *testing.T) {
|
|||||||
// Get the heatmap and compare
|
// Get the heatmap and compare
|
||||||
heatmap, err := GetUserHeatmapDataByUser(user)
|
heatmap, err := GetUserHeatmapDataByUser(user)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, len(actions), len(heatmap))
|
assert.Equal(t, len(actions), len(heatmap), "invalid action count: did the test data became too old?")
|
||||||
assert.Equal(t, tc.CountResult, len(heatmap))
|
assert.Equal(t, tc.CountResult, len(heatmap))
|
||||||
|
|
||||||
//Test JSON rendering
|
//Test JSON rendering
|
||||||
|
|||||||
@@ -140,6 +140,7 @@ func (repo *Repository) updateWikiPage(doer *User, oldWikiName, newWikiName, con
|
|||||||
log.Error("Unable to open temporary repository: %s (%v)", basePath, err)
|
log.Error("Unable to open temporary repository: %s (%v)", basePath, err)
|
||||||
return fmt.Errorf("Failed to open new temporary repository in: %s %v", basePath, err)
|
return fmt.Errorf("Failed to open new temporary repository in: %s %v", basePath, err)
|
||||||
}
|
}
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
if hasMasterBranch {
|
if hasMasterBranch {
|
||||||
if err := gitRepo.ReadTreeToIndex("HEAD"); err != nil {
|
if err := gitRepo.ReadTreeToIndex("HEAD"); err != nil {
|
||||||
@@ -276,6 +277,7 @@ func (repo *Repository) DeleteWikiPage(doer *User, wikiName string) (err error)
|
|||||||
log.Error("Unable to open temporary repository: %s (%v)", basePath, err)
|
log.Error("Unable to open temporary repository: %s (%v)", basePath, err)
|
||||||
return fmt.Errorf("Failed to open new temporary repository in: %s %v", basePath, err)
|
return fmt.Errorf("Failed to open new temporary repository in: %s %v", basePath, err)
|
||||||
}
|
}
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
if err := gitRepo.ReadTreeToIndex("HEAD"); err != nil {
|
if err := gitRepo.ReadTreeToIndex("HEAD"); err != nil {
|
||||||
log.Error("Unable to read HEAD tree to index in: %s %v", basePath, err)
|
log.Error("Unable to read HEAD tree to index in: %s %v", basePath, err)
|
||||||
|
|||||||
@@ -161,6 +161,7 @@ func TestRepository_AddWikiPage(t *testing.T) {
|
|||||||
// Now need to show that the page has been added:
|
// Now need to show that the page has been added:
|
||||||
gitRepo, err := git.OpenRepository(repo.WikiPath())
|
gitRepo, err := git.OpenRepository(repo.WikiPath())
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
defer gitRepo.Close()
|
||||||
masterTree, err := gitRepo.GetTree("master")
|
masterTree, err := gitRepo.GetTree("master")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
wikiPath := WikiNameToFilename(wikiName)
|
wikiPath := WikiNameToFilename(wikiName)
|
||||||
@@ -214,6 +215,7 @@ func TestRepository_EditWikiPage(t *testing.T) {
|
|||||||
_, err := masterTree.GetTreeEntryByPath("Home.md")
|
_, err := masterTree.GetTreeEntryByPath("Home.md")
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
}
|
}
|
||||||
|
gitRepo.Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,6 +228,7 @@ func TestRepository_DeleteWikiPage(t *testing.T) {
|
|||||||
// Now need to show that the page has been added:
|
// Now need to show that the page has been added:
|
||||||
gitRepo, err := git.OpenRepository(repo.WikiPath())
|
gitRepo, err := git.OpenRepository(repo.WikiPath())
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
defer gitRepo.Close()
|
||||||
masterTree, err := gitRepo.GetTree("master")
|
masterTree, err := gitRepo.GetTree("master")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
wikiPath := WikiNameToFilename("Home")
|
wikiPath := WikiNameToFilename("Home")
|
||||||
|
|||||||
@@ -187,7 +187,16 @@ func ReferencesGitRepo(allowEmpty bool) macaron.Handler {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.Repo.GitRepo = gitRepo
|
ctx.Repo.GitRepo = gitRepo
|
||||||
|
// We opened it, we should close it
|
||||||
|
defer func() {
|
||||||
|
// If it's been set to nil then assume someone else has closed it.
|
||||||
|
if ctx.Repo.GitRepo != nil {
|
||||||
|
ctx.Repo.GitRepo.Close()
|
||||||
}
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ func HandleOrgAssignment(ctx *Context, args ...bool) {
|
|||||||
|
|
||||||
// Force redirection when username is actually a user.
|
// Force redirection when username is actually a user.
|
||||||
if !org.IsOrganization() {
|
if !org.IsOrganization() {
|
||||||
ctx.Redirect("/" + org.Name)
|
ctx.Redirect(setting.AppSubURL + "/" + org.Name)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ func RedirectToRepo(ctx *Context, redirectRepoID int64) {
|
|||||||
if ctx.Req.URL.RawQuery != "" {
|
if ctx.Req.URL.RawQuery != "" {
|
||||||
redirectPath += "?" + ctx.Req.URL.RawQuery
|
redirectPath += "?" + ctx.Req.URL.RawQuery
|
||||||
}
|
}
|
||||||
ctx.Redirect(redirectPath)
|
ctx.Redirect(path.Join(setting.AppSubURL, redirectPath))
|
||||||
}
|
}
|
||||||
|
|
||||||
func repoAssignment(ctx *Context, repo *models.Repository) {
|
func repoAssignment(ctx *Context, repo *models.Repository) {
|
||||||
@@ -364,6 +364,13 @@ func RepoAssignment() macaron.Handler {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.Repo.GitRepo = gitRepo
|
ctx.Repo.GitRepo = gitRepo
|
||||||
|
// We opened it, we should close it
|
||||||
|
defer func() {
|
||||||
|
// If it's been set to nil then assume someone else has closed it.
|
||||||
|
if ctx.Repo.GitRepo != nil {
|
||||||
|
ctx.Repo.GitRepo.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
ctx.Repo.RepoLink = repo.Link()
|
ctx.Repo.RepoLink = repo.Link()
|
||||||
ctx.Data["RepoLink"] = ctx.Repo.RepoLink
|
ctx.Data["RepoLink"] = ctx.Repo.RepoLink
|
||||||
ctx.Data["RepoRelPath"] = ctx.Repo.Owner.Name + "/" + ctx.Repo.Repository.Name
|
ctx.Data["RepoRelPath"] = ctx.Repo.Owner.Name + "/" + ctx.Repo.Repository.Name
|
||||||
@@ -426,6 +433,7 @@ func RepoAssignment() macaron.Handler {
|
|||||||
// repo is empty and display enable
|
// repo is empty and display enable
|
||||||
if ctx.Repo.Repository.IsEmpty {
|
if ctx.Repo.Repository.IsEmpty {
|
||||||
ctx.Data["BranchName"] = ctx.Repo.Repository.DefaultBranch
|
ctx.Data["BranchName"] = ctx.Repo.Repository.DefaultBranch
|
||||||
|
ctx.Next()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -476,6 +484,7 @@ func RepoAssignment() macaron.Handler {
|
|||||||
ctx.Data["GoDocDirectory"] = prefix + "{/dir}"
|
ctx.Data["GoDocDirectory"] = prefix + "{/dir}"
|
||||||
ctx.Data["GoDocFile"] = prefix + "{/dir}/{file}#L{line}"
|
ctx.Data["GoDocFile"] = prefix + "{/dir}/{file}#L{line}"
|
||||||
}
|
}
|
||||||
|
ctx.Next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -581,6 +590,13 @@ func RepoRefByType(refType RepoRefType) macaron.Handler {
|
|||||||
ctx.ServerError("RepoRef Invalid repo "+repoPath, err)
|
ctx.ServerError("RepoRef Invalid repo "+repoPath, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// We opened it, we should close it
|
||||||
|
defer func() {
|
||||||
|
// If it's been set to nil then assume someone else has closed it.
|
||||||
|
if ctx.Repo.GitRepo != nil {
|
||||||
|
ctx.Repo.GitRepo.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get default branch.
|
// Get default branch.
|
||||||
@@ -669,6 +685,8 @@ func RepoRefByType(refType RepoRefType) macaron.Handler {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.Data["CommitsCount"] = ctx.Repo.CommitsCount
|
ctx.Data["CommitsCount"] = ctx.Repo.CommitsCount
|
||||||
|
|
||||||
|
ctx.Next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -87,10 +87,11 @@ func (r *BlameReader) Close() error {
|
|||||||
|
|
||||||
// CreateBlameReader creates reader for given repository, commit and file
|
// CreateBlameReader creates reader for given repository, commit and file
|
||||||
func CreateBlameReader(repoPath, commitID, file string) (*BlameReader, error) {
|
func CreateBlameReader(repoPath, commitID, file string) (*BlameReader, error) {
|
||||||
_, err := OpenRepository(repoPath)
|
gitRepo, err := OpenRepository(repoPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
gitRepo.Close()
|
||||||
|
|
||||||
return createBlameReader(repoPath, GitExecutable, "blame", commitID, "--porcelain", "--", file)
|
return createBlameReader(repoPath, GitExecutable, "blame", commitID, "--porcelain", "--", file)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ THE SOFTWARE.
|
|||||||
`
|
`
|
||||||
repo, err := OpenRepository("../../.git")
|
repo, err := OpenRepository("../../.git")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
defer repo.Close()
|
||||||
|
|
||||||
testBlob, err := repo.GetBlob("a8d4b49dd073a4a38a7e58385eeff7cc52568697")
|
testBlob, err := repo.GetBlob("a8d4b49dd073a4a38a7e58385eeff7cc52568697")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
@@ -55,6 +57,8 @@ func Benchmark_Blob_Data(b *testing.B) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatal(err)
|
b.Fatal(err)
|
||||||
}
|
}
|
||||||
|
defer repo.Close()
|
||||||
|
|
||||||
testBlob, err := repo.GetBlob("a8d4b49dd073a4a38a7e58385eeff7cc52568697")
|
testBlob, err := repo.GetBlob("a8d4b49dd073a4a38a7e58385eeff7cc52568697")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatal(err)
|
b.Fatal(err)
|
||||||
|
|||||||
@@ -77,6 +77,8 @@ func TestEntries_GetCommitsInfo(t *testing.T) {
|
|||||||
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
|
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
|
||||||
bareRepo1, err := OpenRepository(bareRepo1Path)
|
bareRepo1, err := OpenRepository(bareRepo1Path)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
defer bareRepo1.Close()
|
||||||
|
|
||||||
testGetCommitsInfo(t, bareRepo1)
|
testGetCommitsInfo(t, bareRepo1)
|
||||||
|
|
||||||
clonedPath, err := cloneRepo(bareRepo1Path, testReposDir, "repo1_TestEntries_GetCommitsInfo")
|
clonedPath, err := cloneRepo(bareRepo1Path, testReposDir, "repo1_TestEntries_GetCommitsInfo")
|
||||||
@@ -84,6 +86,8 @@ func TestEntries_GetCommitsInfo(t *testing.T) {
|
|||||||
defer os.RemoveAll(clonedPath)
|
defer os.RemoveAll(clonedPath)
|
||||||
clonedRepo1, err := OpenRepository(clonedPath)
|
clonedRepo1, err := OpenRepository(clonedPath)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
defer clonedRepo1.Close()
|
||||||
|
|
||||||
testGetCommitsInfo(t, clonedRepo1)
|
testGetCommitsInfo(t, clonedRepo1)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,13 +105,16 @@ func BenchmarkEntries_GetCommitsInfo(b *testing.B) {
|
|||||||
for _, benchmark := range benchmarks {
|
for _, benchmark := range benchmarks {
|
||||||
var commit *Commit
|
var commit *Commit
|
||||||
var entries Entries
|
var entries Entries
|
||||||
|
var repo *Repository
|
||||||
if repoPath, err := cloneRepo(benchmark.url, benchmarkReposDir, benchmark.name); err != nil {
|
if repoPath, err := cloneRepo(benchmark.url, benchmarkReposDir, benchmark.name); err != nil {
|
||||||
b.Fatal(err)
|
b.Fatal(err)
|
||||||
} else if repo, err := OpenRepository(repoPath); err != nil {
|
} else if repo, err = OpenRepository(repoPath); err != nil {
|
||||||
b.Fatal(err)
|
b.Fatal(err)
|
||||||
} else if commit, err = repo.GetBranchCommit("master"); err != nil {
|
} else if commit, err = repo.GetBranchCommit("master"); err != nil {
|
||||||
|
repo.Close()
|
||||||
b.Fatal(err)
|
b.Fatal(err)
|
||||||
} else if entries, err = commit.Tree.ListEntries(); err != nil {
|
} else if entries, err = commit.Tree.ListEntries(); err != nil {
|
||||||
|
repo.Close()
|
||||||
b.Fatal(err)
|
b.Fatal(err)
|
||||||
}
|
}
|
||||||
entries.Sort()
|
entries.Sort()
|
||||||
@@ -120,5 +127,6 @@ func BenchmarkEntries_GetCommitsInfo(b *testing.B) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
repo.Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,6 +90,11 @@ func (h *Hook) Update() error {
|
|||||||
h.IsActive = false
|
h.IsActive = false
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
d := filepath.Dir(h.path)
|
||||||
|
if err := os.MkdirAll(d, os.ModePerm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
err := ioutil.WriteFile(h.path, []byte(strings.Replace(h.Content, "\r", "", -1)), os.ModePerm)
|
err := ioutil.WriteFile(h.path, []byte(strings.Replace(h.Content, "\r", "", -1)), os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ func TestGetNotes(t *testing.T) {
|
|||||||
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
|
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
|
||||||
bareRepo1, err := OpenRepository(bareRepo1Path)
|
bareRepo1, err := OpenRepository(bareRepo1Path)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
defer bareRepo1.Close()
|
||||||
|
|
||||||
note := Note{}
|
note := Note{}
|
||||||
err = GetNote(bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653", ¬e)
|
err = GetNote(bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653", ¬e)
|
||||||
@@ -27,6 +28,7 @@ func TestGetNestedNotes(t *testing.T) {
|
|||||||
repoPath := filepath.Join(testReposDir, "repo3_notes")
|
repoPath := filepath.Join(testReposDir, "repo3_notes")
|
||||||
repo, err := OpenRepository(repoPath)
|
repo, err := OpenRepository(repoPath)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
defer repo.Close()
|
||||||
|
|
||||||
note := Note{}
|
note := Note{}
|
||||||
err = GetNote(repo, "3e668dbfac39cbc80a9ff9c61eb565d944453ba4", ¬e)
|
err = GetNote(repo, "3e668dbfac39cbc80a9ff9c61eb565d944453ba4", ¬e)
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
gitealog "code.gitea.io/gitea/modules/log"
|
||||||
"github.com/Unknwon/com"
|
"github.com/Unknwon/com"
|
||||||
"gopkg.in/src-d/go-billy.v4/osfs"
|
"gopkg.in/src-d/go-billy.v4/osfs"
|
||||||
gogit "gopkg.in/src-d/go-git.v4"
|
gogit "gopkg.in/src-d/go-git.v4"
|
||||||
@@ -107,6 +108,21 @@ func OpenRepository(repoPath string) (*Repository, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close this repository, in particular close the underlying gogitStorage if this is not nil
|
||||||
|
func (repo *Repository) Close() {
|
||||||
|
if repo == nil || repo.gogitStorage == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := repo.gogitStorage.Close(); err != nil {
|
||||||
|
gitealog.Error("Error closing storage: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GoGitRepo gets the go-git repo representation
|
||||||
|
func (repo *Repository) GoGitRepo() *gogit.Repository {
|
||||||
|
return repo.gogitRepo
|
||||||
|
}
|
||||||
|
|
||||||
// IsEmpty Check if repository is empty.
|
// IsEmpty Check if repository is empty.
|
||||||
func (repo *Repository) IsEmpty() (bool, error) {
|
func (repo *Repository) IsEmpty() (bool, error) {
|
||||||
var errbuf strings.Builder
|
var errbuf strings.Builder
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ func TestRepository_GetBlob_Found(t *testing.T) {
|
|||||||
repoPath := filepath.Join(testReposDir, "repo1_bare")
|
repoPath := filepath.Join(testReposDir, "repo1_bare")
|
||||||
r, err := OpenRepository(repoPath)
|
r, err := OpenRepository(repoPath)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
defer r.Close()
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
OID string
|
OID string
|
||||||
@@ -44,6 +45,7 @@ func TestRepository_GetBlob_NotExist(t *testing.T) {
|
|||||||
repoPath := filepath.Join(testReposDir, "repo1_bare")
|
repoPath := filepath.Join(testReposDir, "repo1_bare")
|
||||||
r, err := OpenRepository(repoPath)
|
r, err := OpenRepository(repoPath)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
defer r.Close()
|
||||||
|
|
||||||
testCase := "0000000000000000000000000000000000000000"
|
testCase := "0000000000000000000000000000000000000000"
|
||||||
testError := ErrNotExist{testCase, ""}
|
testError := ErrNotExist{testCase, ""}
|
||||||
@@ -57,6 +59,7 @@ func TestRepository_GetBlob_NoId(t *testing.T) {
|
|||||||
repoPath := filepath.Join(testReposDir, "repo1_bare")
|
repoPath := filepath.Join(testReposDir, "repo1_bare")
|
||||||
r, err := OpenRepository(repoPath)
|
r, err := OpenRepository(repoPath)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
defer r.Close()
|
||||||
|
|
||||||
testCase := ""
|
testCase := ""
|
||||||
testError := fmt.Errorf("Length must be 40: %s", testCase)
|
testError := fmt.Errorf("Length must be 40: %s", testCase)
|
||||||
|
|||||||
@@ -28,8 +28,14 @@ func IsBranchExist(repoPath, name string) bool {
|
|||||||
|
|
||||||
// IsBranchExist returns true if given branch exists in current repository.
|
// IsBranchExist returns true if given branch exists in current repository.
|
||||||
func (repo *Repository) IsBranchExist(name string) bool {
|
func (repo *Repository) IsBranchExist(name string) bool {
|
||||||
_, err := repo.gogitRepo.Reference(plumbing.ReferenceName(BranchPrefix+name), true)
|
if name == "" {
|
||||||
return err == nil
|
return false
|
||||||
|
}
|
||||||
|
reference, err := repo.gogitRepo.Reference(plumbing.ReferenceName(BranchPrefix+name), true)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return reference.Type() != plumbing.InvalidReference
|
||||||
}
|
}
|
||||||
|
|
||||||
// Branch represents a Git branch.
|
// Branch represents a Git branch.
|
||||||
@@ -102,6 +108,7 @@ func GetBranchesByPath(path string) ([]*Branch, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
brs, err := gitRepo.GetBranches()
|
brs, err := gitRepo.GetBranches()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -165,7 +172,7 @@ func (repo *Repository) AddRemote(name, url string, fetch bool) error {
|
|||||||
|
|
||||||
// RemoveRemote removes a remote from repository.
|
// RemoveRemote removes a remote from repository.
|
||||||
func (repo *Repository) RemoveRemote(name string) error {
|
func (repo *Repository) RemoveRemote(name string) error {
|
||||||
_, err := NewCommand("remote", "remove", name).RunInDir(repo.Path)
|
_, err := NewCommand("remote", "rm", name).RunInDir(repo.Path)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ func TestRepository_GetBranches(t *testing.T) {
|
|||||||
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
|
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
|
||||||
bareRepo1, err := OpenRepository(bareRepo1Path)
|
bareRepo1, err := OpenRepository(bareRepo1Path)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
defer bareRepo1.Close()
|
||||||
|
|
||||||
branches, err := bareRepo1.GetBranches()
|
branches, err := bareRepo1.GetBranches()
|
||||||
|
|
||||||
@@ -29,6 +30,7 @@ func BenchmarkRepository_GetBranches(b *testing.B) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatal(err)
|
b.Fatal(err)
|
||||||
}
|
}
|
||||||
|
defer bareRepo1.Close()
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
_, err := bareRepo1.GetBranches()
|
_, err := bareRepo1.GetBranches()
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ func TestRepository_GetCommitBranches(t *testing.T) {
|
|||||||
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
|
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
|
||||||
bareRepo1, err := OpenRepository(bareRepo1Path)
|
bareRepo1, err := OpenRepository(bareRepo1Path)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
defer bareRepo1.Close()
|
||||||
|
|
||||||
// these test case are specific to the repo1_bare test repo
|
// these test case are specific to the repo1_bare test repo
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
@@ -40,6 +41,9 @@ func TestRepository_GetCommitBranches(t *testing.T) {
|
|||||||
func TestGetTagCommitWithSignature(t *testing.T) {
|
func TestGetTagCommitWithSignature(t *testing.T) {
|
||||||
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
|
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
|
||||||
bareRepo1, err := OpenRepository(bareRepo1Path)
|
bareRepo1, err := OpenRepository(bareRepo1Path)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
defer bareRepo1.Close()
|
||||||
|
|
||||||
commit, err := bareRepo1.GetCommit("3ad28a9149a2864384548f3d17ed7f38014c9e8a")
|
commit, err := bareRepo1.GetCommit("3ad28a9149a2864384548f3d17ed7f38014c9e8a")
|
||||||
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
@@ -52,6 +56,9 @@ func TestGetTagCommitWithSignature(t *testing.T) {
|
|||||||
func TestGetCommitWithBadCommitID(t *testing.T) {
|
func TestGetCommitWithBadCommitID(t *testing.T) {
|
||||||
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
|
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
|
||||||
bareRepo1, err := OpenRepository(bareRepo1Path)
|
bareRepo1, err := OpenRepository(bareRepo1Path)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
defer bareRepo1.Close()
|
||||||
|
|
||||||
commit, err := bareRepo1.GetCommit("bad_branch")
|
commit, err := bareRepo1.GetCommit("bad_branch")
|
||||||
assert.Nil(t, commit)
|
assert.Nil(t, commit)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ func TestGetFormatPatch(t *testing.T) {
|
|||||||
defer os.RemoveAll(clonedPath)
|
defer os.RemoveAll(clonedPath)
|
||||||
repo, err := OpenRepository(clonedPath)
|
repo, err := OpenRepository(clonedPath)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
defer repo.Close()
|
||||||
rd, err := repo.GetFormatPatch("8d92fc95^", "8d92fc95")
|
rd, err := repo.GetFormatPatch("8d92fc95^", "8d92fc95")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
patchb, err := ioutil.ReadAll(rd)
|
patchb, err := ioutil.ReadAll(rd)
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ func TestRepository_GetRefs(t *testing.T) {
|
|||||||
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
|
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
|
||||||
bareRepo1, err := OpenRepository(bareRepo1Path)
|
bareRepo1, err := OpenRepository(bareRepo1Path)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
defer bareRepo1.Close()
|
||||||
|
|
||||||
refs, err := bareRepo1.GetRefs()
|
refs, err := bareRepo1.GetRefs()
|
||||||
|
|
||||||
@@ -38,6 +39,7 @@ func TestRepository_GetRefsFiltered(t *testing.T) {
|
|||||||
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
|
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
|
||||||
bareRepo1, err := OpenRepository(bareRepo1Path)
|
bareRepo1, err := OpenRepository(bareRepo1Path)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
defer bareRepo1.Close()
|
||||||
|
|
||||||
refs, err := bareRepo1.GetRefsFiltered(TagPrefix)
|
refs, err := bareRepo1.GetRefsFiltered(TagPrefix)
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ func TestRepository_GetCodeActivityStats(t *testing.T) {
|
|||||||
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
|
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
|
||||||
bareRepo1, err := OpenRepository(bareRepo1Path)
|
bareRepo1, err := OpenRepository(bareRepo1Path)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
defer bareRepo1.Close()
|
||||||
|
|
||||||
timeFrom, err := time.Parse(time.RFC3339, "2016-01-01T00:00:00+00:00")
|
timeFrom, err := time.Parse(time.RFC3339, "2016-01-01T00:00:00+00:00")
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ func TestRepository_GetTags(t *testing.T) {
|
|||||||
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
|
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
|
||||||
bareRepo1, err := OpenRepository(bareRepo1Path)
|
bareRepo1, err := OpenRepository(bareRepo1Path)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
defer bareRepo1.Close()
|
||||||
|
|
||||||
tags, err := bareRepo1.GetTagInfos()
|
tags, err := bareRepo1.GetTagInfos()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
@@ -34,6 +35,7 @@ func TestRepository_GetTag(t *testing.T) {
|
|||||||
|
|
||||||
bareRepo1, err := OpenRepository(clonedPath)
|
bareRepo1, err := OpenRepository(clonedPath)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
defer bareRepo1.Close()
|
||||||
|
|
||||||
lTagCommitID := "6fbd69e9823458e6c4a2fc5c0f6bc022b2f2acd1"
|
lTagCommitID := "6fbd69e9823458e6c4a2fc5c0f6bc022b2f2acd1"
|
||||||
lTagName := "lightweightTag"
|
lTagName := "lightweightTag"
|
||||||
@@ -83,6 +85,7 @@ func TestRepository_GetAnnotatedTag(t *testing.T) {
|
|||||||
|
|
||||||
bareRepo1, err := OpenRepository(clonedPath)
|
bareRepo1, err := OpenRepository(clonedPath)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
defer bareRepo1.Close()
|
||||||
|
|
||||||
lTagCommitID := "6fbd69e9823458e6c4a2fc5c0f6bc022b2f2acd1"
|
lTagCommitID := "6fbd69e9823458e6c4a2fc5c0f6bc022b2f2acd1"
|
||||||
lTagName := "lightweightTag"
|
lTagName := "lightweightTag"
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ func TestRepoIsEmpty(t *testing.T) {
|
|||||||
emptyRepo2Path := filepath.Join(testReposDir, "repo2_empty")
|
emptyRepo2Path := filepath.Join(testReposDir, "repo2_empty")
|
||||||
repo, err := OpenRepository(emptyRepo2Path)
|
repo, err := OpenRepository(emptyRepo2Path)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
defer repo.Close()
|
||||||
isEmpty, err := repo.IsEmpty()
|
isEmpty, err := repo.IsEmpty()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.True(t, isEmpty)
|
assert.True(t, isEmpty)
|
||||||
|
|||||||
@@ -6,11 +6,13 @@
|
|||||||
package git
|
package git
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/mcuadros/go-version"
|
||||||
"gopkg.in/src-d/go-git.v4/plumbing"
|
"gopkg.in/src-d/go-git.v4/plumbing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -63,6 +65,11 @@ type CommitTreeOpts struct {
|
|||||||
|
|
||||||
// CommitTree creates a commit from a given tree id for the user with provided message
|
// CommitTree creates a commit from a given tree id for the user with provided message
|
||||||
func (repo *Repository) CommitTree(sig *Signature, tree *Tree, opts CommitTreeOpts) (SHA1, error) {
|
func (repo *Repository) CommitTree(sig *Signature, tree *Tree, opts CommitTreeOpts) (SHA1, error) {
|
||||||
|
binVersion, err := BinVersion()
|
||||||
|
if err != nil {
|
||||||
|
return SHA1{}, err
|
||||||
|
}
|
||||||
|
|
||||||
commitTimeStr := time.Now().Format(time.RFC3339)
|
commitTimeStr := time.Now().Format(time.RFC3339)
|
||||||
|
|
||||||
// Because this may call hooks we should pass in the environment
|
// Because this may call hooks we should pass in the environment
|
||||||
@@ -80,20 +87,24 @@ func (repo *Repository) CommitTree(sig *Signature, tree *Tree, opts CommitTreeOp
|
|||||||
cmd.AddArguments("-p", parent)
|
cmd.AddArguments("-p", parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.AddArguments("-m", opts.Message)
|
messageBytes := new(bytes.Buffer)
|
||||||
|
_, _ = messageBytes.WriteString(opts.Message)
|
||||||
|
_, _ = messageBytes.WriteString("\n")
|
||||||
|
|
||||||
if opts.KeyID != "" {
|
if opts.KeyID != "" {
|
||||||
cmd.AddArguments(fmt.Sprintf("-S%s", opts.KeyID))
|
cmd.AddArguments(fmt.Sprintf("-S%s", opts.KeyID))
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.NoGPGSign {
|
if version.Compare(binVersion, "2.0.0", ">=") && opts.NoGPGSign {
|
||||||
cmd.AddArguments("--no-gpg-sign")
|
cmd.AddArguments("--no-gpg-sign")
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := cmd.RunInDirWithEnv(repo.Path, env)
|
stdout := new(bytes.Buffer)
|
||||||
|
stderr := new(bytes.Buffer)
|
||||||
|
err = cmd.RunInDirTimeoutEnvFullPipeline(env, -1, repo.Path, stdout, stderr, messageBytes)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return SHA1{}, err
|
return SHA1{}, concatenateError(err, stderr.String())
|
||||||
}
|
}
|
||||||
return NewIDFromString(strings.TrimSpace(res))
|
return NewIDFromString(strings.TrimSpace(stdout.String()))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ func TestEntriesCustomSort(t *testing.T) {
|
|||||||
func TestFollowLink(t *testing.T) {
|
func TestFollowLink(t *testing.T) {
|
||||||
r, err := OpenRepository("tests/repos/repo1_bare")
|
r, err := OpenRepository("tests/repos/repo1_bare")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
defer r.Close()
|
||||||
|
|
||||||
commit, err := r.GetCommit("37991dec2c8e592043f47155ce4808d4580f9123")
|
commit, err := r.GetCommit("37991dec2c8e592043f47155ce4808d4580f9123")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|||||||
@@ -155,7 +155,9 @@ func PostLockHandler(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var req api.LFSLockRequest
|
var req api.LFSLockRequest
|
||||||
dec := json.NewDecoder(ctx.Req.Body().ReadCloser())
|
bodyReader := ctx.Req.Body().ReadCloser()
|
||||||
|
defer bodyReader.Close()
|
||||||
|
dec := json.NewDecoder(bodyReader)
|
||||||
if err := dec.Decode(&req); err != nil {
|
if err := dec.Decode(&req); err != nil {
|
||||||
writeStatus(ctx, 400)
|
writeStatus(ctx, 400)
|
||||||
return
|
return
|
||||||
@@ -269,7 +271,9 @@ func UnLockHandler(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var req api.LFSLockDeleteRequest
|
var req api.LFSLockDeleteRequest
|
||||||
dec := json.NewDecoder(ctx.Req.Body().ReadCloser())
|
bodyReader := ctx.Req.Body().ReadCloser()
|
||||||
|
defer bodyReader.Close()
|
||||||
|
dec := json.NewDecoder(bodyReader)
|
||||||
if err := dec.Decode(&req); err != nil {
|
if err := dec.Decode(&req); err != nil {
|
||||||
writeStatus(ctx, 400)
|
writeStatus(ctx, 400)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -327,7 +327,9 @@ func PutHandler(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
contentStore := &ContentStore{BasePath: setting.LFS.ContentPath}
|
contentStore := &ContentStore{BasePath: setting.LFS.ContentPath}
|
||||||
if err := contentStore.Put(meta, ctx.Req.Body().ReadCloser()); err != nil {
|
bodyReader := ctx.Req.Body().ReadCloser()
|
||||||
|
defer bodyReader.Close()
|
||||||
|
if err := contentStore.Put(meta, bodyReader); err != nil {
|
||||||
ctx.Resp.WriteHeader(500)
|
ctx.Resp.WriteHeader(500)
|
||||||
fmt.Fprintf(ctx.Resp, `{"message":"%s"}`, err)
|
fmt.Fprintf(ctx.Resp, `{"message":"%s"}`, err)
|
||||||
if err = repository.RemoveLFSMetaObjectByOid(rv.Oid); err != nil {
|
if err = repository.RemoveLFSMetaObjectByOid(rv.Oid); err != nil {
|
||||||
@@ -434,7 +436,9 @@ func unpack(ctx *context.Context) *RequestVars {
|
|||||||
|
|
||||||
if r.Method == "POST" { // Maybe also check if +json
|
if r.Method == "POST" { // Maybe also check if +json
|
||||||
var p RequestVars
|
var p RequestVars
|
||||||
dec := json.NewDecoder(r.Body().ReadCloser())
|
bodyReader := r.Body().ReadCloser()
|
||||||
|
defer bodyReader.Close()
|
||||||
|
dec := json.NewDecoder(bodyReader)
|
||||||
err := dec.Decode(&p)
|
err := dec.Decode(&p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return rv
|
return rv
|
||||||
@@ -453,7 +457,9 @@ func unpackbatch(ctx *context.Context) *BatchVars {
|
|||||||
r := ctx.Req
|
r := ctx.Req
|
||||||
var bv BatchVars
|
var bv BatchVars
|
||||||
|
|
||||||
dec := json.NewDecoder(r.Body().ReadCloser())
|
bodyReader := r.Body().ReadCloser()
|
||||||
|
defer bodyReader.Close()
|
||||||
|
dec := json.NewDecoder(bodyReader)
|
||||||
err := dec.Decode(&bv)
|
err := dec.Decode(&bv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &bv
|
return &bv
|
||||||
|
|||||||
@@ -16,4 +16,5 @@ type Uploader interface {
|
|||||||
CreateComments(comments ...*Comment) error
|
CreateComments(comments ...*Comment) error
|
||||||
CreatePullRequests(prs ...*PullRequest) error
|
CreatePullRequests(prs ...*PullRequest) error
|
||||||
Rollback() error
|
Rollback() error
|
||||||
|
Close()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,6 +107,13 @@ func (g *GiteaLocalUploader) CreateRepo(repo *base.Repository, opts base.Migrate
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close closes this uploader
|
||||||
|
func (g *GiteaLocalUploader) Close() {
|
||||||
|
if g.gitRepo != nil {
|
||||||
|
g.gitRepo.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// CreateMilestones creates milestones
|
// CreateMilestones creates milestones
|
||||||
func (g *GiteaLocalUploader) CreateMilestones(milestones ...*base.Milestone) error {
|
func (g *GiteaLocalUploader) CreateMilestones(milestones ...*base.Milestone) error {
|
||||||
var mss = make([]*models.Milestone, 0, len(milestones))
|
var mss = make([]*models.Milestone, 0, len(milestones))
|
||||||
|
|||||||
@@ -113,12 +113,6 @@ func TestGitHubDownloadRepo(t *testing.T) {
|
|||||||
"2018-09-05 16:34:22 +0000 UTC",
|
"2018-09-05 16:34:22 +0000 UTC",
|
||||||
"2018-08-11 08:45:01 +0000 UTC",
|
"2018-08-11 08:45:01 +0000 UTC",
|
||||||
"closed", milestone)
|
"closed", milestone)
|
||||||
case "1.6.0":
|
|
||||||
assertMilestoneEqual(t, "1.6.0", "2018-09-25 07:00:00 +0000 UTC",
|
|
||||||
"2018-05-11 05:37:01 +0000 UTC",
|
|
||||||
"2019-01-27 19:21:22 +0000 UTC",
|
|
||||||
"2018-11-23 13:23:16 +0000 UTC",
|
|
||||||
"closed", milestone)
|
|
||||||
case "1.7.0":
|
case "1.7.0":
|
||||||
assertMilestoneEqual(t, "1.7.0", "2018-12-25 08:00:00 +0000 UTC",
|
assertMilestoneEqual(t, "1.7.0", "2018-12-25 08:00:00 +0000 UTC",
|
||||||
"2018-08-28 14:20:14 +0000 UTC",
|
"2018-08-28 14:20:14 +0000 UTC",
|
||||||
@@ -254,8 +248,8 @@ func TestGitHubDownloadRepo(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Reactions: &base.Reactions{
|
Reactions: &base.Reactions{
|
||||||
TotalCount: 9,
|
TotalCount: 10,
|
||||||
PlusOne: 8,
|
PlusOne: 9,
|
||||||
MinusOne: 0,
|
MinusOne: 0,
|
||||||
Laugh: 0,
|
Laugh: 0,
|
||||||
Confused: 0,
|
Confused: 0,
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ func migrateRepository(downloader base.Downloader, uploader base.Uploader, opts
|
|||||||
if err := uploader.CreateRepo(repo, opts); err != nil {
|
if err := uploader.CreateRepo(repo, opts); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
defer uploader.Close()
|
||||||
|
|
||||||
if opts.Milestones {
|
if opts.Milestones {
|
||||||
log.Trace("migrating milestones")
|
log.Trace("migrating milestones")
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
@@ -9,6 +10,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@@ -93,6 +95,14 @@ func (pm *Manager) ExecDir(timeout time.Duration, dir, desc, cmdName string, arg
|
|||||||
// Returns its complete stdout and stderr
|
// Returns its complete stdout and stderr
|
||||||
// outputs and an error, if any (including timeout)
|
// outputs and an error, if any (including timeout)
|
||||||
func (pm *Manager) ExecDirEnv(timeout time.Duration, dir, desc string, env []string, cmdName string, args ...string) (string, string, error) {
|
func (pm *Manager) ExecDirEnv(timeout time.Duration, dir, desc string, env []string, cmdName string, args ...string) (string, string, error) {
|
||||||
|
return pm.ExecDirEnvStdIn(timeout, dir, desc, env, nil, cmdName, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExecDirEnvStdIn runs a command in given path and environment variables with provided stdIN, and waits for its completion
|
||||||
|
// up to the given timeout (or DefaultTimeout if -1 is given).
|
||||||
|
// Returns its complete stdout and stderr
|
||||||
|
// outputs and an error, if any (including timeout)
|
||||||
|
func (pm *Manager) ExecDirEnvStdIn(timeout time.Duration, dir, desc string, env []string, stdIn io.Reader, cmdName string, args ...string) (string, string, error) {
|
||||||
if timeout == -1 {
|
if timeout == -1 {
|
||||||
timeout = 60 * time.Second
|
timeout = 60 * time.Second
|
||||||
}
|
}
|
||||||
@@ -108,6 +118,10 @@ func (pm *Manager) ExecDirEnv(timeout time.Duration, dir, desc string, env []str
|
|||||||
cmd.Env = env
|
cmd.Env = env
|
||||||
cmd.Stdout = stdOut
|
cmd.Stdout = stdOut
|
||||||
cmd.Stderr = stdErr
|
cmd.Stderr = stdErr
|
||||||
|
if stdIn != nil {
|
||||||
|
cmd.Stdin = stdIn
|
||||||
|
}
|
||||||
|
|
||||||
if err := cmd.Start(); err != nil {
|
if err := cmd.Start(); err != nil {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
@@ -22,6 +22,7 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
"github.com/mcuadros/go-version"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Merge merges pull request to base repository.
|
// Merge merges pull request to base repository.
|
||||||
@@ -66,20 +67,17 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor
|
|||||||
|
|
||||||
headRepoPath := models.RepoPath(pr.HeadUserName, pr.HeadRepo.Name)
|
headRepoPath := models.RepoPath(pr.HeadUserName, pr.HeadRepo.Name)
|
||||||
|
|
||||||
if err := git.Clone(baseGitRepo.Path, tmpBasePath, git.CloneRepoOptions{
|
if err := git.InitRepository(tmpBasePath, false); err != nil {
|
||||||
Shared: true,
|
return fmt.Errorf("git init: %v", err)
|
||||||
NoCheckout: true,
|
|
||||||
Branch: pr.BaseBranch,
|
|
||||||
}); err != nil {
|
|
||||||
return fmt.Errorf("git clone: %v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
remoteRepoName := "head_repo"
|
remoteRepoName := "head_repo"
|
||||||
|
baseBranch := "base"
|
||||||
|
|
||||||
// Add head repo remote.
|
// Add head repo remote.
|
||||||
addCacheRepo := func(staging, cache string) error {
|
addCacheRepo := func(staging, cache string) error {
|
||||||
p := filepath.Join(staging, ".git", "objects", "info", "alternates")
|
p := filepath.Join(staging, ".git", "objects", "info", "alternates")
|
||||||
f, err := os.OpenFile(p, os.O_APPEND|os.O_WRONLY, 0600)
|
f, err := os.OpenFile(p, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -91,25 +89,41 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := addCacheRepo(tmpBasePath, headRepoPath); err != nil {
|
if err := addCacheRepo(tmpBasePath, baseGitRepo.Path); err != nil {
|
||||||
return fmt.Errorf("addCacheRepo [%s -> %s]: %v", headRepoPath, tmpBasePath, err)
|
return fmt.Errorf("addCacheRepo [%s -> %s]: %v", headRepoPath, tmpBasePath, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var errbuf strings.Builder
|
var errbuf strings.Builder
|
||||||
|
if err := git.NewCommand("remote", "add", "-t", pr.BaseBranch, "-m", pr.BaseBranch, "origin", baseGitRepo.Path).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil {
|
||||||
|
return fmt.Errorf("git remote add [%s -> %s]: %s", baseGitRepo.Path, tmpBasePath, errbuf.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := git.NewCommand("fetch", "origin", "--no-tags", pr.BaseBranch+":"+baseBranch, pr.BaseBranch+":original_"+baseBranch).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil {
|
||||||
|
return fmt.Errorf("git fetch [%s -> %s]: %s", headRepoPath, tmpBasePath, errbuf.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := git.NewCommand("symbolic-ref", "HEAD", git.BranchPrefix+baseBranch).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil {
|
||||||
|
return fmt.Errorf("git symbolic-ref HEAD base [%s]: %s", tmpBasePath, errbuf.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := addCacheRepo(tmpBasePath, headRepoPath); err != nil {
|
||||||
|
return fmt.Errorf("addCacheRepo [%s -> %s]: %v", headRepoPath, tmpBasePath, err)
|
||||||
|
}
|
||||||
|
|
||||||
if err := git.NewCommand("remote", "add", remoteRepoName, headRepoPath).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil {
|
if err := git.NewCommand("remote", "add", remoteRepoName, headRepoPath).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil {
|
||||||
return fmt.Errorf("git remote add [%s -> %s]: %s", headRepoPath, tmpBasePath, errbuf.String())
|
return fmt.Errorf("git remote add [%s -> %s]: %s", headRepoPath, tmpBasePath, errbuf.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trackingBranch := "tracking"
|
||||||
// Fetch head branch
|
// Fetch head branch
|
||||||
if err := git.NewCommand("fetch", remoteRepoName, fmt.Sprintf("%s:refs/remotes/%s/%s", pr.HeadBranch, remoteRepoName, pr.HeadBranch)).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil {
|
if err := git.NewCommand("fetch", "--no-tags", remoteRepoName, pr.HeadBranch+":"+trackingBranch).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil {
|
||||||
return fmt.Errorf("git fetch [%s -> %s]: %s", headRepoPath, tmpBasePath, errbuf.String())
|
return fmt.Errorf("git fetch [%s -> %s]: %s", headRepoPath, tmpBasePath, errbuf.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
trackingBranch := path.Join(remoteRepoName, pr.HeadBranch)
|
stagingBranch := "staging"
|
||||||
stagingBranch := fmt.Sprintf("%s_%s", remoteRepoName, pr.HeadBranch)
|
|
||||||
|
|
||||||
// Enable sparse-checkout
|
// Enable sparse-checkout
|
||||||
sparseCheckoutList, err := getDiffTree(tmpBasePath, pr.BaseBranch, trackingBranch)
|
sparseCheckoutList, err := getDiffTree(tmpBasePath, baseBranch, trackingBranch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("getDiffTree: %v", err)
|
return fmt.Errorf("getDiffTree: %v", err)
|
||||||
}
|
}
|
||||||
@@ -123,21 +137,37 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor
|
|||||||
return fmt.Errorf("Writing sparse-checkout file to %s: %v", sparseCheckoutListPath, err)
|
return fmt.Errorf("Writing sparse-checkout file to %s: %v", sparseCheckoutListPath, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gitConfigCommand := func() func() *git.Command {
|
||||||
|
binVersion, err := git.BinVersion()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error retrieving git version: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if version.Compare(binVersion, "1.8.0", ">=") {
|
||||||
|
return func() *git.Command {
|
||||||
|
return git.NewCommand("config", "--local")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return func() *git.Command {
|
||||||
|
return git.NewCommand("config")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
// Switch off LFS process (set required, clean and smudge here also)
|
// Switch off LFS process (set required, clean and smudge here also)
|
||||||
if err := git.NewCommand("config", "--local", "filter.lfs.process", "").RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil {
|
if err := gitConfigCommand().AddArguments("filter.lfs.process", "").RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil {
|
||||||
return fmt.Errorf("git config [filter.lfs.process -> <> ]: %v", errbuf.String())
|
return fmt.Errorf("git config [filter.lfs.process -> <> ]: %v", errbuf.String())
|
||||||
}
|
}
|
||||||
if err := git.NewCommand("config", "--local", "filter.lfs.required", "false").RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil {
|
if err := gitConfigCommand().AddArguments("filter.lfs.required", "false").RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil {
|
||||||
return fmt.Errorf("git config [filter.lfs.required -> <false> ]: %v", errbuf.String())
|
return fmt.Errorf("git config [filter.lfs.required -> <false> ]: %v", errbuf.String())
|
||||||
}
|
}
|
||||||
if err := git.NewCommand("config", "--local", "filter.lfs.clean", "").RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil {
|
if err := gitConfigCommand().AddArguments("filter.lfs.clean", "").RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil {
|
||||||
return fmt.Errorf("git config [filter.lfs.clean -> <> ]: %v", errbuf.String())
|
return fmt.Errorf("git config [filter.lfs.clean -> <> ]: %v", errbuf.String())
|
||||||
}
|
}
|
||||||
if err := git.NewCommand("config", "--local", "filter.lfs.smudge", "").RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil {
|
if err := gitConfigCommand().AddArguments("filter.lfs.smudge", "").RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil {
|
||||||
return fmt.Errorf("git config [filter.lfs.smudge -> <> ]: %v", errbuf.String())
|
return fmt.Errorf("git config [filter.lfs.smudge -> <> ]: %v", errbuf.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := git.NewCommand("config", "--local", "core.sparseCheckout", "true").RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil {
|
if err := gitConfigCommand().AddArguments("core.sparseCheckout", "true").RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil {
|
||||||
return fmt.Errorf("git config [core.sparsecheckout -> true]: %v", errbuf.String())
|
return fmt.Errorf("git config [core.sparsecheckout -> true]: %v", errbuf.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,11 +193,11 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor
|
|||||||
return fmt.Errorf("git checkout: %s", errbuf.String())
|
return fmt.Errorf("git checkout: %s", errbuf.String())
|
||||||
}
|
}
|
||||||
// Rebase before merging
|
// Rebase before merging
|
||||||
if err := git.NewCommand("rebase", "-q", pr.BaseBranch).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil {
|
if err := git.NewCommand("rebase", "-q", baseBranch).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil {
|
||||||
return fmt.Errorf("git rebase [%s -> %s]: %s", headRepoPath, tmpBasePath, errbuf.String())
|
return fmt.Errorf("git rebase [%s -> %s]: %s", headRepoPath, tmpBasePath, errbuf.String())
|
||||||
}
|
}
|
||||||
// Checkout base branch again
|
// Checkout base branch again
|
||||||
if err := git.NewCommand("checkout", pr.BaseBranch).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil {
|
if err := git.NewCommand("checkout", baseBranch).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil {
|
||||||
return fmt.Errorf("git checkout: %s", errbuf.String())
|
return fmt.Errorf("git checkout: %s", errbuf.String())
|
||||||
}
|
}
|
||||||
// Merge fast forward
|
// Merge fast forward
|
||||||
@@ -180,11 +210,11 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor
|
|||||||
return fmt.Errorf("git checkout: %s", errbuf.String())
|
return fmt.Errorf("git checkout: %s", errbuf.String())
|
||||||
}
|
}
|
||||||
// Rebase before merging
|
// Rebase before merging
|
||||||
if err := git.NewCommand("rebase", "-q", pr.BaseBranch).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil {
|
if err := git.NewCommand("rebase", "-q", baseBranch).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil {
|
||||||
return fmt.Errorf("git rebase [%s -> %s]: %s", headRepoPath, tmpBasePath, errbuf.String())
|
return fmt.Errorf("git rebase [%s -> %s]: %s", headRepoPath, tmpBasePath, errbuf.String())
|
||||||
}
|
}
|
||||||
// Checkout base branch again
|
// Checkout base branch again
|
||||||
if err := git.NewCommand("checkout", pr.BaseBranch).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil {
|
if err := git.NewCommand("checkout", baseBranch).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil {
|
||||||
return fmt.Errorf("git checkout: %s", errbuf.String())
|
return fmt.Errorf("git checkout: %s", errbuf.String())
|
||||||
}
|
}
|
||||||
// Prepare merge with commit
|
// Prepare merge with commit
|
||||||
@@ -216,7 +246,7 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to get full commit id for HEAD: %v", err)
|
return fmt.Errorf("Failed to get full commit id for HEAD: %v", err)
|
||||||
}
|
}
|
||||||
mergeBaseSHA, err := git.GetFullCommitID(tmpBasePath, "origin/"+pr.BaseBranch)
|
mergeBaseSHA, err := git.GetFullCommitID(tmpBasePath, "original_"+baseBranch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to get full commit id for origin/%s: %v", pr.BaseBranch, err)
|
return fmt.Errorf("Failed to get full commit id for origin/%s: %v", pr.BaseBranch, err)
|
||||||
}
|
}
|
||||||
@@ -249,7 +279,7 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Push back to upstream.
|
// Push back to upstream.
|
||||||
if err := git.NewCommand("push", "origin", pr.BaseBranch).RunInDirTimeoutEnvPipeline(env, -1, tmpBasePath, nil, &errbuf); err != nil {
|
if err := git.NewCommand("push", "origin", baseBranch+":"+pr.BaseBranch).RunInDirTimeoutEnvPipeline(env, -1, tmpBasePath, nil, &errbuf); err != nil {
|
||||||
return fmt.Errorf("git push: %s", errbuf.String())
|
return fmt.Errorf("git push: %s", errbuf.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,16 +325,31 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var escapedSymbols = regexp.MustCompile(`([*[?! \\])`)
|
||||||
|
|
||||||
func getDiffTree(repoPath, baseBranch, headBranch string) (string, error) {
|
func getDiffTree(repoPath, baseBranch, headBranch string) (string, error) {
|
||||||
getDiffTreeFromBranch := func(repoPath, baseBranch, headBranch string) (string, error) {
|
getDiffTreeFromBranch := func(repoPath, baseBranch, headBranch string) (string, error) {
|
||||||
var outbuf, errbuf strings.Builder
|
var outbuf, errbuf strings.Builder
|
||||||
// Compute the diff-tree for sparse-checkout
|
// Compute the diff-tree for sparse-checkout
|
||||||
if err := git.NewCommand("diff-tree", "--no-commit-id", "--name-only", "-r", "--root", baseBranch, headBranch, "--").RunInDirPipeline(repoPath, &outbuf, &errbuf); err != nil {
|
if err := git.NewCommand("diff-tree", "--no-commit-id", "--name-only", "-r", "-z", "--root", baseBranch, headBranch, "--").RunInDirPipeline(repoPath, &outbuf, &errbuf); err != nil {
|
||||||
return "", fmt.Errorf("git diff-tree [%s base:%s head:%s]: %s", repoPath, baseBranch, headBranch, errbuf.String())
|
return "", fmt.Errorf("git diff-tree [%s base:%s head:%s]: %s", repoPath, baseBranch, headBranch, errbuf.String())
|
||||||
}
|
}
|
||||||
return outbuf.String(), nil
|
return outbuf.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scanNullTerminatedStrings := func(data []byte, atEOF bool) (advance int, token []byte, err error) {
|
||||||
|
if atEOF && len(data) == 0 {
|
||||||
|
return 0, nil, nil
|
||||||
|
}
|
||||||
|
if i := bytes.IndexByte(data, '\x00'); i >= 0 {
|
||||||
|
return i + 1, data[0:i], nil
|
||||||
|
}
|
||||||
|
if atEOF {
|
||||||
|
return len(data), data, nil
|
||||||
|
}
|
||||||
|
return 0, nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
list, err := getDiffTreeFromBranch(repoPath, baseBranch, headBranch)
|
list, err := getDiffTreeFromBranch(repoPath, baseBranch, headBranch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@@ -313,8 +358,14 @@ func getDiffTree(repoPath, baseBranch, headBranch string) (string, error) {
|
|||||||
// Prefixing '/' for each entry, otherwise all files with the same name in subdirectories would be matched.
|
// Prefixing '/' for each entry, otherwise all files with the same name in subdirectories would be matched.
|
||||||
out := bytes.Buffer{}
|
out := bytes.Buffer{}
|
||||||
scanner := bufio.NewScanner(strings.NewReader(list))
|
scanner := bufio.NewScanner(strings.NewReader(list))
|
||||||
|
scanner.Split(scanNullTerminatedStrings)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
fmt.Fprintf(&out, "/%s\n", scanner.Text())
|
filepath := scanner.Text()
|
||||||
|
// escape '*', '?', '[', spaces and '!' prefix
|
||||||
|
filepath = escapedSymbols.ReplaceAllString(filepath, `\$1`)
|
||||||
|
// no necessary to escape the first '#' symbol because the first symbol is '/'
|
||||||
|
fmt.Fprintf(&out, "/%s\n", filepath)
|
||||||
}
|
}
|
||||||
|
|
||||||
return out.String(), nil
|
return out.String(), nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ func GetBlobBySHA(repo *models.Repository, sha string) (*api.GitBlobResponse, er
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
defer gitRepo.Close()
|
||||||
gitBlob, err := gitRepo.GetBlob(sha)
|
gitBlob, err := gitRepo.GetBlob(sha)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ func TestGetBlobBySHA(t *testing.T) {
|
|||||||
test.LoadRepoCommit(t, ctx)
|
test.LoadRepoCommit(t, ctx)
|
||||||
test.LoadUser(t, ctx, 2)
|
test.LoadUser(t, ctx, 2)
|
||||||
test.LoadGitRepo(t, ctx)
|
test.LoadGitRepo(t, ctx)
|
||||||
|
defer ctx.Repo.GitRepo.Close()
|
||||||
|
|
||||||
sha := "65f1bf27bc3bf70f64657658635e66094edbcb4d"
|
sha := "65f1bf27bc3bf70f64657658635e66094edbcb4d"
|
||||||
ctx.SetParams(":id", "1")
|
ctx.SetParams(":id", "1")
|
||||||
ctx.SetParams(":sha", sha)
|
ctx.SetParams(":sha", sha)
|
||||||
|
|||||||
@@ -23,8 +23,10 @@ func CreateCommitStatus(repo *models.Repository, creator *models.User, sha strin
|
|||||||
return fmt.Errorf("OpenRepository[%s]: %v", repoPath, err)
|
return fmt.Errorf("OpenRepository[%s]: %v", repoPath, err)
|
||||||
}
|
}
|
||||||
if _, err := gitRepo.GetCommit(sha); err != nil {
|
if _, err := gitRepo.GetCommit(sha); err != nil {
|
||||||
|
gitRepo.Close()
|
||||||
return fmt.Errorf("GetCommit[%s]: %v", sha, err)
|
return fmt.Errorf("GetCommit[%s]: %v", sha, err)
|
||||||
}
|
}
|
||||||
|
gitRepo.Close()
|
||||||
|
|
||||||
if err := models.NewCommitStatus(models.NewCommitStatusOptions{
|
if err := models.NewCommitStatus(models.NewCommitStatusOptions{
|
||||||
Repo: repo,
|
Repo: repo,
|
||||||
|
|||||||
@@ -38,6 +38,9 @@ func (ct *ContentType) String() string {
|
|||||||
// GetContentsOrList gets the meta data of a file's contents (*ContentsResponse) if treePath not a tree
|
// GetContentsOrList gets the meta data of a file's contents (*ContentsResponse) if treePath not a tree
|
||||||
// directory, otherwise a listing of file contents ([]*ContentsResponse). Ref can be a branch, commit or tag
|
// directory, otherwise a listing of file contents ([]*ContentsResponse). Ref can be a branch, commit or tag
|
||||||
func GetContentsOrList(repo *models.Repository, treePath, ref string) (interface{}, error) {
|
func GetContentsOrList(repo *models.Repository, treePath, ref string) (interface{}, error) {
|
||||||
|
if repo.IsEmpty {
|
||||||
|
return make([]interface{}, 0), nil
|
||||||
|
}
|
||||||
if ref == "" {
|
if ref == "" {
|
||||||
ref = repo.DefaultBranch
|
ref = repo.DefaultBranch
|
||||||
}
|
}
|
||||||
@@ -56,6 +59,7 @@ func GetContentsOrList(repo *models.Repository, treePath, ref string) (interface
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
// Get the commit object for the ref
|
// Get the commit object for the ref
|
||||||
commit, err := gitRepo.GetCommit(ref)
|
commit, err := gitRepo.GetCommit(ref)
|
||||||
@@ -114,6 +118,7 @@ func GetContents(repo *models.Repository, treePath, ref string, forList bool) (*
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
// Get the commit object for the ref
|
// Get the commit object for the ref
|
||||||
commit, err := gitRepo.GetCommit(ref)
|
commit, err := gitRepo.GetCommit(ref)
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ func TestGetContents(t *testing.T) {
|
|||||||
test.LoadRepoCommit(t, ctx)
|
test.LoadRepoCommit(t, ctx)
|
||||||
test.LoadUser(t, ctx, 2)
|
test.LoadUser(t, ctx, 2)
|
||||||
test.LoadGitRepo(t, ctx)
|
test.LoadGitRepo(t, ctx)
|
||||||
|
defer ctx.Repo.GitRepo.Close()
|
||||||
|
|
||||||
treePath := "README.md"
|
treePath := "README.md"
|
||||||
ref := ctx.Repo.Repository.DefaultBranch
|
ref := ctx.Repo.Repository.DefaultBranch
|
||||||
|
|
||||||
@@ -82,6 +84,8 @@ func TestGetContentsOrListForDir(t *testing.T) {
|
|||||||
test.LoadRepoCommit(t, ctx)
|
test.LoadRepoCommit(t, ctx)
|
||||||
test.LoadUser(t, ctx, 2)
|
test.LoadUser(t, ctx, 2)
|
||||||
test.LoadGitRepo(t, ctx)
|
test.LoadGitRepo(t, ctx)
|
||||||
|
defer ctx.Repo.GitRepo.Close()
|
||||||
|
|
||||||
treePath := "" // root dir
|
treePath := "" // root dir
|
||||||
ref := ctx.Repo.Repository.DefaultBranch
|
ref := ctx.Repo.Repository.DefaultBranch
|
||||||
|
|
||||||
@@ -115,6 +119,8 @@ func TestGetContentsOrListForFile(t *testing.T) {
|
|||||||
test.LoadRepoCommit(t, ctx)
|
test.LoadRepoCommit(t, ctx)
|
||||||
test.LoadUser(t, ctx, 2)
|
test.LoadUser(t, ctx, 2)
|
||||||
test.LoadGitRepo(t, ctx)
|
test.LoadGitRepo(t, ctx)
|
||||||
|
defer ctx.Repo.GitRepo.Close()
|
||||||
|
|
||||||
treePath := "README.md"
|
treePath := "README.md"
|
||||||
ref := ctx.Repo.Repository.DefaultBranch
|
ref := ctx.Repo.Repository.DefaultBranch
|
||||||
|
|
||||||
@@ -141,6 +147,8 @@ func TestGetContentsErrors(t *testing.T) {
|
|||||||
test.LoadRepoCommit(t, ctx)
|
test.LoadRepoCommit(t, ctx)
|
||||||
test.LoadUser(t, ctx, 2)
|
test.LoadUser(t, ctx, 2)
|
||||||
test.LoadGitRepo(t, ctx)
|
test.LoadGitRepo(t, ctx)
|
||||||
|
defer ctx.Repo.GitRepo.Close()
|
||||||
|
|
||||||
repo := ctx.Repo.Repository
|
repo := ctx.Repo.Repository
|
||||||
treePath := "README.md"
|
treePath := "README.md"
|
||||||
ref := repo.DefaultBranch
|
ref := repo.DefaultBranch
|
||||||
@@ -170,6 +178,8 @@ func TestGetContentsOrListErrors(t *testing.T) {
|
|||||||
test.LoadRepoCommit(t, ctx)
|
test.LoadRepoCommit(t, ctx)
|
||||||
test.LoadUser(t, ctx, 2)
|
test.LoadUser(t, ctx, 2)
|
||||||
test.LoadGitRepo(t, ctx)
|
test.LoadGitRepo(t, ctx)
|
||||||
|
defer ctx.Repo.GitRepo.Close()
|
||||||
|
|
||||||
repo := ctx.Repo.Repository
|
repo := ctx.Repo.Repository
|
||||||
treePath := "README.md"
|
treePath := "README.md"
|
||||||
ref := repo.DefaultBranch
|
ref := repo.DefaultBranch
|
||||||
@@ -190,3 +200,21 @@ func TestGetContentsOrListErrors(t *testing.T) {
|
|||||||
assert.Nil(t, fileContentResponse)
|
assert.Nil(t, fileContentResponse)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetContentsOrListOfEmptyRepos(t *testing.T) {
|
||||||
|
models.PrepareTestEnv(t)
|
||||||
|
ctx := test.MockContext(t, "user2/repo15")
|
||||||
|
ctx.SetParams(":id", "15")
|
||||||
|
test.LoadRepo(t, ctx, 15)
|
||||||
|
test.LoadUser(t, ctx, 2)
|
||||||
|
test.LoadGitRepo(t, ctx)
|
||||||
|
defer ctx.Repo.GitRepo.Close()
|
||||||
|
|
||||||
|
repo := ctx.Repo.Repository
|
||||||
|
|
||||||
|
t.Run("empty repo", func(t *testing.T) {
|
||||||
|
contents, err := GetContentsOrList(repo, "", "")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Empty(t, contents)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ func TestGetDiffPreview(t *testing.T) {
|
|||||||
test.LoadRepoCommit(t, ctx)
|
test.LoadRepoCommit(t, ctx)
|
||||||
test.LoadUser(t, ctx, 2)
|
test.LoadUser(t, ctx, 2)
|
||||||
test.LoadGitRepo(t, ctx)
|
test.LoadGitRepo(t, ctx)
|
||||||
|
defer ctx.Repo.GitRepo.Close()
|
||||||
|
|
||||||
branch := ctx.Repo.Repository.DefaultBranch
|
branch := ctx.Repo.Repository.DefaultBranch
|
||||||
treePath := "README.md"
|
treePath := "README.md"
|
||||||
content := "# repo1\n\nDescription for repo1\nthis is a new line"
|
content := "# repo1\n\nDescription for repo1\nthis is a new line"
|
||||||
@@ -118,6 +120,8 @@ func TestGetDiffPreviewErrors(t *testing.T) {
|
|||||||
test.LoadRepoCommit(t, ctx)
|
test.LoadRepoCommit(t, ctx)
|
||||||
test.LoadUser(t, ctx, 2)
|
test.LoadUser(t, ctx, 2)
|
||||||
test.LoadGitRepo(t, ctx)
|
test.LoadGitRepo(t, ctx)
|
||||||
|
defer ctx.Repo.GitRepo.Close()
|
||||||
|
|
||||||
branch := ctx.Repo.Repository.DefaultBranch
|
branch := ctx.Repo.Repository.DefaultBranch
|
||||||
treePath := "README.md"
|
treePath := "README.md"
|
||||||
content := "# repo1\n\nDescription for repo1\nthis is a new line"
|
content := "# repo1\n\nDescription for repo1\nthis is a new line"
|
||||||
|
|||||||
@@ -88,10 +88,13 @@ func TestGetFileResponseFromCommit(t *testing.T) {
|
|||||||
test.LoadRepoCommit(t, ctx)
|
test.LoadRepoCommit(t, ctx)
|
||||||
test.LoadUser(t, ctx, 2)
|
test.LoadUser(t, ctx, 2)
|
||||||
test.LoadGitRepo(t, ctx)
|
test.LoadGitRepo(t, ctx)
|
||||||
|
defer ctx.Repo.GitRepo.Close()
|
||||||
|
|
||||||
repo := ctx.Repo.Repository
|
repo := ctx.Repo.Repository
|
||||||
branch := repo.DefaultBranch
|
branch := repo.DefaultBranch
|
||||||
treePath := "README.md"
|
treePath := "README.md"
|
||||||
gitRepo, _ := git.OpenRepository(repo.RepoPath())
|
gitRepo, _ := git.OpenRepository(repo.RepoPath())
|
||||||
|
defer gitRepo.Close()
|
||||||
commit, _ := gitRepo.GetBranchCommit(branch)
|
commit, _ := gitRepo.GetBranchCommit(branch)
|
||||||
expectedFileResponse := getExpectedFileResponse()
|
expectedFileResponse := getExpectedFileResponse()
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/process"
|
"code.gitea.io/gitea/modules/process"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
"github.com/mcuadros/go-version"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TemporaryUploadRepository is a type to wrap our upload repositories as a shallow clone
|
// TemporaryUploadRepository is a type to wrap our upload repositories as a shallow clone
|
||||||
@@ -41,6 +42,7 @@ func NewTemporaryUploadRepository(repo *models.Repository) (*TemporaryUploadRepo
|
|||||||
|
|
||||||
// Close the repository cleaning up all files
|
// Close the repository cleaning up all files
|
||||||
func (t *TemporaryUploadRepository) Close() {
|
func (t *TemporaryUploadRepository) Close() {
|
||||||
|
defer t.gitRepo.Close()
|
||||||
if err := models.RemoveTemporaryPath(t.basePath); err != nil {
|
if err := models.RemoveTemporaryPath(t.basePath); err != nil {
|
||||||
log.Error("Failed to remove temporary path %s: %v", t.basePath, err)
|
log.Error("Failed to remove temporary path %s: %v", t.basePath, err)
|
||||||
}
|
}
|
||||||
@@ -253,6 +255,11 @@ func (t *TemporaryUploadRepository) CommitTree(author, committer *models.User, t
|
|||||||
authorSig := author.NewGitSig()
|
authorSig := author.NewGitSig()
|
||||||
committerSig := committer.NewGitSig()
|
committerSig := committer.NewGitSig()
|
||||||
|
|
||||||
|
binVersion, err := git.BinVersion()
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("Unable to get git version: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: Should we add SSH_ORIGINAL_COMMAND to this
|
// FIXME: Should we add SSH_ORIGINAL_COMMAND to this
|
||||||
// Because this may call hooks we should pass in the environment
|
// Because this may call hooks we should pass in the environment
|
||||||
env := append(os.Environ(),
|
env := append(os.Environ(),
|
||||||
@@ -263,11 +270,21 @@ func (t *TemporaryUploadRepository) CommitTree(author, committer *models.User, t
|
|||||||
"GIT_COMMITTER_EMAIL="+committerSig.Email,
|
"GIT_COMMITTER_EMAIL="+committerSig.Email,
|
||||||
"GIT_COMMITTER_DATE="+commitTimeStr,
|
"GIT_COMMITTER_DATE="+commitTimeStr,
|
||||||
)
|
)
|
||||||
commitHash, stderr, err := process.GetManager().ExecDirEnv(5*time.Minute,
|
messageBytes := new(bytes.Buffer)
|
||||||
|
_, _ = messageBytes.WriteString(message)
|
||||||
|
_, _ = messageBytes.WriteString("\n")
|
||||||
|
|
||||||
|
args := []string{"commit-tree", treeHash, "-p", "HEAD"}
|
||||||
|
if version.Compare(binVersion, "2.0.0", ">=") {
|
||||||
|
args = append(args, "--no-gpg-sign")
|
||||||
|
}
|
||||||
|
|
||||||
|
commitHash, stderr, err := process.GetManager().ExecDirEnvStdIn(5*time.Minute,
|
||||||
t.basePath,
|
t.basePath,
|
||||||
fmt.Sprintf("commitTree (git commit-tree): %s", t.basePath),
|
fmt.Sprintf("commitTree (git commit-tree): %s", t.basePath),
|
||||||
env,
|
env,
|
||||||
git.GitExecutable, "commit-tree", treeHash, "-p", "HEAD", "-m", message)
|
messageBytes,
|
||||||
|
git.GitExecutable, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("git commit-tree: %s", stderr)
|
return "", fmt.Errorf("git commit-tree: %s", stderr)
|
||||||
}
|
}
|
||||||
@@ -327,6 +344,12 @@ func (t *TemporaryUploadRepository) DiffIndex() (diff *models.Diff, err error) {
|
|||||||
|
|
||||||
// CheckAttribute checks the given attribute of the provided files
|
// CheckAttribute checks the given attribute of the provided files
|
||||||
func (t *TemporaryUploadRepository) CheckAttribute(attribute string, args ...string) (map[string]map[string]string, error) {
|
func (t *TemporaryUploadRepository) CheckAttribute(attribute string, args ...string) (map[string]map[string]string, error) {
|
||||||
|
binVersion, err := git.BinVersion()
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Error retrieving git version: %v", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
stdOut := new(bytes.Buffer)
|
stdOut := new(bytes.Buffer)
|
||||||
stdErr := new(bytes.Buffer)
|
stdErr := new(bytes.Buffer)
|
||||||
|
|
||||||
@@ -334,7 +357,14 @@ func (t *TemporaryUploadRepository) CheckAttribute(attribute string, args ...str
|
|||||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
cmdArgs := []string{"check-attr", "-z", attribute, "--cached", "--"}
|
cmdArgs := []string{"check-attr", "-z", attribute}
|
||||||
|
|
||||||
|
// git check-attr --cached first appears in git 1.7.8
|
||||||
|
if version.Compare(binVersion, "1.7.8", ">=") {
|
||||||
|
cmdArgs = append(cmdArgs, "--cached")
|
||||||
|
}
|
||||||
|
cmdArgs = append(cmdArgs, "--")
|
||||||
|
|
||||||
for _, arg := range args {
|
for _, arg := range args {
|
||||||
if arg != "" {
|
if arg != "" {
|
||||||
cmdArgs = append(cmdArgs, arg)
|
cmdArgs = append(cmdArgs, arg)
|
||||||
@@ -352,7 +382,7 @@ func (t *TemporaryUploadRepository) CheckAttribute(attribute string, args ...str
|
|||||||
}
|
}
|
||||||
|
|
||||||
pid := process.GetManager().Add(desc, cmd)
|
pid := process.GetManager().Add(desc, cmd)
|
||||||
err := cmd.Wait()
|
err = cmd.Wait()
|
||||||
process.GetManager().Remove(pid)
|
process.GetManager().Remove(pid)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ func GetTreeBySHA(repo *models.Repository, sha string, page, perPage int, recurs
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
defer gitRepo.Close()
|
||||||
gitTree, err := gitRepo.GetTree(sha)
|
gitTree, err := gitRepo.GetTree(sha)
|
||||||
if err != nil || gitTree == nil {
|
if err != nil || gitTree == nil {
|
||||||
return nil, models.ErrSHANotFound{
|
return nil, models.ErrSHANotFound{
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ func TestGetTreeBySHA(t *testing.T) {
|
|||||||
test.LoadRepoCommit(t, ctx)
|
test.LoadRepoCommit(t, ctx)
|
||||||
test.LoadUser(t, ctx, 2)
|
test.LoadUser(t, ctx, 2)
|
||||||
test.LoadGitRepo(t, ctx)
|
test.LoadGitRepo(t, ctx)
|
||||||
|
defer ctx.Repo.GitRepo.Close()
|
||||||
|
|
||||||
sha := ctx.Repo.Repository.DefaultBranch
|
sha := ctx.Repo.Repository.DefaultBranch
|
||||||
page := 1
|
page := 1
|
||||||
perPage := 10
|
perPage := 10
|
||||||
|
|||||||
@@ -311,12 +311,6 @@ func CreateOrUpdateRepoFile(repo *models.Repository, doer *models.User, opts *Up
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check there is no way this can return multiple infos
|
|
||||||
filename2attribute2info, err := t.CheckAttribute("filter", treePath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
content := opts.Content
|
content := opts.Content
|
||||||
if bom {
|
if bom {
|
||||||
content = string(base.UTF8BOM) + content
|
content = string(base.UTF8BOM) + content
|
||||||
@@ -339,7 +333,14 @@ func CreateOrUpdateRepoFile(repo *models.Repository, doer *models.User, opts *Up
|
|||||||
opts.Content = content
|
opts.Content = content
|
||||||
var lfsMetaObject *models.LFSMetaObject
|
var lfsMetaObject *models.LFSMetaObject
|
||||||
|
|
||||||
if setting.LFS.StartServer && filename2attribute2info[treePath] != nil && filename2attribute2info[treePath]["filter"] == "lfs" {
|
if setting.LFS.StartServer {
|
||||||
|
// Check there is no way this can return multiple infos
|
||||||
|
filename2attribute2info, err := t.CheckAttribute("filter", treePath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if filename2attribute2info[treePath] != nil && filename2attribute2info[treePath]["filter"] == "lfs" {
|
||||||
// OK so we are supposed to LFS this data!
|
// OK so we are supposed to LFS this data!
|
||||||
oid, err := models.GenerateLFSOid(strings.NewReader(opts.Content))
|
oid, err := models.GenerateLFSOid(strings.NewReader(opts.Content))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -348,7 +349,7 @@ func CreateOrUpdateRepoFile(repo *models.Repository, doer *models.User, opts *Up
|
|||||||
lfsMetaObject = &models.LFSMetaObject{Oid: oid, Size: int64(len(opts.Content)), RepositoryID: repo.ID}
|
lfsMetaObject = &models.LFSMetaObject{Oid: oid, Size: int64(len(opts.Content)), RepositoryID: repo.ID}
|
||||||
content = lfsMetaObject.Pointer()
|
content = lfsMetaObject.Pointer()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Add the object to the database
|
// Add the object to the database
|
||||||
objectHash, err := t.HashObject(strings.NewReader(content))
|
objectHash, err := t.HashObject(strings.NewReader(content))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -74,10 +74,13 @@ func UploadRepoFiles(repo *models.Repository, doer *models.User, opts *UploadRep
|
|||||||
infos[i] = uploadInfo{upload: upload}
|
infos[i] = uploadInfo{upload: upload}
|
||||||
}
|
}
|
||||||
|
|
||||||
filename2attribute2info, err := t.CheckAttribute("filter", names...)
|
var filename2attribute2info map[string]map[string]string
|
||||||
|
if setting.LFS.StartServer {
|
||||||
|
filename2attribute2info, err = t.CheckAttribute("filter", names...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Copy uploaded files into repository.
|
// Copy uploaded files into repository.
|
||||||
for i, uploadInfo := range infos {
|
for i, uploadInfo := range infos {
|
||||||
@@ -88,7 +91,7 @@ func UploadRepoFiles(repo *models.Repository, doer *models.User, opts *UploadRep
|
|||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
var objectHash string
|
var objectHash string
|
||||||
if filename2attribute2info[uploadInfo.upload.Name] != nil && filename2attribute2info[uploadInfo.upload.Name]["filter"] == "lfs" {
|
if setting.LFS.StartServer && filename2attribute2info[uploadInfo.upload.Name] != nil && filename2attribute2info[uploadInfo.upload.Name]["filter"] == "lfs" {
|
||||||
// Handle LFS
|
// Handle LFS
|
||||||
// FIXME: Inefficient! this should probably happen in models.Upload
|
// FIXME: Inefficient! this should probably happen in models.Upload
|
||||||
oid, err := models.GenerateLFSOid(file)
|
oid, err := models.GenerateLFSOid(file)
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ func LoadRepo(t *testing.T, ctx *context.Context, repoID int64) {
|
|||||||
func LoadRepoCommit(t *testing.T, ctx *context.Context) {
|
func LoadRepoCommit(t *testing.T, ctx *context.Context) {
|
||||||
gitRepo, err := git.OpenRepository(ctx.Repo.Repository.RepoPath())
|
gitRepo, err := git.OpenRepository(ctx.Repo.Repository.RepoPath())
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
defer gitRepo.Close()
|
||||||
branch, err := gitRepo.GetHEADBranch()
|
branch, err := gitRepo.GetHEADBranch()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
ctx.Repo.Commit, err = gitRepo.GetBranchCommit(branch.Name)
|
ctx.Repo.Commit, err = gitRepo.GetBranchCommit(branch.Name)
|
||||||
|
|||||||
@@ -637,7 +637,7 @@ func RegisterRoutes(m *macaron.Macaron) {
|
|||||||
}, reqRepoReader(models.UnitTypeCode))
|
}, reqRepoReader(models.UnitTypeCode))
|
||||||
m.Group("/tags", func() {
|
m.Group("/tags", func() {
|
||||||
m.Get("", repo.ListTags)
|
m.Get("", repo.ListTags)
|
||||||
}, reqRepoReader(models.UnitTypeCode))
|
}, reqRepoReader(models.UnitTypeCode), context.ReferencesGitRepo(true))
|
||||||
m.Group("/keys", func() {
|
m.Group("/keys", func() {
|
||||||
m.Combo("").Get(repo.ListDeployKeys).
|
m.Combo("").Get(repo.ListDeployKeys).
|
||||||
Post(bind(api.CreateKeyOption{}), repo.CreateDeployKey)
|
Post(bind(api.CreateKeyOption{}), repo.CreateDeployKey)
|
||||||
|
|||||||
@@ -231,12 +231,9 @@ func ToTeam(team *models.Team) *api.Team {
|
|||||||
// ToUser convert models.User to api.User
|
// ToUser convert models.User to api.User
|
||||||
func ToUser(user *models.User, signed, authed bool) *api.User {
|
func ToUser(user *models.User, signed, authed bool) *api.User {
|
||||||
result := &api.User{
|
result := &api.User{
|
||||||
ID: user.ID,
|
|
||||||
UserName: user.Name,
|
UserName: user.Name,
|
||||||
AvatarURL: user.AvatarLink(),
|
AvatarURL: user.AvatarLink(),
|
||||||
FullName: markup.Sanitize(user.FullName),
|
FullName: markup.Sanitize(user.FullName),
|
||||||
IsAdmin: user.IsAdmin,
|
|
||||||
LastLogin: user.LastLoginUnix.AsTime(),
|
|
||||||
Created: user.CreatedUnix.AsTime(),
|
Created: user.CreatedUnix.AsTime(),
|
||||||
}
|
}
|
||||||
// hide primary email if API caller isn't user itself or an admin
|
// hide primary email if API caller isn't user itself or an admin
|
||||||
@@ -244,8 +241,11 @@ func ToUser(user *models.User, signed, authed bool) *api.User {
|
|||||||
result.Email = ""
|
result.Email = ""
|
||||||
} else if user.KeepEmailPrivate && !authed {
|
} else if user.KeepEmailPrivate && !authed {
|
||||||
result.Email = user.GetEmail()
|
result.Email = user.GetEmail()
|
||||||
} else {
|
} else { // only user himself and admin could visit these information
|
||||||
|
result.ID = user.ID
|
||||||
result.Email = user.Email
|
result.Email = user.Email
|
||||||
|
result.IsAdmin = user.IsAdmin
|
||||||
|
result.LastLogin = user.LastLoginUnix.AsTime()
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ func GetSingleCommit(ctx *context.APIContext) {
|
|||||||
ctx.ServerError("OpenRepository", err)
|
ctx.ServerError("OpenRepository", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
defer gitRepo.Close()
|
||||||
commit, err := gitRepo.GetCommit(ctx.Params(":sha"))
|
commit, err := gitRepo.GetCommit(ctx.Params(":sha"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.NotFoundOrServerError("GetCommit", git.IsErrNotExist, err)
|
ctx.NotFoundOrServerError("GetCommit", git.IsErrNotExist, err)
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ func GetArchive(ctx *context.APIContext) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.Repo.GitRepo = gitRepo
|
ctx.Repo.GitRepo = gitRepo
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
repo.Download(ctx.Context)
|
repo.Download(ctx.Context)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,6 +76,8 @@ func getGitRefs(ctx *context.APIContext, filter string) ([]*git.Reference, strin
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "OpenRepository", err
|
return nil, "OpenRepository", err
|
||||||
}
|
}
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
if len(filter) > 0 {
|
if len(filter) > 0 {
|
||||||
filter = "refs/" + filter
|
filter = "refs/" + filter
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -310,15 +310,14 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update the deadline
|
// Update the deadline
|
||||||
var deadlineUnix util.TimeStamp
|
|
||||||
if form.Deadline != nil && !form.Deadline.IsZero() && ctx.Repo.CanWrite(models.UnitTypeIssues) {
|
if form.Deadline != nil && !form.Deadline.IsZero() && ctx.Repo.CanWrite(models.UnitTypeIssues) {
|
||||||
deadlineUnix = util.TimeStamp(form.Deadline.Unix())
|
deadlineUnix := util.TimeStamp(form.Deadline.Unix())
|
||||||
}
|
|
||||||
|
|
||||||
if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.User); err != nil {
|
if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.User); err != nil {
|
||||||
ctx.Error(500, "UpdateIssueDeadline", err)
|
ctx.Error(500, "UpdateIssueDeadline", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
issue.DeadlineUnix = deadlineUnix
|
||||||
|
}
|
||||||
|
|
||||||
// Add/delete assignees
|
// Add/delete assignees
|
||||||
|
|
||||||
|
|||||||
@@ -193,6 +193,7 @@ func CreatePullRequest(ctx *context.APIContext, form api.CreatePullRequestOption
|
|||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
defer headGitRepo.Close()
|
||||||
|
|
||||||
// Check if another PR exists with the same targets
|
// Check if another PR exists with the same targets
|
||||||
existingPr, err := models.GetUnmergedPullRequest(headRepo.ID, ctx.Repo.Repository.ID, headBranch, baseBranch)
|
existingPr, err := models.GetUnmergedPullRequest(headRepo.ID, ctx.Repo.Repository.ID, headBranch, baseBranch)
|
||||||
@@ -375,15 +376,14 @@ func EditPullRequest(ctx *context.APIContext, form api.EditPullRequestOption) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update Deadline
|
// Update Deadline
|
||||||
var deadlineUnix util.TimeStamp
|
|
||||||
if form.Deadline != nil && !form.Deadline.IsZero() {
|
if form.Deadline != nil && !form.Deadline.IsZero() {
|
||||||
deadlineUnix = util.TimeStamp(form.Deadline.Unix())
|
deadlineUnix := util.TimeStamp(form.Deadline.Unix())
|
||||||
}
|
|
||||||
|
|
||||||
if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.User); err != nil {
|
if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.User); err != nil {
|
||||||
ctx.Error(500, "UpdateIssueDeadline", err)
|
ctx.Error(500, "UpdateIssueDeadline", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
issue.DeadlineUnix = deadlineUnix
|
||||||
|
}
|
||||||
|
|
||||||
// Add/delete assignees
|
// Add/delete assignees
|
||||||
|
|
||||||
@@ -684,6 +684,7 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption)
|
|||||||
// user should have permission to read baseRepo's codes and pulls, NOT headRepo's
|
// user should have permission to read baseRepo's codes and pulls, NOT headRepo's
|
||||||
permBase, err := models.GetUserRepoPermission(baseRepo, ctx.User)
|
permBase, err := models.GetUserRepoPermission(baseRepo, ctx.User)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
headGitRepo.Close()
|
||||||
ctx.ServerError("GetUserRepoPermission", err)
|
ctx.ServerError("GetUserRepoPermission", err)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil, nil, nil, nil, "", ""
|
||||||
}
|
}
|
||||||
@@ -694,6 +695,7 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption)
|
|||||||
baseRepo,
|
baseRepo,
|
||||||
permBase)
|
permBase)
|
||||||
}
|
}
|
||||||
|
headGitRepo.Close()
|
||||||
ctx.NotFound("Can't read pulls or can't read UnitTypeCode")
|
ctx.NotFound("Can't read pulls or can't read UnitTypeCode")
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil, nil, nil, nil, "", ""
|
||||||
}
|
}
|
||||||
@@ -701,6 +703,7 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption)
|
|||||||
// user should have permission to read headrepo's codes
|
// user should have permission to read headrepo's codes
|
||||||
permHead, err := models.GetUserRepoPermission(headRepo, ctx.User)
|
permHead, err := models.GetUserRepoPermission(headRepo, ctx.User)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
headGitRepo.Close()
|
||||||
ctx.ServerError("GetUserRepoPermission", err)
|
ctx.ServerError("GetUserRepoPermission", err)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil, nil, nil, nil, "", ""
|
||||||
}
|
}
|
||||||
@@ -711,18 +714,21 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption)
|
|||||||
headRepo,
|
headRepo,
|
||||||
permHead)
|
permHead)
|
||||||
}
|
}
|
||||||
|
headGitRepo.Close()
|
||||||
ctx.NotFound("Can't read headRepo UnitTypeCode")
|
ctx.NotFound("Can't read headRepo UnitTypeCode")
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil, nil, nil, nil, "", ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if head branch is valid.
|
// Check if head branch is valid.
|
||||||
if !headGitRepo.IsBranchExist(headBranch) {
|
if !headGitRepo.IsBranchExist(headBranch) {
|
||||||
|
headGitRepo.Close()
|
||||||
ctx.NotFound()
|
ctx.NotFound()
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil, nil, nil, nil, "", ""
|
||||||
}
|
}
|
||||||
|
|
||||||
compareInfo, err := headGitRepo.GetCompareInfo(models.RepoPath(baseRepo.Owner.Name, baseRepo.Name), baseBranch, headBranch)
|
compareInfo, err := headGitRepo.GetCompareInfo(models.RepoPath(baseRepo.Owner.Name, baseRepo.Name), baseBranch, headBranch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
headGitRepo.Close()
|
||||||
ctx.Error(500, "GetCompareInfo", err)
|
ctx.Error(500, "GetCompareInfo", err)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil, nil, nil, nil, "", ""
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ func ListTags(ctx *context.APIContext) {
|
|||||||
// responses:
|
// responses:
|
||||||
// "200":
|
// "200":
|
||||||
// "$ref": "#/responses/TagList"
|
// "$ref": "#/responses/TagList"
|
||||||
tags, err := ctx.Repo.Repository.GetTags()
|
tags, err := ctx.Repo.GitRepo.GetTagInfos()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Error(500, "GetTags", err)
|
ctx.Error(500, "GetTags", err)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ func GetInfo(ctx *context.APIContext) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.JSON(200, convert.ToUser(u, ctx.IsSigned, ctx.User.ID == u.ID || ctx.User.IsAdmin))
|
ctx.JSON(200, convert.ToUser(u, ctx.IsSigned, ctx.User != nil && (ctx.User.ID == u.ID || ctx.User.IsAdmin)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAuthenticatedUser get current user's information
|
// GetAuthenticatedUser get current user's information
|
||||||
|
|||||||
@@ -272,7 +272,7 @@ func ExploreOrganizations(ctx *context.Context) {
|
|||||||
// ExploreCode render explore code page
|
// ExploreCode render explore code page
|
||||||
func ExploreCode(ctx *context.Context) {
|
func ExploreCode(ctx *context.Context) {
|
||||||
if !setting.Indexer.RepoIndexerEnabled {
|
if !setting.Indexer.RepoIndexerEnabled {
|
||||||
ctx.Redirect("/explore", 302)
|
ctx.Redirect(setting.AppSubURL+"/explore", 302)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -116,6 +116,7 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
|
|||||||
// user should have permission to read baseRepo's codes and pulls, NOT headRepo's
|
// user should have permission to read baseRepo's codes and pulls, NOT headRepo's
|
||||||
permBase, err := models.GetUserRepoPermission(baseRepo, ctx.User)
|
permBase, err := models.GetUserRepoPermission(baseRepo, ctx.User)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
headGitRepo.Close()
|
||||||
ctx.ServerError("GetUserRepoPermission", err)
|
ctx.ServerError("GetUserRepoPermission", err)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil, nil, nil, nil, "", ""
|
||||||
}
|
}
|
||||||
@@ -126,6 +127,7 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
|
|||||||
baseRepo,
|
baseRepo,
|
||||||
permBase)
|
permBase)
|
||||||
}
|
}
|
||||||
|
headGitRepo.Close()
|
||||||
ctx.NotFound("ParseCompareInfo", nil)
|
ctx.NotFound("ParseCompareInfo", nil)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil, nil, nil, nil, "", ""
|
||||||
}
|
}
|
||||||
@@ -133,6 +135,7 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
|
|||||||
// user should have permission to read headrepo's codes
|
// user should have permission to read headrepo's codes
|
||||||
permHead, err := models.GetUserRepoPermission(headRepo, ctx.User)
|
permHead, err := models.GetUserRepoPermission(headRepo, ctx.User)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
headGitRepo.Close()
|
||||||
ctx.ServerError("GetUserRepoPermission", err)
|
ctx.ServerError("GetUserRepoPermission", err)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil, nil, nil, nil, "", ""
|
||||||
}
|
}
|
||||||
@@ -143,6 +146,7 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
|
|||||||
headRepo,
|
headRepo,
|
||||||
permHead)
|
permHead)
|
||||||
}
|
}
|
||||||
|
headGitRepo.Close()
|
||||||
ctx.NotFound("ParseCompareInfo", nil)
|
ctx.NotFound("ParseCompareInfo", nil)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil, nil, nil, nil, "", ""
|
||||||
}
|
}
|
||||||
@@ -158,6 +162,7 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
|
|||||||
ctx.Data["HeadBranch"] = headBranch
|
ctx.Data["HeadBranch"] = headBranch
|
||||||
headIsCommit = true
|
headIsCommit = true
|
||||||
} else {
|
} else {
|
||||||
|
headGitRepo.Close()
|
||||||
ctx.NotFound("IsRefExist", nil)
|
ctx.NotFound("IsRefExist", nil)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil, nil, nil, nil, "", ""
|
||||||
}
|
}
|
||||||
@@ -178,12 +183,14 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
|
|||||||
baseRepo,
|
baseRepo,
|
||||||
permBase)
|
permBase)
|
||||||
}
|
}
|
||||||
|
headGitRepo.Close()
|
||||||
ctx.NotFound("ParseCompareInfo", nil)
|
ctx.NotFound("ParseCompareInfo", nil)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil, nil, nil, nil, "", ""
|
||||||
}
|
}
|
||||||
|
|
||||||
compareInfo, err := headGitRepo.GetCompareInfo(models.RepoPath(baseRepo.Owner.Name, baseRepo.Name), baseBranch, headBranch)
|
compareInfo, err := headGitRepo.GetCompareInfo(models.RepoPath(baseRepo.Owner.Name, baseRepo.Name), baseBranch, headBranch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
headGitRepo.Close()
|
||||||
ctx.ServerError("GetCompareInfo", err)
|
ctx.ServerError("GetCompareInfo", err)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil, nil, nil, nil, "", ""
|
||||||
}
|
}
|
||||||
@@ -285,6 +292,7 @@ func CompareDiff(ctx *context.Context) {
|
|||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
defer headGitRepo.Close()
|
||||||
|
|
||||||
nothingToCompare := PrepareCompareDiff(ctx, headUser, headRepo, headGitRepo, compareInfo, baseBranch, headBranch)
|
nothingToCompare := PrepareCompareDiff(ctx, headUser, headRepo, headGitRepo, compareInfo, baseBranch, headBranch)
|
||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
|
|||||||
@@ -84,6 +84,11 @@ func ServeBlobOrLFS(ctx *context.Context, blob *git.Blob) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
defer func() {
|
||||||
|
if err = lfsDataRc.Close(); err != nil {
|
||||||
|
log.Error("ServeBlobOrLFS: Close: %v", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
return ServeData(ctx, ctx.Repo.TreePath, lfsDataRc)
|
return ServeData(ctx, ctx.Repo.TreePath, lfsDataRc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,8 @@ func TestGetUniquePatchBranchName(t *testing.T) {
|
|||||||
test.LoadRepoCommit(t, ctx)
|
test.LoadRepoCommit(t, ctx)
|
||||||
test.LoadUser(t, ctx, 2)
|
test.LoadUser(t, ctx, 2)
|
||||||
test.LoadGitRepo(t, ctx)
|
test.LoadGitRepo(t, ctx)
|
||||||
|
defer ctx.Repo.GitRepo.Close()
|
||||||
|
|
||||||
expectedBranchName := "user2-patch-1"
|
expectedBranchName := "user2-patch-1"
|
||||||
branchName := GetUniquePatchBranchName(ctx)
|
branchName := GetUniquePatchBranchName(ctx)
|
||||||
assert.Equal(t, expectedBranchName, branchName)
|
assert.Equal(t, expectedBranchName, branchName)
|
||||||
@@ -61,9 +63,12 @@ func TestGetClosestParentWithFiles(t *testing.T) {
|
|||||||
test.LoadRepoCommit(t, ctx)
|
test.LoadRepoCommit(t, ctx)
|
||||||
test.LoadUser(t, ctx, 2)
|
test.LoadUser(t, ctx, 2)
|
||||||
test.LoadGitRepo(t, ctx)
|
test.LoadGitRepo(t, ctx)
|
||||||
|
defer ctx.Repo.GitRepo.Close()
|
||||||
|
|
||||||
repo := ctx.Repo.Repository
|
repo := ctx.Repo.Repository
|
||||||
branch := repo.DefaultBranch
|
branch := repo.DefaultBranch
|
||||||
gitRepo, _ := git.OpenRepository(repo.RepoPath())
|
gitRepo, _ := git.OpenRepository(repo.RepoPath())
|
||||||
|
defer gitRepo.Close()
|
||||||
commit, _ := gitRepo.GetBranchCommit(branch)
|
commit, _ := gitRepo.GetBranchCommit(branch)
|
||||||
expectedTreePath := ""
|
expectedTreePath := ""
|
||||||
|
|
||||||
|
|||||||
@@ -330,6 +330,7 @@ func PrepareViewPullInfo(ctx *context.Context, issue *models.Issue) *git.Compare
|
|||||||
ctx.ServerError("OpenRepository", err)
|
ctx.ServerError("OpenRepository", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
defer headGitRepo.Close()
|
||||||
|
|
||||||
headBranchExist = headGitRepo.IsBranchExist(pull.HeadBranch)
|
headBranchExist = headGitRepo.IsBranchExist(pull.HeadBranch)
|
||||||
|
|
||||||
@@ -500,6 +501,7 @@ func ViewPullFiles(ctx *context.Context) {
|
|||||||
ctx.ServerError("OpenRepository", err)
|
ctx.ServerError("OpenRepository", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
defer headGitRepo.Close()
|
||||||
|
|
||||||
headCommitID, err := headGitRepo.GetBranchCommitID(pull.HeadBranch)
|
headCommitID, err := headGitRepo.GetBranchCommitID(pull.HeadBranch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -670,6 +672,7 @@ func CompareAndPullRequestPost(ctx *context.Context, form auth.CreateIssueForm)
|
|||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
defer headGitRepo.Close()
|
||||||
|
|
||||||
labelIDs, assigneeIDs, milestoneID := ValidateRepoMetas(ctx, form, true)
|
labelIDs, assigneeIDs, milestoneID := ValidateRepoMetas(ctx, form, true)
|
||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
@@ -844,12 +847,14 @@ func CleanUpPullRequest(ctx *context.Context) {
|
|||||||
ctx.ServerError(fmt.Sprintf("OpenRepository[%s]", pr.HeadRepo.RepoPath()), err)
|
ctx.ServerError(fmt.Sprintf("OpenRepository[%s]", pr.HeadRepo.RepoPath()), err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
gitBaseRepo, err := git.OpenRepository(pr.BaseRepo.RepoPath())
|
gitBaseRepo, err := git.OpenRepository(pr.BaseRepo.RepoPath())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError(fmt.Sprintf("OpenRepository[%s]", pr.BaseRepo.RepoPath()), err)
|
ctx.ServerError(fmt.Sprintf("OpenRepository[%s]", pr.BaseRepo.RepoPath()), err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
defer gitBaseRepo.Close()
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
ctx.JSON(200, map[string]interface{}{
|
ctx.JSON(200, map[string]interface{}{
|
||||||
@@ -978,6 +983,7 @@ func DownloadPullPatch(ctx *context.Context) {
|
|||||||
ctx.ServerError("OpenRepository", err)
|
ctx.ServerError("OpenRepository", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
defer headGitRepo.Close()
|
||||||
|
|
||||||
patch, err := headGitRepo.GetFormatPatch(pr.MergeBase, pr.HeadBranch)
|
patch, err := headGitRepo.GetFormatPatch(pr.MergeBase, pr.HeadBranch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -57,5 +57,6 @@ func TestNewReleasePost(t *testing.T) {
|
|||||||
Title: testCase.Form.Title,
|
Title: testCase.Form.Title,
|
||||||
Note: testCase.Form.Content,
|
Note: testCase.Form.Content,
|
||||||
}, models.Cond("is_draft=?", len(testCase.Form.Draft) > 0))
|
}, models.Cond("is_draft=?", len(testCase.Form.Draft) > 0))
|
||||||
|
ctx.Repo.GitRepo.Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,6 +69,11 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) {
|
|||||||
// Check if repository name has been changed.
|
// Check if repository name has been changed.
|
||||||
if repo.LowerName != strings.ToLower(newRepoName) {
|
if repo.LowerName != strings.ToLower(newRepoName) {
|
||||||
isNameChanged = true
|
isNameChanged = true
|
||||||
|
// Close the GitRepo if open
|
||||||
|
if ctx.Repo.GitRepo != nil {
|
||||||
|
ctx.Repo.GitRepo.Close()
|
||||||
|
ctx.Repo.GitRepo = nil
|
||||||
|
}
|
||||||
if err := models.ChangeRepositoryName(ctx.Repo.Owner, repo.Name, newRepoName); err != nil {
|
if err := models.ChangeRepositoryName(ctx.Repo.Owner, repo.Name, newRepoName); err != nil {
|
||||||
ctx.Data["Err_RepoName"] = true
|
ctx.Data["Err_RepoName"] = true
|
||||||
switch {
|
switch {
|
||||||
@@ -371,6 +376,11 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
oldOwnerID := ctx.Repo.Owner.ID
|
oldOwnerID := ctx.Repo.Owner.ID
|
||||||
|
// Close the GitRepo if open
|
||||||
|
if ctx.Repo.GitRepo != nil {
|
||||||
|
ctx.Repo.GitRepo.Close()
|
||||||
|
ctx.Repo.GitRepo = nil
|
||||||
|
}
|
||||||
if err = models.TransferOwnership(ctx.User, newOwner, repo); err != nil {
|
if err = models.TransferOwnership(ctx.User, newOwner, repo); err != nil {
|
||||||
if models.IsErrRepoAlreadyExist(err) {
|
if models.IsErrRepoAlreadyExist(err) {
|
||||||
ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplSettingsOptions, nil)
|
ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplSettingsOptions, nil)
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ func renderWikiPage(ctx *context.Context, isViewPage bool) (*git.Repository, *gi
|
|||||||
if models.IsErrWikiInvalidFileName(err) {
|
if models.IsErrWikiInvalidFileName(err) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
wikiRepo.Close()
|
||||||
ctx.ServerError("WikiFilenameToName", err)
|
ctx.ServerError("WikiFilenameToName", err)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
} else if wikiName == "_Sidebar" || wikiName == "_Footer" {
|
} else if wikiName == "_Sidebar" || wikiName == "_Footer" {
|
||||||
@@ -171,14 +172,19 @@ func renderWikiPage(ctx *context.Context, isViewPage bool) (*git.Repository, *gi
|
|||||||
pageFilename := models.WikiNameToFilename(pageName)
|
pageFilename := models.WikiNameToFilename(pageName)
|
||||||
var entry *git.TreeEntry
|
var entry *git.TreeEntry
|
||||||
if entry, err = findEntryForFile(commit, pageFilename); err != nil {
|
if entry, err = findEntryForFile(commit, pageFilename); err != nil {
|
||||||
|
wikiRepo.Close()
|
||||||
ctx.ServerError("findEntryForFile", err)
|
ctx.ServerError("findEntryForFile", err)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
} else if entry == nil {
|
} else if entry == nil {
|
||||||
|
wikiRepo.Close()
|
||||||
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/_pages")
|
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/_pages")
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
data := wikiContentsByEntry(ctx, entry)
|
data := wikiContentsByEntry(ctx, entry)
|
||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
|
if wikiRepo != nil {
|
||||||
|
wikiRepo.Close()
|
||||||
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,8 +229,16 @@ func Wiki(ctx *context.Context) {
|
|||||||
|
|
||||||
wikiRepo, entry := renderWikiPage(ctx, true)
|
wikiRepo, entry := renderWikiPage(ctx, true)
|
||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
|
if wikiRepo != nil {
|
||||||
|
wikiRepo.Close()
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
defer func() {
|
||||||
|
if wikiRepo != nil {
|
||||||
|
wikiRepo.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
if entry == nil {
|
if entry == nil {
|
||||||
ctx.Data["Title"] = ctx.Tr("repo.wiki")
|
ctx.Data["Title"] = ctx.Tr("repo.wiki")
|
||||||
ctx.HTML(200, tplWikiStart)
|
ctx.HTML(200, tplWikiStart)
|
||||||
@@ -260,11 +274,18 @@ func WikiPages(ctx *context.Context) {
|
|||||||
|
|
||||||
wikiRepo, commit, err := findWikiRepoCommit(ctx)
|
wikiRepo, commit, err := findWikiRepoCommit(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if wikiRepo != nil {
|
||||||
|
wikiRepo.Close()
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
entries, err := commit.ListEntries()
|
entries, err := commit.ListEntries()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if wikiRepo != nil {
|
||||||
|
wikiRepo.Close()
|
||||||
|
}
|
||||||
|
|
||||||
ctx.ServerError("ListEntries", err)
|
ctx.ServerError("ListEntries", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -275,6 +296,10 @@ func WikiPages(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
c, err := wikiRepo.GetCommitByPath(entry.Name())
|
c, err := wikiRepo.GetCommitByPath(entry.Name())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if wikiRepo != nil {
|
||||||
|
wikiRepo.Close()
|
||||||
|
}
|
||||||
|
|
||||||
ctx.ServerError("GetCommit", err)
|
ctx.ServerError("GetCommit", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -283,6 +308,10 @@ func WikiPages(ctx *context.Context) {
|
|||||||
if models.IsErrWikiInvalidFileName(err) {
|
if models.IsErrWikiInvalidFileName(err) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if wikiRepo != nil {
|
||||||
|
wikiRepo.Close()
|
||||||
|
}
|
||||||
|
|
||||||
ctx.ServerError("WikiFilenameToName", err)
|
ctx.ServerError("WikiFilenameToName", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -294,6 +323,11 @@ func WikiPages(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
ctx.Data["Pages"] = pages
|
ctx.Data["Pages"] = pages
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if wikiRepo != nil {
|
||||||
|
wikiRepo.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
ctx.HTML(200, tplWikiPages)
|
ctx.HTML(200, tplWikiPages)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,6 +339,9 @@ func WikiRaw(ctx *context.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
defer func() {
|
||||||
|
wikiRepo.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
providedPath := ctx.Params("*")
|
providedPath := ctx.Params("*")
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user