Browse Source

repo_editor: able to trigger Git hooks (#4338)

Unknwon 6 years ago
parent
commit
ac73d43444
8 changed files with 137 additions and 209 deletions
  1. 17 18
      cmd/hook.go
  2. 1 2
      cmd/serv.go
  3. 1 1
      gogs.go
  4. 96 133
      models/repo_editor.go
  5. 4 0
      pkg/context/context.go
  6. 16 17
      routes/repo/editor.go
  7. 1 37
      routes/repo/http.go
  8. 1 1
      templates/.VERSION

+ 17 - 18
cmd/hook.go

@@ -27,7 +27,6 @@ import (
 	"github.com/gogs/gogs/pkg/mailer"
 	"github.com/gogs/gogs/pkg/setting"
 	"github.com/gogs/gogs/pkg/template"
-	http "github.com/gogs/gogs/routes/repo"
 )
 
 var (
@@ -71,7 +70,7 @@ func runHookPreReceive(c *cli.Context) error {
 	}
 	setup(c, "hooks/pre-receive.log", true)
 
-	isWiki := strings.Contains(os.Getenv(http.ENV_REPO_CUSTOM_HOOKS_PATH), ".wiki.git/")
+	isWiki := strings.Contains(os.Getenv(models.ENV_REPO_CUSTOM_HOOKS_PATH), ".wiki.git/")
 
 	buf := bytes.NewBuffer(nil)
 	scanner := bufio.NewScanner(os.Stdin)
@@ -92,7 +91,7 @@ func runHookPreReceive(c *cli.Context) error {
 		branchName := strings.TrimPrefix(string(fields[2]), git.BRANCH_PREFIX)
 
 		// Branch protection
-		repoID := com.StrTo(os.Getenv(http.ENV_REPO_ID)).MustInt64()
+		repoID := com.StrTo(os.Getenv(models.ENV_REPO_ID)).MustInt64()
 		protectBranch, err := models.GetProtectBranchOfRepoByName(repoID, branchName)
 		if err != nil {
 			if errors.IsErrBranchNotExist(err) {
@@ -108,7 +107,7 @@ func runHookPreReceive(c *cli.Context) error {
 		bypassRequirePullRequest := false
 
 		// Check if user is in whitelist when enabled
-		userID := com.StrTo(os.Getenv(http.ENV_AUTH_USER_ID)).MustInt64()
+		userID := com.StrTo(os.Getenv(models.ENV_AUTH_USER_ID)).MustInt64()
 		if protectBranch.EnableWhitelist {
 			if !models.IsUserInProtectBranchWhitelist(repoID, userID, branchName) {
 				fail(fmt.Sprintf("Branch '%s' is protected and you are not in the push whitelist", branchName), "")
@@ -129,7 +128,7 @@ func runHookPreReceive(c *cli.Context) error {
 
 		// Check force push
 		output, err := git.NewCommand("rev-list", "--max-count=1", oldCommitID, "^"+newCommitID).
-			RunInDir(models.RepoPath(os.Getenv(http.ENV_REPO_OWNER_NAME), os.Getenv(http.ENV_REPO_NAME)))
+			RunInDir(models.RepoPath(os.Getenv(models.ENV_REPO_OWNER_NAME), os.Getenv(models.ENV_REPO_NAME)))
 		if err != nil {
 			fail("Internal error", "Fail to detect force push: %v", err)
 		} else if len(output) > 0 {
@@ -137,7 +136,7 @@ func runHookPreReceive(c *cli.Context) error {
 		}
 	}
 
-	customHooksPath := filepath.Join(os.Getenv(http.ENV_REPO_CUSTOM_HOOKS_PATH), "pre-receive")
+	customHooksPath := filepath.Join(os.Getenv(models.ENV_REPO_CUSTOM_HOOKS_PATH), "pre-receive")
 	if !com.IsFile(customHooksPath) {
 		return nil
 	}
@@ -148,7 +147,7 @@ func runHookPreReceive(c *cli.Context) error {
 	} else {
 		hookCmd = exec.Command(customHooksPath)
 	}
-	hookCmd.Dir = models.RepoPath(os.Getenv(http.ENV_REPO_OWNER_NAME), os.Getenv(http.ENV_REPO_NAME))
+	hookCmd.Dir = models.RepoPath(os.Getenv(models.ENV_REPO_OWNER_NAME), os.Getenv(models.ENV_REPO_NAME))
 	hookCmd.Stdout = os.Stdout
 	hookCmd.Stdin = buf
 	hookCmd.Stderr = os.Stderr
@@ -171,7 +170,7 @@ func runHookUpdate(c *cli.Context) error {
 		fail("First argument 'refName' is empty", "First argument 'refName' is empty")
 	}
 
-	customHooksPath := filepath.Join(os.Getenv(http.ENV_REPO_CUSTOM_HOOKS_PATH), "update")
+	customHooksPath := filepath.Join(os.Getenv(models.ENV_REPO_CUSTOM_HOOKS_PATH), "update")
 	if !com.IsFile(customHooksPath) {
 		return nil
 	}
@@ -182,7 +181,7 @@ func runHookUpdate(c *cli.Context) error {
 	} else {
 		hookCmd = exec.Command(customHooksPath, args...)
 	}
-	hookCmd.Dir = models.RepoPath(os.Getenv(http.ENV_REPO_OWNER_NAME), os.Getenv(http.ENV_REPO_NAME))
+	hookCmd.Dir = models.RepoPath(os.Getenv(models.ENV_REPO_OWNER_NAME), os.Getenv(models.ENV_REPO_NAME))
 	hookCmd.Stdout = os.Stdout
 	hookCmd.Stdin = os.Stdin
 	hookCmd.Stderr = os.Stderr
@@ -205,7 +204,7 @@ func runHookPostReceive(c *cli.Context) error {
 	mailer.InitMailRender(path.Join(setting.StaticRootPath, "templates/mail"),
 		path.Join(setting.CustomPath, "templates/mail"), template.NewFuncMap())
 
-	isWiki := strings.Contains(os.Getenv(http.ENV_REPO_CUSTOM_HOOKS_PATH), ".wiki.git/")
+	isWiki := strings.Contains(os.Getenv(models.ENV_REPO_CUSTOM_HOOKS_PATH), ".wiki.git/")
 
 	buf := bytes.NewBuffer(nil)
 	scanner := bufio.NewScanner(os.Stdin)
@@ -227,10 +226,10 @@ func runHookPostReceive(c *cli.Context) error {
 			OldCommitID:  string(fields[0]),
 			NewCommitID:  string(fields[1]),
 			RefFullName:  string(fields[2]),
-			PusherID:     com.StrTo(os.Getenv(http.ENV_AUTH_USER_ID)).MustInt64(),
-			PusherName:   os.Getenv(http.ENV_AUTH_USER_NAME),
-			RepoUserName: os.Getenv(http.ENV_REPO_OWNER_NAME),
-			RepoName:     os.Getenv(http.ENV_REPO_NAME),
+			PusherID:     com.StrTo(os.Getenv(models.ENV_AUTH_USER_ID)).MustInt64(),
+			PusherName:   os.Getenv(models.ENV_AUTH_USER_NAME),
+			RepoUserName: os.Getenv(models.ENV_REPO_OWNER_NAME),
+			RepoName:     os.Getenv(models.ENV_REPO_NAME),
 		}
 		if err := models.PushUpdate(options); err != nil {
 			log.Error(2, "PushUpdate: %v", err)
@@ -239,8 +238,8 @@ func runHookPostReceive(c *cli.Context) error {
 		// Ask for running deliver hook and test pull request tasks
 		reqURL := setting.LocalURL + options.RepoUserName + "/" + options.RepoName + "/tasks/trigger?branch=" +
 			template.EscapePound(strings.TrimPrefix(options.RefFullName, git.BRANCH_PREFIX)) +
-			"&secret=" + os.Getenv(http.ENV_REPO_OWNER_SALT_MD5) +
-			"&pusher=" + os.Getenv(http.ENV_AUTH_USER_ID)
+			"&secret=" + os.Getenv(models.ENV_REPO_OWNER_SALT_MD5) +
+			"&pusher=" + os.Getenv(models.ENV_AUTH_USER_ID)
 		log.Trace("Trigger task: %s", reqURL)
 
 		resp, err := httplib.Head(reqURL).SetTLSClientConfig(&tls.Config{
@@ -256,7 +255,7 @@ func runHookPostReceive(c *cli.Context) error {
 		}
 	}
 
-	customHooksPath := filepath.Join(os.Getenv(http.ENV_REPO_CUSTOM_HOOKS_PATH), "post-receive")
+	customHooksPath := filepath.Join(os.Getenv(models.ENV_REPO_CUSTOM_HOOKS_PATH), "post-receive")
 	if !com.IsFile(customHooksPath) {
 		return nil
 	}
@@ -267,7 +266,7 @@ func runHookPostReceive(c *cli.Context) error {
 	} else {
 		hookCmd = exec.Command(customHooksPath)
 	}
-	hookCmd.Dir = models.RepoPath(os.Getenv(http.ENV_REPO_OWNER_NAME), os.Getenv(http.ENV_REPO_NAME))
+	hookCmd.Dir = models.RepoPath(os.Getenv(models.ENV_REPO_OWNER_NAME), os.Getenv(models.ENV_REPO_NAME))
 	hookCmd.Stdout = os.Stdout
 	hookCmd.Stdin = buf
 	hookCmd.Stderr = os.Stderr

+ 1 - 2
cmd/serv.go

@@ -19,7 +19,6 @@ import (
 	"github.com/gogs/gogs/models"
 	"github.com/gogs/gogs/models/errors"
 	"github.com/gogs/gogs/pkg/setting"
-	http "github.com/gogs/gogs/routes/repo"
 )
 
 const (
@@ -252,7 +251,7 @@ func runServ(c *cli.Context) error {
 		gitCmd = exec.Command(verb, repoFullName)
 	}
 	if requestMode == models.ACCESS_MODE_WRITE {
-		gitCmd.Env = append(os.Environ(), http.ComposeHookEnvs(http.ComposeHookEnvsOptions{
+		gitCmd.Env = append(os.Environ(), models.ComposeHookEnvs(models.ComposeHookEnvsOptions{
 			AuthUser:  user,
 			OwnerName: owner.Name,
 			OwnerSalt: owner.Salt,

+ 1 - 1
gogs.go

@@ -16,7 +16,7 @@ import (
 	"github.com/gogs/gogs/pkg/setting"
 )
 
-const APP_VER = "0.11.62.0817"
+const APP_VER = "0.11.63.0817"
 
 func init() {
 	setting.AppVer = APP_VER

+ 96 - 133
models/repo_editor.go

@@ -17,15 +17,50 @@ import (
 
 	"github.com/Unknwon/com"
 	gouuid "github.com/satori/go.uuid"
-	log "gopkg.in/clog.v1"
 
-	git "github.com/gogs/git-module"
+	"github.com/gogs/git-module"
 
 	"github.com/gogs/gogs/models/errors"
 	"github.com/gogs/gogs/pkg/process"
 	"github.com/gogs/gogs/pkg/setting"
+	"github.com/gogs/gogs/pkg/tool"
 )
 
+const (
+	ENV_AUTH_USER_ID           = "GOGS_AUTH_USER_ID"
+	ENV_AUTH_USER_NAME         = "GOGS_AUTH_USER_NAME"
+	ENV_AUTH_USER_EMAIL        = "GOGS_AUTH_USER_EMAIL"
+	ENV_REPO_OWNER_NAME        = "GOGS_REPO_OWNER_NAME"
+	ENV_REPO_OWNER_SALT_MD5    = "GOGS_REPO_OWNER_SALT_MD5"
+	ENV_REPO_ID                = "GOGS_REPO_ID"
+	ENV_REPO_NAME              = "GOGS_REPO_NAME"
+	ENV_REPO_CUSTOM_HOOKS_PATH = "GOGS_REPO_CUSTOM_HOOKS_PATH"
+)
+
+type ComposeHookEnvsOptions struct {
+	AuthUser  *User
+	OwnerName string
+	OwnerSalt string
+	RepoID    int64
+	RepoName  string
+	RepoPath  string
+}
+
+func ComposeHookEnvs(opts ComposeHookEnvsOptions) []string {
+	envs := []string{
+		"SSH_ORIGINAL_COMMAND=1",
+		ENV_AUTH_USER_ID + "=" + com.ToStr(opts.AuthUser.ID),
+		ENV_AUTH_USER_NAME + "=" + opts.AuthUser.Name,
+		ENV_AUTH_USER_EMAIL + "=" + opts.AuthUser.Email,
+		ENV_REPO_OWNER_NAME + "=" + opts.OwnerName,
+		ENV_REPO_OWNER_SALT_MD5 + "=" + tool.MD5(opts.OwnerSalt),
+		ENV_REPO_ID + "=" + com.ToStr(opts.RepoID),
+		ENV_REPO_NAME + "=" + opts.RepoName,
+		ENV_REPO_CUSTOM_HOOKS_PATH + "=" + path.Join(opts.RepoPath, "custom_hooks"),
+	}
+	return envs
+}
+
 // ___________    .___.__  __    ___________.__.__
 // \_   _____/  __| _/|__|/  |_  \_   _____/|__|  |   ____
 //  |    __)_  / __ | |  \   __\  |    __)  |  |  | _/ __ \
@@ -88,9 +123,9 @@ func (repo *Repository) UpdateRepoFile(doer *User, opts UpdateRepoFileOptions) (
 	defer repoWorkingPool.CheckOut(com.ToStr(repo.ID))
 
 	if err = repo.DiscardLocalRepoBranchChanges(opts.OldBranch); err != nil {
-		return fmt.Errorf("DiscardLocalRepoBranchChanges [branch: %s]: %v", opts.OldBranch, err)
+		return fmt.Errorf("discard local repo branch[%s] changes: %v", opts.OldBranch, err)
 	} else if err = repo.UpdateLocalCopyBranch(opts.OldBranch); err != nil {
-		return fmt.Errorf("UpdateLocalCopyBranch [branch: %s]: %v", opts.OldBranch, err)
+		return fmt.Errorf("update local copy branch[%s]: %v", opts.OldBranch, err)
 	}
 
 	repoPath := repo.RepoPath()
@@ -107,12 +142,12 @@ func (repo *Repository) UpdateRepoFile(doer *User, opts UpdateRepoFileOptions) (
 			if err = git.DeleteBranch(localPath, opts.NewBranch, git.DeleteBranchOptions{
 				Force: true,
 			}); err != nil {
-				return fmt.Errorf("DeleteBranch [name: %s]: %v", opts.NewBranch, err)
+				return fmt.Errorf("delete branch[%s]: %v", opts.NewBranch, err)
 			}
 		}
 
 		if err := repo.CheckoutNewBranch(opts.OldBranch, opts.NewBranch); err != nil {
-			return fmt.Errorf("CheckoutNewBranch [old_branch: %s, new_branch: %s]: %v", opts.OldBranch, opts.NewBranch, err)
+			return fmt.Errorf("checkout new branch[%s] from old branch[%s]: %v", opts.NewBranch, opts.OldBranch, err)
 		}
 	}
 
@@ -131,12 +166,12 @@ func (repo *Repository) UpdateRepoFile(doer *User, opts UpdateRepoFileOptions) (
 	// Otherwise, move the file when name changed.
 	if com.IsFile(oldFilePath) && opts.OldTreeName != opts.NewTreeName {
 		if err = git.MoveFile(localPath, opts.OldTreeName, opts.NewTreeName); err != nil {
-			return fmt.Errorf("git mv %s %s: %v", opts.OldTreeName, opts.NewTreeName, err)
+			return fmt.Errorf("git mv %q %q: %v", opts.OldTreeName, opts.NewTreeName, err)
 		}
 	}
 
 	if err = ioutil.WriteFile(filePath, []byte(opts.Content), 0666); err != nil {
-		return fmt.Errorf("WriteFile: %v", err)
+		return fmt.Errorf("write file: %v", err)
 	}
 
 	if err = git.AddChanges(localPath, true); err != nil {
@@ -145,45 +180,18 @@ func (repo *Repository) UpdateRepoFile(doer *User, opts UpdateRepoFileOptions) (
 		Committer: doer.NewGitSig(),
 		Message:   opts.Message,
 	}); err != nil {
-		return fmt.Errorf("CommitChanges: %v", err)
-	} else if err = git.Push(localPath, "origin", opts.NewBranch); err != nil {
+		return fmt.Errorf("commit changes on %q: %v", localPath, err)
+	} else if err = git.PushWithEnvs(localPath, "origin", opts.NewBranch,
+		ComposeHookEnvs(ComposeHookEnvsOptions{
+			AuthUser:  doer,
+			OwnerName: repo.MustOwner().Name,
+			OwnerSalt: repo.MustOwner().Salt,
+			RepoID:    repo.ID,
+			RepoName:  repo.Name,
+			RepoPath:  repo.RepoPath(),
+		})); err != nil {
 		return fmt.Errorf("git push origin %s: %v", opts.NewBranch, err)
 	}
-
-	gitRepo, err := git.OpenRepository(repo.RepoPath())
-	if err != nil {
-		log.Error(2, "OpenRepository: %v", err)
-		return nil
-	}
-	commit, err := gitRepo.GetBranchCommit(opts.NewBranch)
-	if err != nil {
-		log.Error(2, "GetBranchCommit [branch: %s]: %v", opts.NewBranch, err)
-		return nil
-	}
-
-	// Simulate push event.
-	pushCommits := &PushCommits{
-		Len:     1,
-		Commits: []*PushCommit{CommitToPushCommit(commit)},
-	}
-	oldCommitID := opts.LastCommitID
-	if opts.NewBranch != opts.OldBranch {
-		oldCommitID = git.EMPTY_SHA
-	}
-	if err := CommitRepoAction(CommitRepoActionOptions{
-		PusherName:  doer.Name,
-		RepoOwnerID: repo.MustOwner().ID,
-		RepoName:    repo.Name,
-		RefFullName: git.BRANCH_PREFIX + opts.NewBranch,
-		OldCommitID: oldCommitID,
-		NewCommitID: commit.ID.String(),
-		Commits:     pushCommits,
-	}); err != nil {
-		log.Error(2, "CommitRepoAction: %v", err)
-		return nil
-	}
-
-	go AddTestPullRequestTask(doer, repo.ID, opts.NewBranch, true)
 	return nil
 }
 
@@ -193,16 +201,16 @@ func (repo *Repository) GetDiffPreview(branch, treePath, content string) (diff *
 	defer repoWorkingPool.CheckOut(com.ToStr(repo.ID))
 
 	if err = repo.DiscardLocalRepoBranchChanges(branch); err != nil {
-		return nil, fmt.Errorf("DiscardLocalRepoBranchChanges [branch: %s]: %v", branch, err)
+		return nil, fmt.Errorf("discard local repo branch[%s] changes: %v", branch, err)
 	} else if err = repo.UpdateLocalCopyBranch(branch); err != nil {
-		return nil, fmt.Errorf("UpdateLocalCopyBranch [branch: %s]: %v", branch, err)
+		return nil, fmt.Errorf("update local copy branch[%s]: %v", branch, err)
 	}
 
 	localPath := repo.LocalCopyPath()
 	filePath := path.Join(localPath, treePath)
 	os.MkdirAll(filepath.Dir(filePath), os.ModePerm)
 	if err = ioutil.WriteFile(filePath, []byte(content), 0666); err != nil {
-		return nil, fmt.Errorf("WriteFile: %v", err)
+		return nil, fmt.Errorf("write file: %v", err)
 	}
 
 	cmd := exec.Command("git", "diff", treePath)
@@ -211,11 +219,11 @@ func (repo *Repository) GetDiffPreview(branch, treePath, content string) (diff *
 
 	stdout, err := cmd.StdoutPipe()
 	if err != nil {
-		return nil, fmt.Errorf("StdoutPipe: %v", err)
+		return nil, fmt.Errorf("get stdout pipe: %v", err)
 	}
 
 	if err = cmd.Start(); err != nil {
-		return nil, fmt.Errorf("Start: %v", err)
+		return nil, fmt.Errorf("start: %v", err)
 	}
 
 	pid := process.Add(fmt.Sprintf("GetDiffPreview [repo_path: %s]", repo.RepoPath()), cmd)
@@ -223,11 +231,11 @@ func (repo *Repository) GetDiffPreview(branch, treePath, content string) (diff *
 
 	diff, err = ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, stdout)
 	if err != nil {
-		return nil, fmt.Errorf("ParsePatch: %v", err)
+		return nil, fmt.Errorf("parse path: %v", err)
 	}
 
 	if err = cmd.Wait(); err != nil {
-		return nil, fmt.Errorf("Wait: %v", err)
+		return nil, fmt.Errorf("wait: %v", err)
 	}
 
 	return diff, nil
@@ -254,20 +262,20 @@ func (repo *Repository) DeleteRepoFile(doer *User, opts DeleteRepoFileOptions) (
 	defer repoWorkingPool.CheckOut(com.ToStr(repo.ID))
 
 	if err = repo.DiscardLocalRepoBranchChanges(opts.OldBranch); err != nil {
-		return fmt.Errorf("DiscardLocalRepoBranchChanges [branch: %s]: %v", opts.OldBranch, err)
+		return fmt.Errorf("discard local repo branch[%s] changes: %v", opts.OldBranch, err)
 	} else if err = repo.UpdateLocalCopyBranch(opts.OldBranch); err != nil {
-		return fmt.Errorf("UpdateLocalCopyBranch [branch: %s]: %v", opts.OldBranch, err)
+		return fmt.Errorf("update local copy branch[%s]: %v", opts.OldBranch, err)
 	}
 
 	if opts.OldBranch != opts.NewBranch {
 		if err := repo.CheckoutNewBranch(opts.OldBranch, opts.NewBranch); err != nil {
-			return fmt.Errorf("CheckoutNewBranch [old_branch: %s, new_branch: %s]: %v", opts.OldBranch, opts.NewBranch, err)
+			return fmt.Errorf("checkout new branch[%s] from old branch[%s]: %v", opts.NewBranch, opts.OldBranch, err)
 		}
 	}
 
 	localPath := repo.LocalCopyPath()
 	if err = os.Remove(path.Join(localPath, opts.TreePath)); err != nil {
-		return fmt.Errorf("Remove: %v", err)
+		return fmt.Errorf("remove file %q: %v", opts.TreePath, err)
 	}
 
 	if err = git.AddChanges(localPath, true); err != nil {
@@ -276,41 +284,18 @@ func (repo *Repository) DeleteRepoFile(doer *User, opts DeleteRepoFileOptions) (
 		Committer: doer.NewGitSig(),
 		Message:   opts.Message,
 	}); err != nil {
-		return fmt.Errorf("CommitChanges: %v", err)
-	} else if err = git.Push(localPath, "origin", opts.NewBranch); err != nil {
+		return fmt.Errorf("commit changes to %q: %v", localPath, err)
+	} else if err = git.PushWithEnvs(localPath, "origin", opts.NewBranch,
+		ComposeHookEnvs(ComposeHookEnvsOptions{
+			AuthUser:  doer,
+			OwnerName: repo.MustOwner().Name,
+			OwnerSalt: repo.MustOwner().Salt,
+			RepoID:    repo.ID,
+			RepoName:  repo.Name,
+			RepoPath:  repo.RepoPath(),
+		})); err != nil {
 		return fmt.Errorf("git push origin %s: %v", opts.NewBranch, err)
 	}
-
-	gitRepo, err := git.OpenRepository(repo.RepoPath())
-	if err != nil {
-		log.Error(2, "OpenRepository: %v", err)
-		return nil
-	}
-	commit, err := gitRepo.GetBranchCommit(opts.NewBranch)
-	if err != nil {
-		log.Error(2, "GetBranchCommit [branch: %s]: %v", opts.NewBranch, err)
-		return nil
-	}
-
-	// Simulate push event.
-	pushCommits := &PushCommits{
-		Len:     1,
-		Commits: []*PushCommit{CommitToPushCommit(commit)},
-	}
-	if err := CommitRepoAction(CommitRepoActionOptions{
-		PusherName:  doer.Name,
-		RepoOwnerID: repo.MustOwner().ID,
-		RepoName:    repo.Name,
-		RefFullName: git.BRANCH_PREFIX + opts.NewBranch,
-		OldCommitID: opts.LastCommitID,
-		NewCommitID: commit.ID.String(),
-		Commits:     pushCommits,
-	}); err != nil {
-		log.Error(2, "CommitRepoAction: %v", err)
-		return nil
-	}
-
-	go AddTestPullRequestTask(doer, repo.ID, opts.NewBranch, true)
 	return nil
 }
 
@@ -348,19 +333,19 @@ func NewUpload(name string, buf []byte, file multipart.File) (_ *Upload, err err
 
 	localPath := upload.LocalPath()
 	if err = os.MkdirAll(path.Dir(localPath), os.ModePerm); err != nil {
-		return nil, fmt.Errorf("MkdirAll: %v", err)
+		return nil, fmt.Errorf("mkdir all: %v", err)
 	}
 
 	fw, err := os.Create(localPath)
 	if err != nil {
-		return nil, fmt.Errorf("Create: %v", err)
+		return nil, fmt.Errorf("create: %v", err)
 	}
 	defer fw.Close()
 
 	if _, err = fw.Write(buf); err != nil {
-		return nil, fmt.Errorf("Write: %v", err)
+		return nil, fmt.Errorf("write: %v", err)
 	} else if _, err = io.Copy(fw, file); err != nil {
-		return nil, fmt.Errorf("Copy: %v", err)
+		return nil, fmt.Errorf("copy: %v", err)
 	}
 
 	if _, err := x.Insert(upload); err != nil {
@@ -434,11 +419,11 @@ func DeleteUploadByUUID(uuid string) error {
 		if IsErrUploadNotExist(err) {
 			return nil
 		}
-		return fmt.Errorf("GetUploadByUUID: %v", err)
+		return fmt.Errorf("get upload by UUID[%s]: %v", uuid, err)
 	}
 
 	if err := DeleteUpload(upload); err != nil {
-		return fmt.Errorf("DeleteUpload: %v", err)
+		return fmt.Errorf("delete upload: %v", err)
 	}
 
 	return nil
@@ -450,7 +435,7 @@ type UploadRepoFileOptions struct {
 	NewBranch    string
 	TreePath     string
 	Message      string
-	Files        []string // In UUID format.
+	Files        []string // In UUID format
 }
 
 func (repo *Repository) UploadRepoFiles(doer *User, opts UploadRepoFileOptions) (err error) {
@@ -460,21 +445,21 @@ func (repo *Repository) UploadRepoFiles(doer *User, opts UploadRepoFileOptions)
 
 	uploads, err := GetUploadsByUUIDs(opts.Files)
 	if err != nil {
-		return fmt.Errorf("GetUploadsByUUIDs [uuids: %v]: %v", opts.Files, err)
+		return fmt.Errorf("get uploads by UUIDs[%v]: %v", opts.Files, err)
 	}
 
 	repoWorkingPool.CheckIn(com.ToStr(repo.ID))
 	defer repoWorkingPool.CheckOut(com.ToStr(repo.ID))
 
 	if err = repo.DiscardLocalRepoBranchChanges(opts.OldBranch); err != nil {
-		return fmt.Errorf("DiscardLocalRepoBranchChanges [branch: %s]: %v", opts.OldBranch, err)
+		return fmt.Errorf("discard local repo branch[%s] changes: %v", opts.OldBranch, err)
 	} else if err = repo.UpdateLocalCopyBranch(opts.OldBranch); err != nil {
-		return fmt.Errorf("UpdateLocalCopyBranch [branch: %s]: %v", opts.OldBranch, err)
+		return fmt.Errorf("update local copy branch[%s]: %v", opts.OldBranch, err)
 	}
 
 	if opts.OldBranch != opts.NewBranch {
 		if err = repo.CheckoutNewBranch(opts.OldBranch, opts.NewBranch); err != nil {
-			return fmt.Errorf("CheckoutNewBranch [old_branch: %s, new_branch: %s]: %v", opts.OldBranch, opts.NewBranch, err)
+			return fmt.Errorf("checkout new branch[%s] from old branch[%s]: %v", opts.NewBranch, opts.OldBranch, err)
 		}
 	}
 
@@ -491,7 +476,7 @@ func (repo *Repository) UploadRepoFiles(doer *User, opts UploadRepoFileOptions)
 		}
 
 		if err = com.Copy(tmpPath, targetPath); err != nil {
-			return fmt.Errorf("Copy: %v", err)
+			return fmt.Errorf("copy: %v", err)
 		}
 	}
 
@@ -501,40 +486,18 @@ func (repo *Repository) UploadRepoFiles(doer *User, opts UploadRepoFileOptions)
 		Committer: doer.NewGitSig(),
 		Message:   opts.Message,
 	}); err != nil {
-		return fmt.Errorf("CommitChanges: %v", err)
-	} else if err = git.Push(localPath, "origin", opts.NewBranch); err != nil {
+		return fmt.Errorf("commit changes on %q: %v", localPath, err)
+	} else if err = git.PushWithEnvs(localPath, "origin", opts.NewBranch,
+		ComposeHookEnvs(ComposeHookEnvsOptions{
+			AuthUser:  doer,
+			OwnerName: repo.MustOwner().Name,
+			OwnerSalt: repo.MustOwner().Salt,
+			RepoID:    repo.ID,
+			RepoName:  repo.Name,
+			RepoPath:  repo.RepoPath(),
+		})); err != nil {
 		return fmt.Errorf("git push origin %s: %v", opts.NewBranch, err)
 	}
 
-	gitRepo, err := git.OpenRepository(repo.RepoPath())
-	if err != nil {
-		log.Error(2, "OpenRepository: %v", err)
-		return nil
-	}
-	commit, err := gitRepo.GetBranchCommit(opts.NewBranch)
-	if err != nil {
-		log.Error(2, "GetBranchCommit [branch: %s]: %v", opts.NewBranch, err)
-		return nil
-	}
-
-	// Simulate push event.
-	pushCommits := &PushCommits{
-		Len:     1,
-		Commits: []*PushCommit{CommitToPushCommit(commit)},
-	}
-	if err := CommitRepoAction(CommitRepoActionOptions{
-		PusherName:  doer.Name,
-		RepoOwnerID: repo.MustOwner().ID,
-		RepoName:    repo.Name,
-		RefFullName: git.BRANCH_PREFIX + opts.NewBranch,
-		OldCommitID: opts.LastCommitID,
-		NewCommitID: commit.ID.String(),
-		Commits:     pushCommits,
-	}); err != nil {
-		log.Error(2, "CommitRepoAction: %v", err)
-		return nil
-	}
-
-	go AddTestPullRequestTask(doer, repo.ID, opts.NewBranch, true)
 	return DeleteUploads(uploads...)
 }

+ 4 - 0
pkg/context/context.go

@@ -72,6 +72,10 @@ func (c *Context) RequireAutosize() {
 	c.Require("Autosize")
 }
 
+func (c *Context) RequireDropzone() {
+	c.Require("Dropzone")
+}
+
 // FormErr sets "Err_xxx" field in template data.
 func (c *Context) FormErr(names ...string) {
 	for i := range names {

+ 16 - 17
routes/repo/editor.go

@@ -89,7 +89,7 @@ func editFile(c *context.Context, isNewFile bool) {
 		buf = append(buf, d...)
 		if err, content := template.ToUTF8WithErr(buf); err != nil {
 			if err != nil {
-				log.Error(2, "ToUTF8WithErr: %v", err)
+				log.Error(2, "Failed to convert encoding to UTF-8: %v", err)
 			}
 			c.Data["FileContent"] = string(buf)
 		} else {
@@ -324,18 +324,18 @@ func DiffPreviewPost(c *context.Context, f form.EditPreviewDiff) {
 }
 
 func DeleteFile(c *context.Context) {
-	c.Data["PageIsDelete"] = true
+	c.PageIs("Delete")
 	c.Data["BranchLink"] = c.Repo.RepoLink + "/src/" + c.Repo.BranchName
 	c.Data["TreePath"] = c.Repo.TreePath
 	c.Data["commit_summary"] = ""
 	c.Data["commit_message"] = ""
 	c.Data["commit_choice"] = "direct"
 	c.Data["new_branch_name"] = ""
-	c.HTML(200, DELETE_FILE)
+	c.Success(DELETE_FILE)
 }
 
 func DeleteFilePost(c *context.Context, f form.DeleteRepoFile) {
-	c.Data["PageIsDelete"] = true
+	c.PageIs("Delete")
 	c.Data["BranchLink"] = c.Repo.RepoLink + "/src/" + c.Repo.BranchName
 	c.Data["TreePath"] = c.Repo.TreePath
 
@@ -351,13 +351,13 @@ func DeleteFilePost(c *context.Context, f form.DeleteRepoFile) {
 	c.Data["new_branch_name"] = branchName
 
 	if c.HasError() {
-		c.HTML(200, DELETE_FILE)
+		c.Success(DELETE_FILE)
 		return
 	}
 
 	if oldBranchName != branchName {
 		if _, err := c.Repo.Repository.GetBranch(branchName); err == nil {
-			c.Data["Err_NewBranchName"] = true
+			c.FormErr("NewBranchName")
 			c.RenderWithErr(c.Tr("repo.editor.branch_already_exists", branchName), DELETE_FILE, &f)
 			return
 		}
@@ -380,7 +380,7 @@ func DeleteFilePost(c *context.Context, f form.DeleteRepoFile) {
 		TreePath:     c.Repo.TreePath,
 		Message:      message,
 	}); err != nil {
-		c.Handle(500, "DeleteRepoFile", err)
+		c.ServerError("DeleteRepoFile", err)
 		return
 	}
 
@@ -393,14 +393,14 @@ func DeleteFilePost(c *context.Context, f form.DeleteRepoFile) {
 }
 
 func renderUploadSettings(c *context.Context) {
-	c.Data["RequireDropzone"] = true
+	c.RequireDropzone()
 	c.Data["UploadAllowedTypes"] = strings.Join(setting.Repository.Upload.AllowedTypes, ",")
 	c.Data["UploadMaxSize"] = setting.Repository.Upload.FileMaxSize
 	c.Data["UploadMaxFiles"] = setting.Repository.Upload.MaxFiles
 }
 
 func UploadFile(c *context.Context) {
-	c.Data["PageIsUpload"] = true
+	c.PageIs("Upload")
 	renderUploadSettings(c)
 
 	treeNames, treePaths := getParentTreeFields(c.Repo.TreePath)
@@ -416,12 +416,11 @@ func UploadFile(c *context.Context) {
 	c.Data["commit_message"] = ""
 	c.Data["commit_choice"] = "direct"
 	c.Data["new_branch_name"] = ""
-
-	c.HTML(200, UPLOAD_FILE)
+	c.Success(UPLOAD_FILE)
 }
 
 func UploadFilePost(c *context.Context, f form.UploadRepoFile) {
-	c.Data["PageIsUpload"] = true
+	c.PageIs("Upload")
 	renderUploadSettings(c)
 
 	oldBranchName := c.Repo.BranchName
@@ -448,13 +447,13 @@ func UploadFilePost(c *context.Context, f form.UploadRepoFile) {
 	c.Data["new_branch_name"] = branchName
 
 	if c.HasError() {
-		c.HTML(200, UPLOAD_FILE)
+		c.Success(UPLOAD_FILE)
 		return
 	}
 
 	if oldBranchName != branchName {
 		if _, err := c.Repo.Repository.GetBranch(branchName); err == nil {
-			c.Data["Err_NewBranchName"] = true
+			c.FormErr("NewBranchName")
 			c.RenderWithErr(c.Tr("repo.editor.branch_already_exists", branchName), UPLOAD_FILE, &f)
 			return
 		}
@@ -470,13 +469,13 @@ func UploadFilePost(c *context.Context, f form.UploadRepoFile) {
 				break
 			}
 
-			c.Handle(500, "Repo.Commit.GetTreeEntryByPath", err)
+			c.ServerError("GetTreeEntryByPath", err)
 			return
 		}
 
 		// User can only upload files to a directory.
 		if !entry.IsDir() {
-			c.Data["Err_TreePath"] = true
+			c.FormErr("TreePath")
 			c.RenderWithErr(c.Tr("repo.editor.directory_is_a_file", part), UPLOAD_FILE, &f)
 			return
 		}
@@ -500,7 +499,7 @@ func UploadFilePost(c *context.Context, f form.UploadRepoFile) {
 		Message:      message,
 		Files:        f.Files,
 	}); err != nil {
-		c.Data["Err_TreePath"] = true
+		c.FormErr("TreePath")
 		c.RenderWithErr(c.Tr("repo.editor.unable_to_upload_files", f.TreePath, err), UPLOAD_FILE, &f)
 		return
 	}

+ 1 - 37
routes/repo/http.go

@@ -17,7 +17,6 @@ import (
 	"strings"
 	"time"
 
-	"github.com/Unknwon/com"
 	log "gopkg.in/clog.v1"
 	"gopkg.in/macaron.v1"
 
@@ -28,17 +27,6 @@ import (
 	"github.com/gogs/gogs/pkg/tool"
 )
 
-const (
-	ENV_AUTH_USER_ID           = "GOGS_AUTH_USER_ID"
-	ENV_AUTH_USER_NAME         = "GOGS_AUTH_USER_NAME"
-	ENV_AUTH_USER_EMAIL        = "GOGS_AUTH_USER_EMAIL"
-	ENV_REPO_OWNER_NAME        = "GOGS_REPO_OWNER_NAME"
-	ENV_REPO_OWNER_SALT_MD5    = "GOGS_REPO_OWNER_SALT_MD5"
-	ENV_REPO_ID                = "GOGS_REPO_ID"
-	ENV_REPO_NAME              = "GOGS_REPO_NAME"
-	ENV_REPO_CUSTOM_HOOKS_PATH = "GOGS_REPO_CUSTOM_HOOKS_PATH"
-)
-
 type HTTPContext struct {
 	*context.Context
 	OwnerName string
@@ -228,30 +216,6 @@ func (h *serviceHandler) sendFile(contentType string) {
 	http.ServeFile(h.w, h.r, reqFile)
 }
 
-type ComposeHookEnvsOptions struct {
-	AuthUser  *models.User
-	OwnerName string
-	OwnerSalt string
-	RepoID    int64
-	RepoName  string
-	RepoPath  string
-}
-
-func ComposeHookEnvs(opts ComposeHookEnvsOptions) []string {
-	envs := []string{
-		"SSH_ORIGINAL_COMMAND=1",
-		ENV_AUTH_USER_ID + "=" + com.ToStr(opts.AuthUser.ID),
-		ENV_AUTH_USER_NAME + "=" + opts.AuthUser.Name,
-		ENV_AUTH_USER_EMAIL + "=" + opts.AuthUser.Email,
-		ENV_REPO_OWNER_NAME + "=" + opts.OwnerName,
-		ENV_REPO_OWNER_SALT_MD5 + "=" + tool.MD5(opts.OwnerSalt),
-		ENV_REPO_ID + "=" + com.ToStr(opts.RepoID),
-		ENV_REPO_NAME + "=" + opts.RepoName,
-		ENV_REPO_CUSTOM_HOOKS_PATH + "=" + path.Join(opts.RepoPath, "custom_hooks"),
-	}
-	return envs
-}
-
 func serviceRPC(h serviceHandler, service string) {
 	defer h.r.Body.Close()
 
@@ -279,7 +243,7 @@ func serviceRPC(h serviceHandler, service string) {
 	var stderr bytes.Buffer
 	cmd := exec.Command("git", service, "--stateless-rpc", h.dir)
 	if service == "receive-pack" {
-		cmd.Env = append(os.Environ(), ComposeHookEnvs(ComposeHookEnvsOptions{
+		cmd.Env = append(os.Environ(), models.ComposeHookEnvs(models.ComposeHookEnvsOptions{
 			AuthUser:  h.authUser,
 			OwnerName: h.ownerName,
 			OwnerSalt: h.ownerSalt,

+ 1 - 1
templates/.VERSION

@@ -1 +1 @@
-0.11.62.0817
+0.11.63.0817