2014-04-27 11:05:13 +04:00
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
2014-04-11 06:27:13 +04:00
package models
import (
"container/list"
2014-06-24 00:22:34 +04:00
"fmt"
2014-04-11 06:27:13 +04:00
"os/exec"
"strings"
2016-11-10 19:24:48 +03:00
"code.gitea.io/git"
2015-12-10 04:46:05 +03:00
2016-11-10 19:24:48 +03:00
"code.gitea.io/gitea/modules/log"
2014-04-11 06:27:13 +04:00
)
2017-02-25 17:54:40 +03:00
// env keys for git hooks need
const (
EnvRepoName = "GITEA_REPO_NAME"
EnvRepoUsername = "GITEA_REPO_USER_NAME"
EnvRepoUserSalt = "GITEA_REPO_USER_SALT"
EnvRepoIsWiki = "GITEA_REPO_IS_WIKI"
EnvPusherName = "GITEA_PUSHER_NAME"
EnvPusherID = "GITEA_PUSHER_ID"
)
2014-06-28 19:56:41 +04:00
2016-08-12 12:29:29 +03:00
// CommitToPushCommit transforms a git.Commit to PushCommit type.
func CommitToPushCommit ( commit * git . Commit ) * PushCommit {
return & PushCommit {
Sha1 : commit . ID . String ( ) ,
Message : commit . Message ( ) ,
AuthorEmail : commit . Author . Email ,
AuthorName : commit . Author . Name ,
CommitterEmail : commit . Committer . Email ,
CommitterName : commit . Committer . Name ,
Timestamp : commit . Author . When ,
}
}
2016-11-25 00:35:47 +03:00
// ListToPushCommits transforms a list.List to PushCommits type.
2015-12-10 04:46:05 +03:00
func ListToPushCommits ( l * list . List ) * PushCommits {
2016-11-29 16:05:26 +03:00
var commits [ ] * PushCommit
2015-12-10 04:46:05 +03:00
var actEmail string
for e := l . Front ( ) ; e != nil ; e = e . Next ( ) {
commit := e . Value . ( * git . Commit )
if actEmail == "" {
actEmail = commit . Committer . Email
}
2016-08-12 12:29:29 +03:00
commits = append ( commits , CommitToPushCommit ( commit ) )
2015-12-10 04:46:05 +03:00
}
return & PushCommits { l . Len ( ) , commits , "" , nil }
}
2016-11-25 00:35:47 +03:00
// PushUpdateOptions defines the push update options
2016-02-18 06:47:06 +03:00
type PushUpdateOptions struct {
PusherID int64
PusherName string
RepoUserName string
RepoName string
2016-08-17 09:06:38 +03:00
RefFullName string
OldCommitID string
NewCommitID string
2016-02-18 06:47:06 +03:00
}
// PushUpdate must be called for any push actions in order to
// generates necessary push action history feeds.
2017-05-04 08:42:02 +03:00
func PushUpdate ( opts PushUpdateOptions ) ( repo * Repository , err error ) {
2016-12-22 12:30:52 +03:00
isNewRef := opts . OldCommitID == git . EmptySHA
isDelRef := opts . NewCommitID == git . EmptySHA
2016-02-18 06:47:06 +03:00
if isNewRef && isDelRef {
2017-05-04 08:42:02 +03:00
return nil , fmt . Errorf ( "Old and new revisions are both %s" , git . EmptySHA )
2014-04-11 06:27:13 +04:00
}
2016-02-18 06:47:06 +03:00
repoPath := RepoPath ( opts . RepoUserName , opts . RepoName )
2014-04-11 06:27:13 +04:00
gitUpdate := exec . Command ( "git" , "update-server-info" )
2016-02-18 06:47:06 +03:00
gitUpdate . Dir = repoPath
if err = gitUpdate . Run ( ) ; err != nil {
2017-05-04 08:42:02 +03:00
return nil , fmt . Errorf ( "Failed to call 'git update-server-info': %v" , err )
2016-02-18 06:47:06 +03:00
}
2014-04-11 06:27:13 +04:00
2017-05-04 08:42:02 +03:00
owner , err := GetUserByName ( opts . RepoUserName )
if err != nil {
return nil , fmt . Errorf ( "GetUserByName: %v" , err )
2014-05-03 07:12:15 +04:00
}
2017-05-04 08:42:02 +03:00
repo , err = GetRepositoryByName ( owner . ID , opts . RepoName )
2014-04-11 06:27:13 +04:00
if err != nil {
2017-05-04 08:42:02 +03:00
return nil , fmt . Errorf ( "GetRepositoryByName: %v" , err )
2014-04-11 06:27:13 +04:00
}
2017-05-04 08:42:02 +03:00
if isDelRef {
log . GitLogger . Info ( "Reference '%s' has been deleted from '%s/%s' by %s" ,
opts . RefFullName , opts . RepoUserName , opts . RepoName , opts . PusherName )
return repo , nil
2014-05-03 09:37:49 +04:00
}
2017-05-04 08:42:02 +03:00
gitRepo , err := git . OpenRepository ( repoPath )
2014-04-11 06:27:13 +04:00
if err != nil {
2017-05-04 08:42:02 +03:00
return nil , fmt . Errorf ( "OpenRepository: %v" , err )
2014-04-11 06:27:13 +04:00
}
2017-04-11 16:30:15 +03:00
if err = repo . UpdateSize ( ) ; err != nil {
log . Error ( 4 , "Failed to update size for repository: %v" , err )
}
2014-07-26 08:24:27 +04:00
// Push tags.
2016-12-22 12:30:52 +03:00
if strings . HasPrefix ( opts . RefFullName , git . TagPrefix ) {
2016-08-17 09:06:38 +03:00
if err := CommitRepoAction ( CommitRepoActionOptions {
PusherName : opts . PusherName ,
RepoOwnerID : owner . ID ,
RepoName : repo . Name ,
RefFullName : opts . RefFullName ,
OldCommitID : opts . OldCommitID ,
NewCommitID : opts . NewCommitID ,
Commits : & PushCommits { } ,
} ) ; err != nil {
2017-05-04 08:42:02 +03:00
return nil , fmt . Errorf ( "CommitRepoAction (tag): %v" , err )
2014-06-28 10:55:33 +04:00
}
2017-05-04 08:42:02 +03:00
return repo , nil
2014-06-28 10:55:33 +04:00
}
2016-02-18 06:47:06 +03:00
newCommit , err := gitRepo . GetCommit ( opts . NewCommitID )
2014-06-28 19:56:41 +04:00
if err != nil {
2017-05-04 08:42:02 +03:00
return nil , fmt . Errorf ( "gitRepo.GetCommit: %v" , err )
2014-06-28 19:56:41 +04:00
}
2014-10-11 05:40:51 +04:00
// Push new branch.
2014-06-28 19:56:41 +04:00
var l * list . List
2016-02-18 06:47:06 +03:00
if isNewRef {
2015-12-11 00:27:47 +03:00
l , err = newCommit . CommitsBeforeLimit ( 10 )
2014-06-28 19:56:41 +04:00
if err != nil {
2017-05-04 08:42:02 +03:00
return nil , fmt . Errorf ( "newCommit.CommitsBeforeLimit: %v" , err )
2014-06-28 19:56:41 +04:00
}
} else {
2016-02-18 06:47:06 +03:00
l , err = newCommit . CommitsBeforeUntil ( opts . OldCommitID )
2014-06-28 19:56:41 +04:00
if err != nil {
2017-05-04 08:42:02 +03:00
return nil , fmt . Errorf ( "newCommit.CommitsBeforeUntil: %v" , err )
2014-06-28 19:56:41 +04:00
}
}
2016-08-17 09:06:38 +03:00
if err := CommitRepoAction ( CommitRepoActionOptions {
PusherName : opts . PusherName ,
RepoOwnerID : owner . ID ,
RepoName : repo . Name ,
RefFullName : opts . RefFullName ,
OldCommitID : opts . OldCommitID ,
NewCommitID : opts . NewCommitID ,
Commits : ListToPushCommits ( l ) ,
} ) ; err != nil {
2017-05-04 08:42:02 +03:00
return nil , fmt . Errorf ( "CommitRepoAction (branch): %v" , err )
2014-04-11 06:27:13 +04:00
}
2017-05-04 08:42:02 +03:00
return repo , nil
2014-04-11 06:27:13 +04:00
}