1
0
Просмотр исходного кода

repo: check directory existence before creation (#8091)

Co-authored-by: ᴊᴏᴇ ᴄʜᴇɴ <jc@unknwon.io>
Shivam Kumar 3 недель назад
Родитель
Сommit
beeeb64969
3 измененных файлов с 24 добавлено и 5 удалено
  1. 1 0
      CHANGELOG.md
  2. 4 5
      internal/database/repo.go
  3. 19 0
      internal/database/repo_test.go

+ 1 - 0
CHANGELOG.md

@@ -16,6 +16,7 @@ All notable changes to Gogs are documented in this file.
 - The required Go version to compile source code changed to 1.25.
 - The build tag `cert` has been removed, and the `gogs cert` subcommand is now always available. [#7883](https://github.com/gogs/gogs/pull/7883)
 - Updated Mermaid JS to 11.9.0. [#8009](https://github.com/gogs/gogs/pull/8009)
+- Halt the repository creation and leave the directory untouched if the repository root already exists. [#8091](https://github.com/gogs/gogs/pull/8091)
 
 ### Fixed
 

+ 4 - 5
internal/database/repo.go

@@ -1037,10 +1037,6 @@ func prepareRepoCommit(repo *Repository, tmpDir, repoPath string, opts CreateRep
 
 // initRepository performs initial commit with chosen setup files on behave of doer.
 func initRepository(e Engine, repoPath string, doer *User, repo *Repository, opts CreateRepoOptionsLegacy) (err error) {
-	// Somehow the directory could exist.
-	if com.IsExist(repoPath) {
-		return fmt.Errorf("initRepository: path already exists: %s", repoPath)
-	}
 
 	// Init bare new repository.
 	if err = git.Init(repoPath, git.InitOptions{Bare: true}); err != nil {
@@ -1204,6 +1200,10 @@ func (err ErrReachLimitOfRepo) Error() string {
 
 // CreateRepository creates a repository for given user or organization.
 func CreateRepository(doer, owner *User, opts CreateRepoOptionsLegacy) (_ *Repository, err error) {
+	repoPath := RepoPath(owner.Name, opts.Name)
+	if osutil.IsExist(repoPath) {
+		return nil, errors.Errorf("repository directory already exists: %s", repoPath)
+	}
 	if !owner.canCreateRepo() {
 		return nil, ErrReachLimitOfRepo{Limit: owner.maxNumRepos()}
 	}
@@ -1233,7 +1233,6 @@ func CreateRepository(doer, owner *User, opts CreateRepoOptionsLegacy) (_ *Repos
 
 	// No need for init mirror.
 	if !opts.IsMirror {
-		repoPath := RepoPath(owner.Name, repo.Name)
 		if err = initRepository(sess, repoPath, doer, repo, opts); err != nil {
 			RemoveAllWithNotice("Delete repository for initialization failure", repoPath)
 			return nil, fmt.Errorf("initRepository: %v", err)

+ 19 - 0
internal/database/repo_test.go

@@ -1,11 +1,15 @@
 package database
 
 import (
+	"os"
+	"path/filepath"
 	"testing"
 
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 
 	"gogs.io/gogs/internal/markup"
+	"gogs.io/gogs/internal/osutil"
 )
 
 func TestRepository_ComposeMetas(t *testing.T) {
@@ -52,3 +56,18 @@ func TestRepository_ComposeMetas(t *testing.T) {
 		assert.Equal(t, "https://someurl.com/{user}/{repo}/{issue}", metas["format"])
 	})
 }
+
+func Test_CreateRepository_PreventDeletion(t *testing.T) {
+	owner := &User{Name: "testuser"}
+	opts := CreateRepoOptionsLegacy{Name: "safety-test"}
+	repoPath := RepoPath(owner.Name, opts.Name)
+	require.NoError(t, os.MkdirAll(repoPath, os.ModePerm))
+
+	canary := filepath.Join(repoPath, "canary.txt")
+	require.NoError(t, os.WriteFile(canary, []byte("should survive"), 0644))
+
+	_, err := CreateRepository(owner, owner, opts)
+	require.Error(t, err)
+	assert.Contains(t, err.Error(), "repository directory already exists")
+	assert.True(t, osutil.IsExist(canary))
+}