2014-04-27 01:05:13 -06: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 10:27:13 +08:00
package models
import (
"container/list"
2014-06-23 16:22:34 -04:00
"fmt"
2014-04-11 10:27:13 +08:00
"os/exec"
"strings"
2015-12-09 20:46:05 -05:00
"github.com/gogits/git-shell"
2014-06-20 01:14:54 -04:00
"github.com/gogits/gogs/modules/log"
2014-04-11 10:27:13 +08:00
)
2014-06-28 23:56:41 +08:00
type UpdateTask struct {
2015-10-24 03:36:47 -04:00
ID int64 ` xorm:"pk autoincr" `
UUID string ` xorm:"index" `
2014-06-28 23:56:41 +08:00
RefName string
2015-10-24 03:36:47 -04:00
OldCommitID string
NewCommitID string
2014-06-28 23:56:41 +08:00
}
func AddUpdateTask ( task * UpdateTask ) error {
_ , err := x . Insert ( task )
return err
}
2015-11-04 21:57:10 -05:00
// GetUpdateTaskByUUID returns update task by given UUID.
2015-10-24 03:36:47 -04:00
func GetUpdateTaskByUUID ( uuid string ) ( * UpdateTask , error ) {
2014-06-28 23:56:41 +08:00
task := & UpdateTask {
2015-10-24 03:36:47 -04:00
UUID : uuid ,
2014-06-28 23:56:41 +08:00
}
2015-10-24 03:36:47 -04:00
has , err := x . Get ( task )
2014-06-28 23:56:41 +08:00
if err != nil {
return nil , err
2015-10-24 03:36:47 -04:00
} else if ! has {
2015-11-04 21:57:10 -05:00
return nil , ErrUpdateTaskNotExist { uuid }
2014-06-28 23:56:41 +08:00
}
2015-10-24 03:36:47 -04:00
return task , nil
2014-06-28 23:56:41 +08:00
}
2015-10-24 03:36:47 -04:00
func DeleteUpdateTaskByUUID ( uuid string ) error {
_ , err := x . Delete ( & UpdateTask { UUID : uuid } )
2014-06-28 23:56:41 +08:00
return err
}
2015-12-09 20:46:05 -05:00
func ListToPushCommits ( l * list . List ) * PushCommits {
commits := make ( [ ] * PushCommit , 0 )
var actEmail string
for e := l . Front ( ) ; e != nil ; e = e . Next ( ) {
commit := e . Value . ( * git . Commit )
if actEmail == "" {
actEmail = commit . Committer . Email
}
commits = append ( commits ,
& PushCommit { commit . ID . String ( ) ,
commit . Message ( ) ,
commit . Author . Email ,
commit . Author . Name ,
} )
}
return & PushCommits { l . Len ( ) , commits , "" , nil }
}
2015-11-05 19:18:59 -05:00
func Update ( refName , oldCommitID , newCommitID , userName , repoUserName , repoName string , userID int64 ) error {
isNew := strings . HasPrefix ( oldCommitID , "0000000" )
2014-04-11 10:27:13 +08:00
if isNew &&
2015-11-05 19:18:59 -05:00
strings . HasPrefix ( newCommitID , "0000000" ) {
2014-06-23 16:22:34 -04:00
return fmt . Errorf ( "old rev and new rev both 000000" )
2014-04-11 10:27:13 +08:00
}
2014-05-03 01:37:49 -04:00
f := RepoPath ( repoUserName , repoName )
2014-04-11 10:27:13 +08:00
gitUpdate := exec . Command ( "git" , "update-server-info" )
gitUpdate . Dir = f
gitUpdate . Run ( )
2015-11-05 19:18:59 -05:00
isDel := strings . HasPrefix ( newCommitID , "0000000" )
2014-05-03 11:12:15 +08:00
if isDel {
2015-11-05 19:18:59 -05:00
log . GitLogger . Info ( "del rev" , refName , "from" , userName + "/" + repoName + ".git" , "by" , userID )
2014-06-23 16:22:34 -04:00
return nil
2014-05-03 11:12:15 +08:00
}
2015-11-05 19:18:59 -05:00
gitRepo , err := git . OpenRepository ( f )
2014-04-11 10:27:13 +08:00
if err != nil {
2014-06-23 16:22:34 -04:00
return fmt . Errorf ( "runUpdate.Open repoId: %v" , err )
2014-04-11 10:27:13 +08:00
}
2015-11-05 19:18:59 -05:00
user , err := GetUserByName ( repoUserName )
2014-05-03 01:37:49 -04:00
if err != nil {
2014-06-23 16:22:34 -04:00
return fmt . Errorf ( "runUpdate.GetUserByName: %v" , err )
2014-05-03 01:37:49 -04:00
}
2015-11-05 19:18:59 -05:00
repo , err := GetRepositoryByName ( user . Id , repoName )
2014-04-11 10:27:13 +08:00
if err != nil {
2014-06-23 16:22:34 -04:00
return fmt . Errorf ( "runUpdate.GetRepositoryByName userId: %v" , err )
2014-04-11 10:27:13 +08:00
}
2014-07-26 00:24:27 -04:00
// Push tags.
2014-06-28 14:55:33 +08:00
if strings . HasPrefix ( refName , "refs/tags/" ) {
tagName := git . RefEndName ( refName )
2015-11-05 19:18:59 -05:00
tag , err := gitRepo . GetTag ( tagName )
2014-06-28 14:55:33 +08:00
if err != nil {
2014-07-26 00:24:27 -04:00
log . GitLogger . Fatal ( 4 , "runUpdate.GetTag: %v" , err )
2014-06-28 14:55:33 +08:00
}
var actEmail string
if tag . Tagger != nil {
actEmail = tag . Tagger . Email
} else {
cmt , err := tag . Commit ( )
if err != nil {
2014-07-26 00:24:27 -04:00
log . GitLogger . Fatal ( 4 , "runUpdate.GetTag Commit: %v" , err )
2014-06-28 14:55:33 +08:00
}
actEmail = cmt . Committer . Email
}
2015-11-13 17:10:25 -05:00
commit := & PushCommits { }
2014-06-28 14:55:33 +08:00
2015-11-05 19:18:59 -05:00
if err = CommitRepoAction ( userID , user . Id , userName , actEmail ,
repo . ID , repoUserName , repoName , refName , commit , oldCommitID , newCommitID ) ; err != nil {
2014-10-10 21:40:51 -04:00
log . GitLogger . Fatal ( 4 , "CommitRepoAction: %s/%s:%v" , repoUserName , repoName , err )
2014-06-28 14:55:33 +08:00
}
2014-06-28 15:00:03 +08:00
return err
2014-06-28 14:55:33 +08:00
}
2015-11-05 19:18:59 -05:00
newCommit , err := gitRepo . GetCommit ( newCommitID )
2014-06-28 23:56:41 +08:00
if err != nil {
return fmt . Errorf ( "runUpdate GetCommit of newCommitId: %v" , err )
}
2014-10-10 21:40:51 -04:00
// Push new branch.
2014-06-28 23:56:41 +08:00
var l * list . List
if isNew {
l , err = newCommit . CommitsBefore ( )
if err != nil {
2015-10-23 10:31:13 -04:00
return fmt . Errorf ( "CommitsBefore: %v" , err )
2014-06-28 23:56:41 +08:00
}
} else {
2015-11-05 19:18:59 -05:00
l , err = newCommit . CommitsBeforeUntil ( oldCommitID )
2014-06-28 23:56:41 +08:00
if err != nil {
2015-10-23 10:31:13 -04:00
return fmt . Errorf ( "CommitsBeforeUntil: %v" , err )
2014-06-28 23:56:41 +08:00
}
}
if err != nil {
return fmt . Errorf ( "runUpdate.Commit repoId: %v" , err )
}
2015-12-09 20:46:05 -05:00
if err = CommitRepoAction ( userID , user . Id , userName , user . Email ,
repo . ID , repoUserName , repoName , refName , ListToPushCommits ( l ) , oldCommitID , newCommitID ) ; err != nil {
2014-06-23 16:22:34 -04:00
return fmt . Errorf ( "runUpdate.models.CommitRepoAction: %s/%s:%v" , repoUserName , repoName , err )
2014-04-11 10:27:13 +08:00
}
2014-06-23 16:22:34 -04:00
return nil
2014-04-11 10:27:13 +08:00
}