Move repofiles from modules/repofiles to services/repository/files (#17774)
* Move repofiles from modules to services * rename services/repository/repofiles -> services/repository/files * Fix test Co-authored-by: 6543 <6543@obermui.de>
This commit is contained in:
		
					parent
					
						
							
								754fdd8f9c
							
						
					
				
			
			
				commit
				
					
						c97d66d23c
					
				
			
		
					 37 changed files with 277 additions and 353 deletions
				
			
		| 
						 | 
				
			
			@ -6,12 +6,12 @@ package integrations
 | 
			
		|||
 | 
			
		||||
import (
 | 
			
		||||
	"code.gitea.io/gitea/models"
 | 
			
		||||
	"code.gitea.io/gitea/modules/repofiles"
 | 
			
		||||
	api "code.gitea.io/gitea/modules/structs"
 | 
			
		||||
	files_service "code.gitea.io/gitea/services/repository/files"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func createFileInBranch(user *models.User, repo *models.Repository, treePath, branchName, content string) (*api.FileResponse, error) {
 | 
			
		||||
	opts := &repofiles.UpdateRepoFileOptions{
 | 
			
		||||
	opts := &files_service.UpdateRepoFileOptions{
 | 
			
		||||
		OldBranch: branchName,
 | 
			
		||||
		TreePath:  treePath,
 | 
			
		||||
		Content:   content,
 | 
			
		||||
| 
						 | 
				
			
			@ -19,7 +19,7 @@ func createFileInBranch(user *models.User, repo *models.Repository, treePath, br
 | 
			
		|||
		Author:    nil,
 | 
			
		||||
		Committer: nil,
 | 
			
		||||
	}
 | 
			
		||||
	return repofiles.CreateOrUpdateRepoFile(repo, user, opts)
 | 
			
		||||
	return files_service.CreateOrUpdateRepoFile(repo, user, opts)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func createFile(user *models.User, repo *models.Repository, treePath string) (*api.FileResponse, error) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,9 +12,9 @@ import (
 | 
			
		|||
 | 
			
		||||
	"code.gitea.io/gitea/models"
 | 
			
		||||
	"code.gitea.io/gitea/models/unittest"
 | 
			
		||||
	"code.gitea.io/gitea/modules/repofiles"
 | 
			
		||||
	pull_service "code.gitea.io/gitea/services/pull"
 | 
			
		||||
	repo_service "code.gitea.io/gitea/services/repository"
 | 
			
		||||
	files_service "code.gitea.io/gitea/services/repository/files"
 | 
			
		||||
 | 
			
		||||
	"github.com/stretchr/testify/assert"
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -97,22 +97,22 @@ func createOutdatedPR(t *testing.T, actor, forkOrg *models.User) *models.PullReq
 | 
			
		|||
	assert.NotEmpty(t, headRepo)
 | 
			
		||||
 | 
			
		||||
	//create a commit on base Repo
 | 
			
		||||
	_, err = repofiles.CreateOrUpdateRepoFile(baseRepo, actor, &repofiles.UpdateRepoFileOptions{
 | 
			
		||||
	_, err = files_service.CreateOrUpdateRepoFile(baseRepo, actor, &files_service.UpdateRepoFileOptions{
 | 
			
		||||
		TreePath:  "File_A",
 | 
			
		||||
		Message:   "Add File A",
 | 
			
		||||
		Content:   "File A",
 | 
			
		||||
		IsNewFile: true,
 | 
			
		||||
		OldBranch: "master",
 | 
			
		||||
		NewBranch: "master",
 | 
			
		||||
		Author: &repofiles.IdentityOptions{
 | 
			
		||||
		Author: &files_service.IdentityOptions{
 | 
			
		||||
			Name:  actor.Name,
 | 
			
		||||
			Email: actor.Email,
 | 
			
		||||
		},
 | 
			
		||||
		Committer: &repofiles.IdentityOptions{
 | 
			
		||||
		Committer: &files_service.IdentityOptions{
 | 
			
		||||
			Name:  actor.Name,
 | 
			
		||||
			Email: actor.Email,
 | 
			
		||||
		},
 | 
			
		||||
		Dates: &repofiles.CommitDateOptions{
 | 
			
		||||
		Dates: &files_service.CommitDateOptions{
 | 
			
		||||
			Author:    time.Now(),
 | 
			
		||||
			Committer: time.Now(),
 | 
			
		||||
		},
 | 
			
		||||
| 
						 | 
				
			
			@ -120,22 +120,22 @@ func createOutdatedPR(t *testing.T, actor, forkOrg *models.User) *models.PullReq
 | 
			
		|||
	assert.NoError(t, err)
 | 
			
		||||
 | 
			
		||||
	//create a commit on head Repo
 | 
			
		||||
	_, err = repofiles.CreateOrUpdateRepoFile(headRepo, actor, &repofiles.UpdateRepoFileOptions{
 | 
			
		||||
	_, err = files_service.CreateOrUpdateRepoFile(headRepo, actor, &files_service.UpdateRepoFileOptions{
 | 
			
		||||
		TreePath:  "File_B",
 | 
			
		||||
		Message:   "Add File on PR branch",
 | 
			
		||||
		Content:   "File B",
 | 
			
		||||
		IsNewFile: true,
 | 
			
		||||
		OldBranch: "master",
 | 
			
		||||
		NewBranch: "newBranch",
 | 
			
		||||
		Author: &repofiles.IdentityOptions{
 | 
			
		||||
		Author: &files_service.IdentityOptions{
 | 
			
		||||
			Name:  actor.Name,
 | 
			
		||||
			Email: actor.Email,
 | 
			
		||||
		},
 | 
			
		||||
		Committer: &repofiles.IdentityOptions{
 | 
			
		||||
		Committer: &files_service.IdentityOptions{
 | 
			
		||||
			Name:  actor.Name,
 | 
			
		||||
			Email: actor.Email,
 | 
			
		||||
		},
 | 
			
		||||
		Dates: &repofiles.CommitDateOptions{
 | 
			
		||||
		Dates: &files_service.CommitDateOptions{
 | 
			
		||||
			Author:    time.Now(),
 | 
			
		||||
			Committer: time.Now(),
 | 
			
		||||
		},
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,22 +10,22 @@ import (
 | 
			
		|||
 | 
			
		||||
	"code.gitea.io/gitea/models"
 | 
			
		||||
	"code.gitea.io/gitea/models/unittest"
 | 
			
		||||
	"code.gitea.io/gitea/modules/repofiles"
 | 
			
		||||
	api "code.gitea.io/gitea/modules/structs"
 | 
			
		||||
	"code.gitea.io/gitea/modules/test"
 | 
			
		||||
	files_service "code.gitea.io/gitea/services/repository/files"
 | 
			
		||||
 | 
			
		||||
	"github.com/stretchr/testify/assert"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func getDeleteRepoFileOptions(repo *models.Repository) *repofiles.DeleteRepoFileOptions {
 | 
			
		||||
	return &repofiles.DeleteRepoFileOptions{
 | 
			
		||||
func getDeleteRepoFileOptions(repo *models.Repository) *files_service.DeleteRepoFileOptions {
 | 
			
		||||
	return &files_service.DeleteRepoFileOptions{
 | 
			
		||||
		LastCommitID: "",
 | 
			
		||||
		OldBranch:    repo.DefaultBranch,
 | 
			
		||||
		NewBranch:    repo.DefaultBranch,
 | 
			
		||||
		TreePath:     "README.md",
 | 
			
		||||
		Message:      "Deletes README.md",
 | 
			
		||||
		SHA:          "4b4851ad51df6a7d9f25c979345979eaeb5b349f",
 | 
			
		||||
		Author: &repofiles.IdentityOptions{
 | 
			
		||||
		Author: &files_service.IdentityOptions{
 | 
			
		||||
			Name:  "Bob Smith",
 | 
			
		||||
			Email: "bob@smith.com",
 | 
			
		||||
		},
 | 
			
		||||
| 
						 | 
				
			
			@ -80,7 +80,7 @@ func testDeleteRepoFile(t *testing.T, u *url.URL) {
 | 
			
		|||
	opts := getDeleteRepoFileOptions(repo)
 | 
			
		||||
 | 
			
		||||
	t.Run("Delete README.md file", func(t *testing.T) {
 | 
			
		||||
		fileResponse, err := repofiles.DeleteRepoFile(repo, doer, opts)
 | 
			
		||||
		fileResponse, err := files_service.DeleteRepoFile(repo, doer, opts)
 | 
			
		||||
		assert.NoError(t, err)
 | 
			
		||||
		expectedFileResponse := getExpectedDeleteFileResponse(u)
 | 
			
		||||
		assert.NotNil(t, fileResponse)
 | 
			
		||||
| 
						 | 
				
			
			@ -92,7 +92,7 @@ func testDeleteRepoFile(t *testing.T, u *url.URL) {
 | 
			
		|||
	})
 | 
			
		||||
 | 
			
		||||
	t.Run("Verify README.md has been deleted", func(t *testing.T) {
 | 
			
		||||
		fileResponse, err := repofiles.DeleteRepoFile(repo, doer, opts)
 | 
			
		||||
		fileResponse, err := files_service.DeleteRepoFile(repo, doer, opts)
 | 
			
		||||
		assert.Nil(t, fileResponse)
 | 
			
		||||
		expectedError := "repository file does not exist [path: " + opts.TreePath + "]"
 | 
			
		||||
		assert.EqualError(t, err, expectedError)
 | 
			
		||||
| 
						 | 
				
			
			@ -122,7 +122,7 @@ func testDeleteRepoFileWithoutBranchNames(t *testing.T, u *url.URL) {
 | 
			
		|||
	opts.NewBranch = ""
 | 
			
		||||
 | 
			
		||||
	t.Run("Delete README.md without Branch Name", func(t *testing.T) {
 | 
			
		||||
		fileResponse, err := repofiles.DeleteRepoFile(repo, doer, opts)
 | 
			
		||||
		fileResponse, err := files_service.DeleteRepoFile(repo, doer, opts)
 | 
			
		||||
		assert.NoError(t, err)
 | 
			
		||||
		expectedFileResponse := getExpectedDeleteFileResponse(u)
 | 
			
		||||
		assert.NotNil(t, fileResponse)
 | 
			
		||||
| 
						 | 
				
			
			@ -151,7 +151,7 @@ func TestDeleteRepoFileErrors(t *testing.T) {
 | 
			
		|||
	t.Run("Bad branch", func(t *testing.T) {
 | 
			
		||||
		opts := getDeleteRepoFileOptions(repo)
 | 
			
		||||
		opts.OldBranch = "bad_branch"
 | 
			
		||||
		fileResponse, err := repofiles.DeleteRepoFile(repo, doer, opts)
 | 
			
		||||
		fileResponse, err := files_service.DeleteRepoFile(repo, doer, opts)
 | 
			
		||||
		assert.Error(t, err)
 | 
			
		||||
		assert.Nil(t, fileResponse)
 | 
			
		||||
		expectedError := "branch does not exist [name: " + opts.OldBranch + "]"
 | 
			
		||||
| 
						 | 
				
			
			@ -162,7 +162,7 @@ func TestDeleteRepoFileErrors(t *testing.T) {
 | 
			
		|||
		opts := getDeleteRepoFileOptions(repo)
 | 
			
		||||
		origSHA := opts.SHA
 | 
			
		||||
		opts.SHA = "bad_sha"
 | 
			
		||||
		fileResponse, err := repofiles.DeleteRepoFile(repo, doer, opts)
 | 
			
		||||
		fileResponse, err := files_service.DeleteRepoFile(repo, doer, opts)
 | 
			
		||||
		assert.Nil(t, fileResponse)
 | 
			
		||||
		assert.Error(t, err)
 | 
			
		||||
		expectedError := "sha does not match [given: " + opts.SHA + ", expected: " + origSHA + "]"
 | 
			
		||||
| 
						 | 
				
			
			@ -172,7 +172,7 @@ func TestDeleteRepoFileErrors(t *testing.T) {
 | 
			
		|||
	t.Run("New branch already exists", func(t *testing.T) {
 | 
			
		||||
		opts := getDeleteRepoFileOptions(repo)
 | 
			
		||||
		opts.NewBranch = "develop"
 | 
			
		||||
		fileResponse, err := repofiles.DeleteRepoFile(repo, doer, opts)
 | 
			
		||||
		fileResponse, err := files_service.DeleteRepoFile(repo, doer, opts)
 | 
			
		||||
		assert.Nil(t, fileResponse)
 | 
			
		||||
		assert.Error(t, err)
 | 
			
		||||
		expectedError := "branch already exists [name: " + opts.NewBranch + "]"
 | 
			
		||||
| 
						 | 
				
			
			@ -182,7 +182,7 @@ func TestDeleteRepoFileErrors(t *testing.T) {
 | 
			
		|||
	t.Run("TreePath is empty:", func(t *testing.T) {
 | 
			
		||||
		opts := getDeleteRepoFileOptions(repo)
 | 
			
		||||
		opts.TreePath = ""
 | 
			
		||||
		fileResponse, err := repofiles.DeleteRepoFile(repo, doer, opts)
 | 
			
		||||
		fileResponse, err := files_service.DeleteRepoFile(repo, doer, opts)
 | 
			
		||||
		assert.Nil(t, fileResponse)
 | 
			
		||||
		assert.Error(t, err)
 | 
			
		||||
		expectedError := "path contains a malformed path component [path: ]"
 | 
			
		||||
| 
						 | 
				
			
			@ -192,7 +192,7 @@ func TestDeleteRepoFileErrors(t *testing.T) {
 | 
			
		|||
	t.Run("TreePath is a git directory:", func(t *testing.T) {
 | 
			
		||||
		opts := getDeleteRepoFileOptions(repo)
 | 
			
		||||
		opts.TreePath = ".git"
 | 
			
		||||
		fileResponse, err := repofiles.DeleteRepoFile(repo, doer, opts)
 | 
			
		||||
		fileResponse, err := files_service.DeleteRepoFile(repo, doer, opts)
 | 
			
		||||
		assert.Nil(t, fileResponse)
 | 
			
		||||
		assert.Error(t, err)
 | 
			
		||||
		expectedError := "path contains a malformed path component [path: " + opts.TreePath + "]"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,16 +12,16 @@ import (
 | 
			
		|||
 | 
			
		||||
	"code.gitea.io/gitea/models"
 | 
			
		||||
	"code.gitea.io/gitea/modules/git"
 | 
			
		||||
	"code.gitea.io/gitea/modules/repofiles"
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	api "code.gitea.io/gitea/modules/structs"
 | 
			
		||||
	"code.gitea.io/gitea/modules/test"
 | 
			
		||||
	files_service "code.gitea.io/gitea/services/repository/files"
 | 
			
		||||
 | 
			
		||||
	"github.com/stretchr/testify/assert"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func getCreateRepoFileOptions(repo *models.Repository) *repofiles.UpdateRepoFileOptions {
 | 
			
		||||
	return &repofiles.UpdateRepoFileOptions{
 | 
			
		||||
func getCreateRepoFileOptions(repo *models.Repository) *files_service.UpdateRepoFileOptions {
 | 
			
		||||
	return &files_service.UpdateRepoFileOptions{
 | 
			
		||||
		OldBranch: repo.DefaultBranch,
 | 
			
		||||
		NewBranch: repo.DefaultBranch,
 | 
			
		||||
		TreePath:  "new/file.txt",
 | 
			
		||||
| 
						 | 
				
			
			@ -33,8 +33,8 @@ func getCreateRepoFileOptions(repo *models.Repository) *repofiles.UpdateRepoFile
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getUpdateRepoFileOptions(repo *models.Repository) *repofiles.UpdateRepoFileOptions {
 | 
			
		||||
	return &repofiles.UpdateRepoFileOptions{
 | 
			
		||||
func getUpdateRepoFileOptions(repo *models.Repository) *files_service.UpdateRepoFileOptions {
 | 
			
		||||
	return &files_service.UpdateRepoFileOptions{
 | 
			
		||||
		OldBranch: repo.DefaultBranch,
 | 
			
		||||
		NewBranch: repo.DefaultBranch,
 | 
			
		||||
		TreePath:  "README.md",
 | 
			
		||||
| 
						 | 
				
			
			@ -198,7 +198,7 @@ func TestCreateOrUpdateRepoFileForCreate(t *testing.T) {
 | 
			
		|||
		opts := getCreateRepoFileOptions(repo)
 | 
			
		||||
 | 
			
		||||
		// test
 | 
			
		||||
		fileResponse, err := repofiles.CreateOrUpdateRepoFile(repo, doer, opts)
 | 
			
		||||
		fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts)
 | 
			
		||||
 | 
			
		||||
		// asserts
 | 
			
		||||
		assert.NoError(t, err)
 | 
			
		||||
| 
						 | 
				
			
			@ -234,7 +234,7 @@ func TestCreateOrUpdateRepoFileForUpdate(t *testing.T) {
 | 
			
		|||
		opts := getUpdateRepoFileOptions(repo)
 | 
			
		||||
 | 
			
		||||
		// test
 | 
			
		||||
		fileResponse, err := repofiles.CreateOrUpdateRepoFile(repo, doer, opts)
 | 
			
		||||
		fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts)
 | 
			
		||||
 | 
			
		||||
		// asserts
 | 
			
		||||
		assert.NoError(t, err)
 | 
			
		||||
| 
						 | 
				
			
			@ -269,7 +269,7 @@ func TestCreateOrUpdateRepoFileForUpdateWithFileMove(t *testing.T) {
 | 
			
		|||
		opts.TreePath = "README_new.md" // new file name, README_new.md
 | 
			
		||||
 | 
			
		||||
		// test
 | 
			
		||||
		fileResponse, err := repofiles.CreateOrUpdateRepoFile(repo, doer, opts)
 | 
			
		||||
		fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts)
 | 
			
		||||
 | 
			
		||||
		// asserts
 | 
			
		||||
		assert.NoError(t, err)
 | 
			
		||||
| 
						 | 
				
			
			@ -319,7 +319,7 @@ func TestCreateOrUpdateRepoFileWithoutBranchNames(t *testing.T) {
 | 
			
		|||
		opts.NewBranch = ""
 | 
			
		||||
 | 
			
		||||
		// test
 | 
			
		||||
		fileResponse, err := repofiles.CreateOrUpdateRepoFile(repo, doer, opts)
 | 
			
		||||
		fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts)
 | 
			
		||||
 | 
			
		||||
		// asserts
 | 
			
		||||
		assert.NoError(t, err)
 | 
			
		||||
| 
						 | 
				
			
			@ -349,7 +349,7 @@ func TestCreateOrUpdateRepoFileErrors(t *testing.T) {
 | 
			
		|||
		t.Run("bad branch", func(t *testing.T) {
 | 
			
		||||
			opts := getUpdateRepoFileOptions(repo)
 | 
			
		||||
			opts.OldBranch = "bad_branch"
 | 
			
		||||
			fileResponse, err := repofiles.CreateOrUpdateRepoFile(repo, doer, opts)
 | 
			
		||||
			fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts)
 | 
			
		||||
			assert.Error(t, err)
 | 
			
		||||
			assert.Nil(t, fileResponse)
 | 
			
		||||
			expectedError := "branch does not exist [name: " + opts.OldBranch + "]"
 | 
			
		||||
| 
						 | 
				
			
			@ -360,7 +360,7 @@ func TestCreateOrUpdateRepoFileErrors(t *testing.T) {
 | 
			
		|||
			opts := getUpdateRepoFileOptions(repo)
 | 
			
		||||
			origSHA := opts.SHA
 | 
			
		||||
			opts.SHA = "bad_sha"
 | 
			
		||||
			fileResponse, err := repofiles.CreateOrUpdateRepoFile(repo, doer, opts)
 | 
			
		||||
			fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts)
 | 
			
		||||
			assert.Nil(t, fileResponse)
 | 
			
		||||
			assert.Error(t, err)
 | 
			
		||||
			expectedError := "sha does not match [given: " + opts.SHA + ", expected: " + origSHA + "]"
 | 
			
		||||
| 
						 | 
				
			
			@ -370,7 +370,7 @@ func TestCreateOrUpdateRepoFileErrors(t *testing.T) {
 | 
			
		|||
		t.Run("new branch already exists", func(t *testing.T) {
 | 
			
		||||
			opts := getUpdateRepoFileOptions(repo)
 | 
			
		||||
			opts.NewBranch = "develop"
 | 
			
		||||
			fileResponse, err := repofiles.CreateOrUpdateRepoFile(repo, doer, opts)
 | 
			
		||||
			fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts)
 | 
			
		||||
			assert.Nil(t, fileResponse)
 | 
			
		||||
			assert.Error(t, err)
 | 
			
		||||
			expectedError := "branch already exists [name: " + opts.NewBranch + "]"
 | 
			
		||||
| 
						 | 
				
			
			@ -380,7 +380,7 @@ func TestCreateOrUpdateRepoFileErrors(t *testing.T) {
 | 
			
		|||
		t.Run("treePath is empty:", func(t *testing.T) {
 | 
			
		||||
			opts := getUpdateRepoFileOptions(repo)
 | 
			
		||||
			opts.TreePath = ""
 | 
			
		||||
			fileResponse, err := repofiles.CreateOrUpdateRepoFile(repo, doer, opts)
 | 
			
		||||
			fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts)
 | 
			
		||||
			assert.Nil(t, fileResponse)
 | 
			
		||||
			assert.Error(t, err)
 | 
			
		||||
			expectedError := "path contains a malformed path component [path: ]"
 | 
			
		||||
| 
						 | 
				
			
			@ -390,7 +390,7 @@ func TestCreateOrUpdateRepoFileErrors(t *testing.T) {
 | 
			
		|||
		t.Run("treePath is a git directory:", func(t *testing.T) {
 | 
			
		||||
			opts := getUpdateRepoFileOptions(repo)
 | 
			
		||||
			opts.TreePath = ".git"
 | 
			
		||||
			fileResponse, err := repofiles.CreateOrUpdateRepoFile(repo, doer, opts)
 | 
			
		||||
			fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts)
 | 
			
		||||
			assert.Nil(t, fileResponse)
 | 
			
		||||
			assert.Error(t, err)
 | 
			
		||||
			expectedError := "path contains a malformed path component [path: " + opts.TreePath + "]"
 | 
			
		||||
| 
						 | 
				
			
			@ -400,7 +400,7 @@ func TestCreateOrUpdateRepoFileErrors(t *testing.T) {
 | 
			
		|||
		t.Run("create file that already exists", func(t *testing.T) {
 | 
			
		||||
			opts := getCreateRepoFileOptions(repo)
 | 
			
		||||
			opts.TreePath = "README.md" //already exists
 | 
			
		||||
			fileResponse, err := repofiles.CreateOrUpdateRepoFile(repo, doer, opts)
 | 
			
		||||
			fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts)
 | 
			
		||||
			assert.Nil(t, fileResponse)
 | 
			
		||||
			assert.Error(t, err)
 | 
			
		||||
			expectedError := "repository file already exists [path: " + opts.TreePath + "]"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,7 +10,6 @@ import (
 | 
			
		|||
	"code.gitea.io/gitea/models"
 | 
			
		||||
	"code.gitea.io/gitea/modules/git"
 | 
			
		||||
	"code.gitea.io/gitea/modules/log"
 | 
			
		||||
	repo_module "code.gitea.io/gitea/modules/repository"
 | 
			
		||||
	api "code.gitea.io/gitea/modules/structs"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -83,7 +82,14 @@ func ToAPIPullRequest(pr *models.PullRequest, doer *models.User) *api.PullReques
 | 
			
		|||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	baseBranch, err = repo_module.GetBranch(pr.BaseRepo, pr.BaseBranch)
 | 
			
		||||
	gitRepo, err := git.OpenRepository(pr.BaseRepo.RepoPath())
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Error("OpenRepository[%s]: %v", pr.BaseRepo.RepoPath(), err)
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	defer gitRepo.Close()
 | 
			
		||||
 | 
			
		||||
	baseBranch, err = gitRepo.GetBranch(pr.BaseBranch)
 | 
			
		||||
	if err != nil && !git.IsErrBranchNotExist(err) {
 | 
			
		||||
		log.Error("GetBranch[%s]: %v", pr.BaseBranch, err)
 | 
			
		||||
		return nil
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,41 +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 repofiles
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"net/url"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/models"
 | 
			
		||||
	"code.gitea.io/gitea/modules/git"
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	api "code.gitea.io/gitea/modules/structs"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// GetBlobBySHA get the GitBlobResponse of a repository using a sha hash.
 | 
			
		||||
func GetBlobBySHA(repo *models.Repository, sha string) (*api.GitBlobResponse, error) {
 | 
			
		||||
	gitRepo, err := git.OpenRepository(repo.RepoPath())
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	defer gitRepo.Close()
 | 
			
		||||
	gitBlob, err := gitRepo.GetBlob(sha)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	content := ""
 | 
			
		||||
	if gitBlob.Size() <= setting.API.DefaultMaxBlobSize {
 | 
			
		||||
		content, err = gitBlob.GetBlobContentBase64()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return &api.GitBlobResponse{
 | 
			
		||||
		SHA:      gitBlob.ID.String(),
 | 
			
		||||
		URL:      repo.APIURL() + "/git/blobs/" + url.PathEscape(gitBlob.ID.String()),
 | 
			
		||||
		Size:     gitBlob.Size(),
 | 
			
		||||
		Encoding: "base64",
 | 
			
		||||
		Content:  content,
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,40 +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 repofiles
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/models/unittest"
 | 
			
		||||
	api "code.gitea.io/gitea/modules/structs"
 | 
			
		||||
	"code.gitea.io/gitea/modules/test"
 | 
			
		||||
 | 
			
		||||
	"github.com/stretchr/testify/assert"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestGetBlobBySHA(t *testing.T) {
 | 
			
		||||
	unittest.PrepareTestEnv(t)
 | 
			
		||||
	ctx := test.MockContext(t, "user2/repo1")
 | 
			
		||||
	test.LoadRepo(t, ctx, 1)
 | 
			
		||||
	test.LoadRepoCommit(t, ctx)
 | 
			
		||||
	test.LoadUser(t, ctx, 2)
 | 
			
		||||
	test.LoadGitRepo(t, ctx)
 | 
			
		||||
	defer ctx.Repo.GitRepo.Close()
 | 
			
		||||
 | 
			
		||||
	sha := "65f1bf27bc3bf70f64657658635e66094edbcb4d"
 | 
			
		||||
	ctx.SetParams(":id", "1")
 | 
			
		||||
	ctx.SetParams(":sha", sha)
 | 
			
		||||
 | 
			
		||||
	gbr, err := GetBlobBySHA(ctx.Repo.Repository, ctx.Params(":sha"))
 | 
			
		||||
	expectedGBR := &api.GitBlobResponse{
 | 
			
		||||
		Content:  "dHJlZSAyYTJmMWQ0NjcwNzI4YTJlMTAwNDllMzQ1YmQ3YTI3NjQ2OGJlYWI2CmF1dGhvciB1c2VyMSA8YWRkcmVzczFAZXhhbXBsZS5jb20+IDE0ODk5NTY0NzkgLTA0MDAKY29tbWl0dGVyIEV0aGFuIEtvZW5pZyA8ZXRoYW50a29lbmlnQGdtYWlsLmNvbT4gMTQ4OTk1NjQ3OSAtMDQwMAoKSW5pdGlhbCBjb21taXQK",
 | 
			
		||||
		Encoding: "base64",
 | 
			
		||||
		URL:      "https://try.gitea.io/api/v1/repos/user2/repo1/git/blobs/65f1bf27bc3bf70f64657658635e66094edbcb4d",
 | 
			
		||||
		SHA:      "65f1bf27bc3bf70f64657658635e66094edbcb4d",
 | 
			
		||||
		Size:     180,
 | 
			
		||||
	}
 | 
			
		||||
	assert.NoError(t, err)
 | 
			
		||||
	assert.Equal(t, expectedGBR, gbr)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,19 +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 repofiles
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"code.gitea.io/gitea/models"
 | 
			
		||||
	"code.gitea.io/gitea/modules/git"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// CountDivergingCommits determines how many commits a branch is ahead or behind the repository's base branch
 | 
			
		||||
func CountDivergingCommits(repo *models.Repository, branch string) (*git.DivergeObject, error) {
 | 
			
		||||
	divergence, err := git.GetDivergingCommits(repo.RepoPath(), repo.DefaultBranch, branch)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return &divergence, nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,41 +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 repofiles
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/models"
 | 
			
		||||
	"code.gitea.io/gitea/modules/git"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// CreateCommitStatus creates a new CommitStatus given a bunch of parameters
 | 
			
		||||
// NOTE: All text-values will be trimmed from whitespaces.
 | 
			
		||||
// Requires: Repo, Creator, SHA
 | 
			
		||||
func CreateCommitStatus(repo *models.Repository, creator *models.User, sha string, status *models.CommitStatus) error {
 | 
			
		||||
	repoPath := repo.RepoPath()
 | 
			
		||||
 | 
			
		||||
	// confirm that commit is exist
 | 
			
		||||
	gitRepo, err := git.OpenRepository(repoPath)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("OpenRepository[%s]: %v", repoPath, err)
 | 
			
		||||
	}
 | 
			
		||||
	if _, err := gitRepo.GetCommit(sha); err != nil {
 | 
			
		||||
		gitRepo.Close()
 | 
			
		||||
		return fmt.Errorf("GetCommit[%s]: %v", sha, err)
 | 
			
		||||
	}
 | 
			
		||||
	gitRepo.Close()
 | 
			
		||||
 | 
			
		||||
	if err := models.NewCommitStatus(models.NewCommitStatusOptions{
 | 
			
		||||
		Repo:         repo,
 | 
			
		||||
		Creator:      creator,
 | 
			
		||||
		SHA:          sha,
 | 
			
		||||
		CommitStatus: status,
 | 
			
		||||
	}); err != nil {
 | 
			
		||||
		return fmt.Errorf("NewCommitStatus[repo_id: %d, user_id: %d, sha: %s]: %v", repo.ID, creator.ID, sha, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,23 +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 repofiles
 | 
			
		||||
 | 
			
		||||
package repofiles
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"path"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// CleanUploadFileName Trims a filename and returns empty string if it is a .git directory
 | 
			
		||||
func CleanUploadFileName(name string) string {
 | 
			
		||||
	// Rebase the filename
 | 
			
		||||
	name = strings.Trim(path.Clean("/"+name), " /")
 | 
			
		||||
	// Git disallows any filenames to have a .git directory in them.
 | 
			
		||||
	for _, part := range strings.Split(name, "/") {
 | 
			
		||||
		if strings.ToLower(part) == ".git" {
 | 
			
		||||
			return ""
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return name
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,27 +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 repofiles
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"github.com/stretchr/testify/assert"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestCleanUploadFileName(t *testing.T) {
 | 
			
		||||
	t.Run("Clean regular file", func(t *testing.T) {
 | 
			
		||||
		name := "this/is/test"
 | 
			
		||||
		cleanName := CleanUploadFileName(name)
 | 
			
		||||
		expectedCleanName := name
 | 
			
		||||
		assert.EqualValues(t, expectedCleanName, cleanName)
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	t.Run("Clean a .git path", func(t *testing.T) {
 | 
			
		||||
		name := "this/is/test/.git"
 | 
			
		||||
		cleanName := CleanUploadFileName(name)
 | 
			
		||||
		expectedCleanName := ""
 | 
			
		||||
		assert.EqualValues(t, expectedCleanName, cleanName)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,33 +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 repofiles
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"code.gitea.io/gitea/models"
 | 
			
		||||
	"code.gitea.io/gitea/modules/git"
 | 
			
		||||
	"code.gitea.io/gitea/modules/structs"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// GetPayloadCommitVerification returns the verification information of a commit
 | 
			
		||||
func GetPayloadCommitVerification(commit *git.Commit) *structs.PayloadCommitVerification {
 | 
			
		||||
	verification := &structs.PayloadCommitVerification{}
 | 
			
		||||
	commitVerification := models.ParseCommitWithSignature(commit)
 | 
			
		||||
	if commit.Signature != nil {
 | 
			
		||||
		verification.Signature = commit.Signature.Signature
 | 
			
		||||
		verification.Payload = commit.Signature.Payload
 | 
			
		||||
	}
 | 
			
		||||
	if commitVerification.SigningUser != nil {
 | 
			
		||||
		verification.Signer = &structs.PayloadUser{
 | 
			
		||||
			Name:  commitVerification.SigningUser.Name,
 | 
			
		||||
			Email: commitVerification.SigningUser.Email,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	verification.Verified = commitVerification.Verified
 | 
			
		||||
	verification.Reason = commitVerification.Reason
 | 
			
		||||
	if verification.Reason == "" && !verification.Verified {
 | 
			
		||||
		verification.Reason = "gpg.error.not_signed_commit"
 | 
			
		||||
	}
 | 
			
		||||
	return verification
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,26 +0,0 @@
 | 
			
		|||
// Copyright 2020 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 repository
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/models"
 | 
			
		||||
	"code.gitea.io/gitea/modules/git"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// GetBranch returns a branch by its name
 | 
			
		||||
func GetBranch(repo *models.Repository, branch string) (*git.Branch, error) {
 | 
			
		||||
	if len(branch) == 0 {
 | 
			
		||||
		return nil, fmt.Errorf("GetBranch: empty string for branch")
 | 
			
		||||
	}
 | 
			
		||||
	gitRepo, err := git.OpenRepository(repo.RepoPath())
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	defer gitRepo.Close()
 | 
			
		||||
 | 
			
		||||
	return gitRepo.GetBranch(branch)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -8,7 +8,7 @@ import (
 | 
			
		|||
	"net/http"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/modules/context"
 | 
			
		||||
	"code.gitea.io/gitea/modules/repofiles"
 | 
			
		||||
	files_service "code.gitea.io/gitea/services/repository/files"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// GetBlob get the blob of a repository file.
 | 
			
		||||
| 
						 | 
				
			
			@ -45,7 +45,7 @@ func GetBlob(ctx *context.APIContext) {
 | 
			
		|||
		ctx.Error(http.StatusBadRequest, "", "sha not provided")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if blob, err := repofiles.GetBlobBySHA(ctx.Repo.Repository, sha); err != nil {
 | 
			
		||||
	if blob, err := files_service.GetBlobBySHA(ctx.Repo.Repository, sha); err != nil {
 | 
			
		||||
		ctx.Error(http.StatusBadRequest, "", err)
 | 
			
		||||
	} else {
 | 
			
		||||
		ctx.JSON(http.StatusOK, blob)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,7 +14,6 @@ import (
 | 
			
		|||
	"code.gitea.io/gitea/modules/context"
 | 
			
		||||
	"code.gitea.io/gitea/modules/convert"
 | 
			
		||||
	"code.gitea.io/gitea/modules/git"
 | 
			
		||||
	repo_module "code.gitea.io/gitea/modules/repository"
 | 
			
		||||
	api "code.gitea.io/gitea/modules/structs"
 | 
			
		||||
	"code.gitea.io/gitea/modules/web"
 | 
			
		||||
	"code.gitea.io/gitea/routers/api/v1/utils"
 | 
			
		||||
| 
						 | 
				
			
			@ -53,7 +52,7 @@ func GetBranch(ctx *context.APIContext) {
 | 
			
		|||
 | 
			
		||||
	branchName := ctx.Params("*")
 | 
			
		||||
 | 
			
		||||
	branch, err := repo_module.GetBranch(ctx.Repo.Repository, branchName)
 | 
			
		||||
	branch, err := repo_service.GetBranch(ctx.Repo.Repository, branchName)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		if git.IsErrBranchNotExist(err) {
 | 
			
		||||
			ctx.NotFound(err)
 | 
			
		||||
| 
						 | 
				
			
			@ -198,7 +197,7 @@ func CreateBranch(ctx *context.APIContext) {
 | 
			
		|||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	branch, err := repo_module.GetBranch(ctx.Repo.Repository, opt.BranchName)
 | 
			
		||||
	branch, err := repo_service.GetBranch(ctx.Repo.Repository, opt.BranchName)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		ctx.Error(http.StatusInternalServerError, "GetBranch", err)
 | 
			
		||||
		return
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,11 +15,11 @@ import (
 | 
			
		|||
	"code.gitea.io/gitea/models/unit"
 | 
			
		||||
	"code.gitea.io/gitea/modules/context"
 | 
			
		||||
	"code.gitea.io/gitea/modules/git"
 | 
			
		||||
	"code.gitea.io/gitea/modules/repofiles"
 | 
			
		||||
	api "code.gitea.io/gitea/modules/structs"
 | 
			
		||||
	"code.gitea.io/gitea/modules/web"
 | 
			
		||||
	"code.gitea.io/gitea/routers/common"
 | 
			
		||||
	"code.gitea.io/gitea/routers/web/repo"
 | 
			
		||||
	files_service "code.gitea.io/gitea/services/repository/files"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// GetRawFile get a file by path on a repository
 | 
			
		||||
| 
						 | 
				
			
			@ -240,22 +240,22 @@ func CreateFile(ctx *context.APIContext) {
 | 
			
		|||
		apiOpts.BranchName = ctx.Repo.Repository.DefaultBranch
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	opts := &repofiles.UpdateRepoFileOptions{
 | 
			
		||||
	opts := &files_service.UpdateRepoFileOptions{
 | 
			
		||||
		Content:   apiOpts.Content,
 | 
			
		||||
		IsNewFile: true,
 | 
			
		||||
		Message:   apiOpts.Message,
 | 
			
		||||
		TreePath:  ctx.Params("*"),
 | 
			
		||||
		OldBranch: apiOpts.BranchName,
 | 
			
		||||
		NewBranch: apiOpts.NewBranchName,
 | 
			
		||||
		Committer: &repofiles.IdentityOptions{
 | 
			
		||||
		Committer: &files_service.IdentityOptions{
 | 
			
		||||
			Name:  apiOpts.Committer.Name,
 | 
			
		||||
			Email: apiOpts.Committer.Email,
 | 
			
		||||
		},
 | 
			
		||||
		Author: &repofiles.IdentityOptions{
 | 
			
		||||
		Author: &files_service.IdentityOptions{
 | 
			
		||||
			Name:  apiOpts.Author.Name,
 | 
			
		||||
			Email: apiOpts.Author.Email,
 | 
			
		||||
		},
 | 
			
		||||
		Dates: &repofiles.CommitDateOptions{
 | 
			
		||||
		Dates: &files_service.CommitDateOptions{
 | 
			
		||||
			Author:    apiOpts.Dates.Author,
 | 
			
		||||
			Committer: apiOpts.Dates.Committer,
 | 
			
		||||
		},
 | 
			
		||||
| 
						 | 
				
			
			@ -327,7 +327,7 @@ func UpdateFile(ctx *context.APIContext) {
 | 
			
		|||
		apiOpts.BranchName = ctx.Repo.Repository.DefaultBranch
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	opts := &repofiles.UpdateRepoFileOptions{
 | 
			
		||||
	opts := &files_service.UpdateRepoFileOptions{
 | 
			
		||||
		Content:      apiOpts.Content,
 | 
			
		||||
		SHA:          apiOpts.SHA,
 | 
			
		||||
		IsNewFile:    false,
 | 
			
		||||
| 
						 | 
				
			
			@ -336,15 +336,15 @@ func UpdateFile(ctx *context.APIContext) {
 | 
			
		|||
		TreePath:     ctx.Params("*"),
 | 
			
		||||
		OldBranch:    apiOpts.BranchName,
 | 
			
		||||
		NewBranch:    apiOpts.NewBranchName,
 | 
			
		||||
		Committer: &repofiles.IdentityOptions{
 | 
			
		||||
		Committer: &files_service.IdentityOptions{
 | 
			
		||||
			Name:  apiOpts.Committer.Name,
 | 
			
		||||
			Email: apiOpts.Committer.Email,
 | 
			
		||||
		},
 | 
			
		||||
		Author: &repofiles.IdentityOptions{
 | 
			
		||||
		Author: &files_service.IdentityOptions{
 | 
			
		||||
			Name:  apiOpts.Author.Name,
 | 
			
		||||
			Email: apiOpts.Author.Email,
 | 
			
		||||
		},
 | 
			
		||||
		Dates: &repofiles.CommitDateOptions{
 | 
			
		||||
		Dates: &files_service.CommitDateOptions{
 | 
			
		||||
			Author:    apiOpts.Dates.Author,
 | 
			
		||||
			Committer: apiOpts.Dates.Committer,
 | 
			
		||||
		},
 | 
			
		||||
| 
						 | 
				
			
			@ -387,7 +387,7 @@ func handleCreateOrUpdateFileError(ctx *context.APIContext, err error) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// Called from both CreateFile or UpdateFile to handle both
 | 
			
		||||
func createOrUpdateFile(ctx *context.APIContext, opts *repofiles.UpdateRepoFileOptions) (*api.FileResponse, error) {
 | 
			
		||||
func createOrUpdateFile(ctx *context.APIContext, opts *files_service.UpdateRepoFileOptions) (*api.FileResponse, error) {
 | 
			
		||||
	if !canWriteFiles(ctx.Repo) {
 | 
			
		||||
		return nil, models.ErrUserDoesNotHaveAccessToRepo{
 | 
			
		||||
			UserID:   ctx.User.ID,
 | 
			
		||||
| 
						 | 
				
			
			@ -401,7 +401,7 @@ func createOrUpdateFile(ctx *context.APIContext, opts *repofiles.UpdateRepoFileO
 | 
			
		|||
	}
 | 
			
		||||
	opts.Content = string(content)
 | 
			
		||||
 | 
			
		||||
	return repofiles.CreateOrUpdateRepoFile(ctx.Repo.Repository, ctx.User, opts)
 | 
			
		||||
	return files_service.CreateOrUpdateRepoFile(ctx.Repo.Repository, ctx.User, opts)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DeleteFile Delete a fle in a repository
 | 
			
		||||
| 
						 | 
				
			
			@ -457,21 +457,21 @@ func DeleteFile(ctx *context.APIContext) {
 | 
			
		|||
		apiOpts.BranchName = ctx.Repo.Repository.DefaultBranch
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	opts := &repofiles.DeleteRepoFileOptions{
 | 
			
		||||
	opts := &files_service.DeleteRepoFileOptions{
 | 
			
		||||
		Message:   apiOpts.Message,
 | 
			
		||||
		OldBranch: apiOpts.BranchName,
 | 
			
		||||
		NewBranch: apiOpts.NewBranchName,
 | 
			
		||||
		SHA:       apiOpts.SHA,
 | 
			
		||||
		TreePath:  ctx.Params("*"),
 | 
			
		||||
		Committer: &repofiles.IdentityOptions{
 | 
			
		||||
		Committer: &files_service.IdentityOptions{
 | 
			
		||||
			Name:  apiOpts.Committer.Name,
 | 
			
		||||
			Email: apiOpts.Committer.Email,
 | 
			
		||||
		},
 | 
			
		||||
		Author: &repofiles.IdentityOptions{
 | 
			
		||||
		Author: &files_service.IdentityOptions{
 | 
			
		||||
			Name:  apiOpts.Author.Name,
 | 
			
		||||
			Email: apiOpts.Author.Email,
 | 
			
		||||
		},
 | 
			
		||||
		Dates: &repofiles.CommitDateOptions{
 | 
			
		||||
		Dates: &files_service.CommitDateOptions{
 | 
			
		||||
			Author:    apiOpts.Dates.Author,
 | 
			
		||||
			Committer: apiOpts.Dates.Committer,
 | 
			
		||||
		},
 | 
			
		||||
| 
						 | 
				
			
			@ -488,7 +488,7 @@ func DeleteFile(ctx *context.APIContext) {
 | 
			
		|||
		opts.Message = ctx.Tr("repo.editor.delete", opts.TreePath)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if fileResponse, err := repofiles.DeleteRepoFile(ctx.Repo.Repository, ctx.User, opts); err != nil {
 | 
			
		||||
	if fileResponse, err := files_service.DeleteRepoFile(ctx.Repo.Repository, ctx.User, opts); err != nil {
 | 
			
		||||
		if git.IsErrBranchNotExist(err) || models.IsErrRepoFileDoesNotExist(err) || git.IsErrNotExist(err) {
 | 
			
		||||
			ctx.Error(http.StatusNotFound, "DeleteFile", err)
 | 
			
		||||
			return
 | 
			
		||||
| 
						 | 
				
			
			@ -554,7 +554,7 @@ func GetContents(ctx *context.APIContext) {
 | 
			
		|||
	treePath := ctx.Params("*")
 | 
			
		||||
	ref := ctx.FormTrim("ref")
 | 
			
		||||
 | 
			
		||||
	if fileList, err := repofiles.GetContentsOrList(ctx.Repo.Repository, treePath, ref); err != nil {
 | 
			
		||||
	if fileList, err := files_service.GetContentsOrList(ctx.Repo.Repository, treePath, ref); err != nil {
 | 
			
		||||
		if git.IsErrNotExist(err) {
 | 
			
		||||
			ctx.NotFound("GetContentsOrList", err)
 | 
			
		||||
			return
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,10 +11,10 @@ import (
 | 
			
		|||
	"code.gitea.io/gitea/models"
 | 
			
		||||
	"code.gitea.io/gitea/modules/context"
 | 
			
		||||
	"code.gitea.io/gitea/modules/convert"
 | 
			
		||||
	"code.gitea.io/gitea/modules/repofiles"
 | 
			
		||||
	api "code.gitea.io/gitea/modules/structs"
 | 
			
		||||
	"code.gitea.io/gitea/modules/web"
 | 
			
		||||
	"code.gitea.io/gitea/routers/api/v1/utils"
 | 
			
		||||
	files_service "code.gitea.io/gitea/services/repository/files"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// NewCommitStatus creates a new CommitStatus
 | 
			
		||||
| 
						 | 
				
			
			@ -62,7 +62,7 @@ func NewCommitStatus(ctx *context.APIContext) {
 | 
			
		|||
		Description: form.Description,
 | 
			
		||||
		Context:     form.Context,
 | 
			
		||||
	}
 | 
			
		||||
	if err := repofiles.CreateCommitStatus(ctx.Repo.Repository, ctx.User, sha, status); err != nil {
 | 
			
		||||
	if err := files_service.CreateCommitStatus(ctx.Repo.Repository, ctx.User, sha, status); err != nil {
 | 
			
		||||
		ctx.Error(http.StatusInternalServerError, "CreateCommitStatus", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,7 @@ import (
 | 
			
		|||
	"net/http"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/modules/context"
 | 
			
		||||
	"code.gitea.io/gitea/modules/repofiles"
 | 
			
		||||
	files_service "code.gitea.io/gitea/services/repository/files"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// GetTree get the tree of a repository.
 | 
			
		||||
| 
						 | 
				
			
			@ -60,7 +60,7 @@ func GetTree(ctx *context.APIContext) {
 | 
			
		|||
		ctx.Error(http.StatusBadRequest, "", "sha not provided")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if tree, err := repofiles.GetTreeBySHA(ctx.Repo.Repository, sha, ctx.FormInt("page"), ctx.FormInt("per_page"), ctx.FormBool("recursive")); err != nil {
 | 
			
		||||
	if tree, err := files_service.GetTreeBySHA(ctx.Repo.Repository, sha, ctx.FormInt("page"), ctx.FormInt("per_page"), ctx.FormBool("recursive")); err != nil {
 | 
			
		||||
		ctx.Error(http.StatusBadRequest, "", err.Error())
 | 
			
		||||
	} else {
 | 
			
		||||
		ctx.JSON(http.StatusOK, tree)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,7 +17,6 @@ import (
 | 
			
		|||
	"code.gitea.io/gitea/modules/context"
 | 
			
		||||
	"code.gitea.io/gitea/modules/git"
 | 
			
		||||
	"code.gitea.io/gitea/modules/log"
 | 
			
		||||
	"code.gitea.io/gitea/modules/repofiles"
 | 
			
		||||
	repo_module "code.gitea.io/gitea/modules/repository"
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
| 
						 | 
				
			
			@ -26,6 +25,7 @@ import (
 | 
			
		|||
	"code.gitea.io/gitea/services/forms"
 | 
			
		||||
	release_service "code.gitea.io/gitea/services/release"
 | 
			
		||||
	repo_service "code.gitea.io/gitea/services/repository"
 | 
			
		||||
	files_service "code.gitea.io/gitea/services/repository/files"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
| 
						 | 
				
			
			@ -165,7 +165,7 @@ func redirect(ctx *context.Context) {
 | 
			
		|||
// loadBranches loads branches from the repository limited by page & pageSize.
 | 
			
		||||
// NOTE: May write to context on error.
 | 
			
		||||
func loadBranches(ctx *context.Context, skip, limit int) ([]*Branch, int) {
 | 
			
		||||
	defaultBranch, err := repo_module.GetBranch(ctx.Repo.Repository, ctx.Repo.Repository.DefaultBranch)
 | 
			
		||||
	defaultBranch, err := repo_service.GetBranch(ctx.Repo.Repository, ctx.Repo.Repository.DefaultBranch)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Error("loadBranches: get default branch: %v", err)
 | 
			
		||||
		ctx.ServerError("GetDefaultBranch", err)
 | 
			
		||||
| 
						 | 
				
			
			@ -242,7 +242,7 @@ func loadOneBranch(ctx *context.Context, rawBranch *git.Branch, protectedBranche
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	divergence, divergenceError := repofiles.CountDivergingCommits(ctx.Repo.Repository, git.BranchPrefix+branchName)
 | 
			
		||||
	divergence, divergenceError := files_service.CountDivergingCommits(ctx.Repo.Repository, git.BranchPrefix+branchName)
 | 
			
		||||
	if divergenceError != nil {
 | 
			
		||||
		ctx.ServerError("CountDivergingCommits", divergenceError)
 | 
			
		||||
		return nil
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,8 +19,6 @@ import (
 | 
			
		|||
	"code.gitea.io/gitea/modules/git"
 | 
			
		||||
	"code.gitea.io/gitea/modules/json"
 | 
			
		||||
	"code.gitea.io/gitea/modules/log"
 | 
			
		||||
	"code.gitea.io/gitea/modules/repofiles"
 | 
			
		||||
	repo_module "code.gitea.io/gitea/modules/repository"
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	"code.gitea.io/gitea/modules/typesniffer"
 | 
			
		||||
	"code.gitea.io/gitea/modules/upload"
 | 
			
		||||
| 
						 | 
				
			
			@ -28,6 +26,8 @@ import (
 | 
			
		|||
	"code.gitea.io/gitea/modules/web"
 | 
			
		||||
	"code.gitea.io/gitea/routers/utils"
 | 
			
		||||
	"code.gitea.io/gitea/services/forms"
 | 
			
		||||
	repo_service "code.gitea.io/gitea/services/repository"
 | 
			
		||||
	files_service "code.gitea.io/gitea/services/repository/files"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
| 
						 | 
				
			
			@ -244,7 +244,7 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b
 | 
			
		|||
		message += "\n\n" + form.CommitMessage
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if _, err := repofiles.CreateOrUpdateRepoFile(ctx.Repo.Repository, ctx.User, &repofiles.UpdateRepoFileOptions{
 | 
			
		||||
	if _, err := files_service.CreateOrUpdateRepoFile(ctx.Repo.Repository, ctx.User, &files_service.UpdateRepoFileOptions{
 | 
			
		||||
		LastCommitID: form.LastCommit,
 | 
			
		||||
		OldBranch:    ctx.Repo.BranchName,
 | 
			
		||||
		NewBranch:    branchName,
 | 
			
		||||
| 
						 | 
				
			
			@ -255,7 +255,7 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b
 | 
			
		|||
		IsNewFile:    isNewFile,
 | 
			
		||||
		Signoff:      form.Signoff,
 | 
			
		||||
	}); err != nil {
 | 
			
		||||
		// This is where we handle all the errors thrown by repofiles.CreateOrUpdateRepoFile
 | 
			
		||||
		// This is where we handle all the errors thrown by files_service.CreateOrUpdateRepoFile
 | 
			
		||||
		if git.IsErrNotExist(err) {
 | 
			
		||||
			ctx.RenderWithErr(ctx.Tr("repo.editor.file_editing_no_longer_exists", ctx.Repo.TreePath), tplEditFile, &form)
 | 
			
		||||
		} else if models.IsErrLFSFileLocked(err) {
 | 
			
		||||
| 
						 | 
				
			
			@ -369,7 +369,7 @@ func DiffPreviewPost(ctx *context.Context) {
 | 
			
		|||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	diff, err := repofiles.GetDiffPreview(ctx.Repo.Repository, ctx.Repo.BranchName, treePath, form.Content)
 | 
			
		||||
	diff, err := files_service.GetDiffPreview(ctx.Repo.Repository, ctx.Repo.BranchName, treePath, form.Content)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		ctx.Error(http.StatusInternalServerError, "GetDiffPreview: "+err.Error())
 | 
			
		||||
		return
 | 
			
		||||
| 
						 | 
				
			
			@ -450,7 +450,7 @@ func DeleteFilePost(ctx *context.Context) {
 | 
			
		|||
		message += "\n\n" + form.CommitMessage
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if _, err := repofiles.DeleteRepoFile(ctx.Repo.Repository, ctx.User, &repofiles.DeleteRepoFileOptions{
 | 
			
		||||
	if _, err := files_service.DeleteRepoFile(ctx.Repo.Repository, ctx.User, &files_service.DeleteRepoFileOptions{
 | 
			
		||||
		LastCommitID: form.LastCommit,
 | 
			
		||||
		OldBranch:    ctx.Repo.BranchName,
 | 
			
		||||
		NewBranch:    branchName,
 | 
			
		||||
| 
						 | 
				
			
			@ -614,7 +614,7 @@ func UploadFilePost(ctx *context.Context) {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	if oldBranchName != branchName {
 | 
			
		||||
		if _, err := repo_module.GetBranch(ctx.Repo.Repository, branchName); err == nil {
 | 
			
		||||
		if _, err := repo_service.GetBranch(ctx.Repo.Repository, branchName); err == nil {
 | 
			
		||||
			ctx.Data["Err_NewBranchName"] = true
 | 
			
		||||
			ctx.RenderWithErr(ctx.Tr("repo.editor.branch_already_exists", branchName), tplUploadFile, &form)
 | 
			
		||||
			return
 | 
			
		||||
| 
						 | 
				
			
			@ -658,7 +658,7 @@ func UploadFilePost(ctx *context.Context) {
 | 
			
		|||
		message += "\n\n" + form.CommitMessage
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := repofiles.UploadRepoFiles(ctx.Repo.Repository, ctx.User, &repofiles.UploadRepoFileOptions{
 | 
			
		||||
	if err := files_service.UploadRepoFiles(ctx.Repo.Repository, ctx.User, &files_service.UploadRepoFileOptions{
 | 
			
		||||
		LastCommitID: ctx.Repo.CommitID,
 | 
			
		||||
		OldBranch:    oldBranchName,
 | 
			
		||||
		NewBranch:    branchName,
 | 
			
		||||
| 
						 | 
				
			
			@ -806,7 +806,7 @@ func GetUniquePatchBranchName(ctx *context.Context) string {
 | 
			
		|||
	prefix := ctx.User.LowerName + "-patch-"
 | 
			
		||||
	for i := 1; i <= 1000; i++ {
 | 
			
		||||
		branchName := fmt.Sprintf("%s%d", prefix, i)
 | 
			
		||||
		if _, err := repo_module.GetBranch(ctx.Repo.Repository, branchName); err != nil {
 | 
			
		||||
		if _, err := repo_service.GetBranch(ctx.Repo.Repository, branchName); err != nil {
 | 
			
		||||
			if git.IsErrBranchNotExist(err) {
 | 
			
		||||
				return branchName
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,11 +10,11 @@ import (
 | 
			
		|||
 | 
			
		||||
	"code.gitea.io/gitea/models"
 | 
			
		||||
	"code.gitea.io/gitea/models/webhook"
 | 
			
		||||
	repository_service "code.gitea.io/gitea/modules/repository"
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	"code.gitea.io/gitea/services/auth"
 | 
			
		||||
	"code.gitea.io/gitea/services/migrations"
 | 
			
		||||
	mirror_service "code.gitea.io/gitea/services/mirror"
 | 
			
		||||
	repository_service "code.gitea.io/gitea/services/repository"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func registerUpdateMirrorTask() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,7 +9,6 @@ import (
 | 
			
		|||
	"time"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/models"
 | 
			
		||||
	repo_module "code.gitea.io/gitea/modules/repository"
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	"code.gitea.io/gitea/modules/updatechecker"
 | 
			
		||||
	repo_service "code.gitea.io/gitea/services/repository"
 | 
			
		||||
| 
						 | 
				
			
			@ -56,7 +55,7 @@ func registerGarbageCollectRepositories() {
 | 
			
		|||
		Args:    setting.Git.GCArgs,
 | 
			
		||||
	}, func(ctx context.Context, _ *models.User, config Config) error {
 | 
			
		||||
		rhcConfig := config.(*RepoHealthCheckConfig)
 | 
			
		||||
		return repo_module.GitGcRepos(ctx, rhcConfig.Timeout, rhcConfig.Args...)
 | 
			
		||||
		return repo_service.GitGcRepos(ctx, rhcConfig.Timeout, rhcConfig.Args...)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -96,7 +95,7 @@ func registerReinitMissingRepositories() {
 | 
			
		|||
		RunAtStart: false,
 | 
			
		||||
		Schedule:   "@every 72h",
 | 
			
		||||
	}, func(ctx context.Context, _ *models.User, _ Config) error {
 | 
			
		||||
		return repo_module.ReinitMissingRepositories(ctx)
 | 
			
		||||
		return repo_service.ReinitMissingRepositories(ctx)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -106,7 +105,7 @@ func registerDeleteMissingRepositories() {
 | 
			
		|||
		RunAtStart: false,
 | 
			
		||||
		Schedule:   "@every 72h",
 | 
			
		||||
	}, func(ctx context.Context, user *models.User, _ Config) error {
 | 
			
		||||
		return repo_module.DeleteMissingRepositories(ctx, user)
 | 
			
		||||
		return repo_service.DeleteMissingRepositories(ctx, user)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,6 +43,20 @@ func CreateNewBranch(doer *models.User, repo *models.Repository, oldBranchName,
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetBranch returns a branch by its name
 | 
			
		||||
func GetBranch(repo *models.Repository, branch string) (*git.Branch, error) {
 | 
			
		||||
	if len(branch) == 0 {
 | 
			
		||||
		return nil, fmt.Errorf("GetBranch: empty string for branch")
 | 
			
		||||
	}
 | 
			
		||||
	gitRepo, err := git.OpenRepository(repo.RepoPath())
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	defer gitRepo.Close()
 | 
			
		||||
 | 
			
		||||
	return gitRepo.GetBranch(branch)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetBranches returns branches from the repository, skipping skip initial branches and
 | 
			
		||||
// returning at most limit branches, or all branches if limit is 0.
 | 
			
		||||
func GetBranches(repo *models.Repository, skip, limit int) ([]*git.Branch, int, error) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										73
									
								
								services/repository/files/commit.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								services/repository/files/commit.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,73 @@
 | 
			
		|||
// 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 files
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/models"
 | 
			
		||||
	"code.gitea.io/gitea/modules/git"
 | 
			
		||||
	"code.gitea.io/gitea/modules/structs"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// CreateCommitStatus creates a new CommitStatus given a bunch of parameters
 | 
			
		||||
// NOTE: All text-values will be trimmed from whitespaces.
 | 
			
		||||
// Requires: Repo, Creator, SHA
 | 
			
		||||
func CreateCommitStatus(repo *models.Repository, creator *models.User, sha string, status *models.CommitStatus) error {
 | 
			
		||||
	repoPath := repo.RepoPath()
 | 
			
		||||
 | 
			
		||||
	// confirm that commit is exist
 | 
			
		||||
	gitRepo, err := git.OpenRepository(repoPath)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("OpenRepository[%s]: %v", repoPath, err)
 | 
			
		||||
	}
 | 
			
		||||
	if _, err := gitRepo.GetCommit(sha); err != nil {
 | 
			
		||||
		gitRepo.Close()
 | 
			
		||||
		return fmt.Errorf("GetCommit[%s]: %v", sha, err)
 | 
			
		||||
	}
 | 
			
		||||
	gitRepo.Close()
 | 
			
		||||
 | 
			
		||||
	if err := models.NewCommitStatus(models.NewCommitStatusOptions{
 | 
			
		||||
		Repo:         repo,
 | 
			
		||||
		Creator:      creator,
 | 
			
		||||
		SHA:          sha,
 | 
			
		||||
		CommitStatus: status,
 | 
			
		||||
	}); err != nil {
 | 
			
		||||
		return fmt.Errorf("NewCommitStatus[repo_id: %d, user_id: %d, sha: %s]: %v", repo.ID, creator.ID, sha, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CountDivergingCommits determines how many commits a branch is ahead or behind the repository's base branch
 | 
			
		||||
func CountDivergingCommits(repo *models.Repository, branch string) (*git.DivergeObject, error) {
 | 
			
		||||
	divergence, err := git.GetDivergingCommits(repo.RepoPath(), repo.DefaultBranch, branch)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return &divergence, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetPayloadCommitVerification returns the verification information of a commit
 | 
			
		||||
func GetPayloadCommitVerification(commit *git.Commit) *structs.PayloadCommitVerification {
 | 
			
		||||
	verification := &structs.PayloadCommitVerification{}
 | 
			
		||||
	commitVerification := models.ParseCommitWithSignature(commit)
 | 
			
		||||
	if commit.Signature != nil {
 | 
			
		||||
		verification.Signature = commit.Signature.Signature
 | 
			
		||||
		verification.Payload = commit.Signature.Payload
 | 
			
		||||
	}
 | 
			
		||||
	if commitVerification.SigningUser != nil {
 | 
			
		||||
		verification.Signer = &structs.PayloadUser{
 | 
			
		||||
			Name:  commitVerification.SigningUser.Name,
 | 
			
		||||
			Email: commitVerification.SigningUser.Email,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	verification.Verified = commitVerification.Verified
 | 
			
		||||
	verification.Reason = commitVerification.Reason
 | 
			
		||||
	if verification.Reason == "" && !verification.Verified {
 | 
			
		||||
		verification.Reason = "gpg.error.not_signed_commit"
 | 
			
		||||
	}
 | 
			
		||||
	return verification
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
// Use of this source code is governed by a MIT-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package repofiles
 | 
			
		||||
package files
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
| 
						 | 
				
			
			@ -12,6 +12,7 @@ import (
 | 
			
		|||
 | 
			
		||||
	"code.gitea.io/gitea/models"
 | 
			
		||||
	"code.gitea.io/gitea/modules/git"
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	api "code.gitea.io/gitea/modules/structs"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -215,3 +216,30 @@ func GetContents(repo *models.Repository, treePath, ref string, forList bool) (*
 | 
			
		|||
 | 
			
		||||
	return contentsResponse, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetBlobBySHA get the GitBlobResponse of a repository using a sha hash.
 | 
			
		||||
func GetBlobBySHA(repo *models.Repository, sha string) (*api.GitBlobResponse, error) {
 | 
			
		||||
	gitRepo, err := git.OpenRepository(repo.RepoPath())
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	defer gitRepo.Close()
 | 
			
		||||
	gitBlob, err := gitRepo.GetBlob(sha)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	content := ""
 | 
			
		||||
	if gitBlob.Size() <= setting.API.DefaultMaxBlobSize {
 | 
			
		||||
		content, err = gitBlob.GetBlobContentBase64()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return &api.GitBlobResponse{
 | 
			
		||||
		SHA:      gitBlob.ID.String(),
 | 
			
		||||
		URL:      repo.APIURL() + "/git/blobs/" + url.PathEscape(gitBlob.ID.String()),
 | 
			
		||||
		Size:     gitBlob.Size(),
 | 
			
		||||
		Encoding: "base64",
 | 
			
		||||
		Content:  content,
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
// Use of this source code is governed by a MIT-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package repofiles
 | 
			
		||||
package files
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
| 
						 | 
				
			
			@ -16,7 +16,7 @@ import (
 | 
			
		|||
)
 | 
			
		||||
 | 
			
		||||
func TestMain(m *testing.M) {
 | 
			
		||||
	unittest.MainTest(m, filepath.Join("..", ".."))
 | 
			
		||||
	unittest.MainTest(m, filepath.Join("..", "..", ".."))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getExpectedReadmeContentsResponse() *api.ContentsResponse {
 | 
			
		||||
| 
						 | 
				
			
			@ -218,3 +218,28 @@ func TestGetContentsOrListOfEmptyRepos(t *testing.T) {
 | 
			
		|||
		assert.Empty(t, contents)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestGetBlobBySHA(t *testing.T) {
 | 
			
		||||
	unittest.PrepareTestEnv(t)
 | 
			
		||||
	ctx := test.MockContext(t, "user2/repo1")
 | 
			
		||||
	test.LoadRepo(t, ctx, 1)
 | 
			
		||||
	test.LoadRepoCommit(t, ctx)
 | 
			
		||||
	test.LoadUser(t, ctx, 2)
 | 
			
		||||
	test.LoadGitRepo(t, ctx)
 | 
			
		||||
	defer ctx.Repo.GitRepo.Close()
 | 
			
		||||
 | 
			
		||||
	sha := "65f1bf27bc3bf70f64657658635e66094edbcb4d"
 | 
			
		||||
	ctx.SetParams(":id", "1")
 | 
			
		||||
	ctx.SetParams(":sha", sha)
 | 
			
		||||
 | 
			
		||||
	gbr, err := GetBlobBySHA(ctx.Repo.Repository, ctx.Params(":sha"))
 | 
			
		||||
	expectedGBR := &api.GitBlobResponse{
 | 
			
		||||
		Content:  "dHJlZSAyYTJmMWQ0NjcwNzI4YTJlMTAwNDllMzQ1YmQ3YTI3NjQ2OGJlYWI2CmF1dGhvciB1c2VyMSA8YWRkcmVzczFAZXhhbXBsZS5jb20+IDE0ODk5NTY0NzkgLTA0MDAKY29tbWl0dGVyIEV0aGFuIEtvZW5pZyA8ZXRoYW50a29lbmlnQGdtYWlsLmNvbT4gMTQ4OTk1NjQ3OSAtMDQwMAoKSW5pdGlhbCBjb21taXQK",
 | 
			
		||||
		Encoding: "base64",
 | 
			
		||||
		URL:      "https://try.gitea.io/api/v1/repos/user2/repo1/git/blobs/65f1bf27bc3bf70f64657658635e66094edbcb4d",
 | 
			
		||||
		SHA:      "65f1bf27bc3bf70f64657658635e66094edbcb4d",
 | 
			
		||||
		Size:     180,
 | 
			
		||||
	}
 | 
			
		||||
	assert.NoError(t, err)
 | 
			
		||||
	assert.Equal(t, expectedGBR, gbr)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
// Use of this source code is governed by a MIT-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package repofiles
 | 
			
		||||
package files
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
| 
						 | 
				
			
			@ -10,8 +10,8 @@ import (
 | 
			
		|||
 | 
			
		||||
	"code.gitea.io/gitea/models"
 | 
			
		||||
	"code.gitea.io/gitea/modules/git"
 | 
			
		||||
	repo_module "code.gitea.io/gitea/modules/repository"
 | 
			
		||||
	api "code.gitea.io/gitea/modules/structs"
 | 
			
		||||
	repo_service "code.gitea.io/gitea/services/repository"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// DeleteRepoFileOptions holds the repository delete file options
 | 
			
		||||
| 
						 | 
				
			
			@ -39,7 +39,7 @@ func DeleteRepoFile(repo *models.Repository, doer *models.User, opts *DeleteRepo
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	// oldBranch must exist for this operation
 | 
			
		||||
	if _, err := repo_module.GetBranch(repo, opts.OldBranch); err != nil {
 | 
			
		||||
	if _, err := repo_service.GetBranch(repo, opts.OldBranch); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -47,7 +47,7 @@ func DeleteRepoFile(repo *models.Repository, doer *models.User, opts *DeleteRepo
 | 
			
		|||
	// Check to make sure the branch does not already exist, otherwise we can't proceed.
 | 
			
		||||
	// If we aren't branching to a new branch, make sure user can commit to the given branch
 | 
			
		||||
	if opts.NewBranch != opts.OldBranch {
 | 
			
		||||
		newBranch, err := repo_module.GetBranch(repo, opts.NewBranch)
 | 
			
		||||
		newBranch, err := repo_service.GetBranch(repo, opts.NewBranch)
 | 
			
		||||
		if err != nil && !git.IsErrBranchNotExist(err) {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
// Use of this source code is governed by a MIT-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package repofiles
 | 
			
		||||
package files
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"strings"
 | 
			
		||||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
// Use of this source code is governed by a MIT-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package repofiles
 | 
			
		||||
package files
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"testing"
 | 
			
		||||
| 
						 | 
				
			
			@ -2,11 +2,12 @@
 | 
			
		|||
// Use of this source code is governed by a MIT-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package repofiles
 | 
			
		||||
package files
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"path"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -123,3 +124,16 @@ func GetAuthorAndCommitterUsers(author, committer *IdentityOptions, doer *models
 | 
			
		|||
	}
 | 
			
		||||
	return authorUser, committerUser
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CleanUploadFileName Trims a filename and returns empty string if it is a .git directory
 | 
			
		||||
func CleanUploadFileName(name string) string {
 | 
			
		||||
	// Rebase the filename
 | 
			
		||||
	name = strings.Trim(path.Clean("/"+name), " /")
 | 
			
		||||
	// Git disallows any filenames to have a .git directory in them.
 | 
			
		||||
	for _, part := range strings.Split(name, "/") {
 | 
			
		||||
		if strings.ToLower(part) == ".git" {
 | 
			
		||||
			return ""
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return name
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
// Use of this source code is governed by a MIT-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package repofiles
 | 
			
		||||
package files
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"testing"
 | 
			
		||||
| 
						 | 
				
			
			@ -16,6 +16,22 @@ import (
 | 
			
		|||
	"github.com/stretchr/testify/assert"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestCleanUploadFileName(t *testing.T) {
 | 
			
		||||
	t.Run("Clean regular file", func(t *testing.T) {
 | 
			
		||||
		name := "this/is/test"
 | 
			
		||||
		cleanName := CleanUploadFileName(name)
 | 
			
		||||
		expectedCleanName := name
 | 
			
		||||
		assert.EqualValues(t, expectedCleanName, cleanName)
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	t.Run("Clean a .git path", func(t *testing.T) {
 | 
			
		||||
		name := "this/is/test/.git"
 | 
			
		||||
		cleanName := CleanUploadFileName(name)
 | 
			
		||||
		expectedCleanName := ""
 | 
			
		||||
		assert.EqualValues(t, expectedCleanName, cleanName)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getExpectedFileResponse() *api.FileResponse {
 | 
			
		||||
	treePath := "README.md"
 | 
			
		||||
	sha := "4b4851ad51df6a7d9f25c979345979eaeb5b349f"
 | 
			
		||||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
// Use of this source code is governed by a MIT-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package repofiles
 | 
			
		||||
package files
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
// Use of this source code is governed by a MIT-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package repofiles
 | 
			
		||||
package files
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
// Use of this source code is governed by a MIT-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package repofiles
 | 
			
		||||
package files
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"testing"
 | 
			
		||||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
// Use of this source code is governed by a MIT-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package repofiles
 | 
			
		||||
package files
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
| 
						 | 
				
			
			@ -16,10 +16,10 @@ import (
 | 
			
		|||
	"code.gitea.io/gitea/modules/git"
 | 
			
		||||
	"code.gitea.io/gitea/modules/lfs"
 | 
			
		||||
	"code.gitea.io/gitea/modules/log"
 | 
			
		||||
	repo_module "code.gitea.io/gitea/modules/repository"
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	"code.gitea.io/gitea/modules/structs"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
	repo_service "code.gitea.io/gitea/services/repository"
 | 
			
		||||
 | 
			
		||||
	stdcharset "golang.org/x/net/html/charset"
 | 
			
		||||
	"golang.org/x/text/transform"
 | 
			
		||||
| 
						 | 
				
			
			@ -132,7 +132,7 @@ func CreateOrUpdateRepoFile(repo *models.Repository, doer *models.User, opts *Up
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	// oldBranch must exist for this operation
 | 
			
		||||
	if _, err := repo_module.GetBranch(repo, opts.OldBranch); err != nil {
 | 
			
		||||
	if _, err := repo_service.GetBranch(repo, opts.OldBranch); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -140,7 +140,7 @@ func CreateOrUpdateRepoFile(repo *models.Repository, doer *models.User, opts *Up
 | 
			
		|||
	// Check to make sure the branch does not already exist, otherwise we can't proceed.
 | 
			
		||||
	// If we aren't branching to a new branch, make sure user can commit to the given branch
 | 
			
		||||
	if opts.NewBranch != opts.OldBranch {
 | 
			
		||||
		existingBranch, err := repo_module.GetBranch(repo, opts.NewBranch)
 | 
			
		||||
		existingBranch, err := repo_service.GetBranch(repo, opts.NewBranch)
 | 
			
		||||
		if existingBranch != nil {
 | 
			
		||||
			return nil, models.ErrBranchAlreadyExists{
 | 
			
		||||
				BranchName: opts.NewBranch,
 | 
			
		||||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
// Use of this source code is governed by a MIT-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package repofiles
 | 
			
		||||
package files
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue