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