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 {
Id int64
Uuid string ` xorm:"index" `
RefName string
OldCommitId string
NewCommitId string
}
2014-09-22 16:25:39 +04:00
const (
MAX_COMMITS int = 5
)
2014-06-28 19:56:41 +04:00
func AddUpdateTask ( task * UpdateTask ) error {
_ , err := x . Insert ( task )
return err
}
func GetUpdateTasksByUuid ( uuid string ) ( [ ] * UpdateTask , error ) {
task := & UpdateTask {
Uuid : uuid ,
}
tasks := make ( [ ] * UpdateTask , 0 )
err := x . Find ( & tasks , task )
if err != nil {
return nil , err
}
return tasks , nil
}
func DelUpdateTasksByUuid ( uuid string ) error {
_ , err := x . Delete ( & UpdateTask { Uuid : uuid } )
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 ,
2014-08-26 16:20:18 +04: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 {
return fmt . Errorf ( "Find CommitsBefore erro: %v" , err )
}
} else {
l , err = newCommit . CommitsBeforeUntil ( oldCommitId )
if err != nil {
return fmt . Errorf ( "Find CommitsBeforeUntil erro: %v" , err )
}
}
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 )
2014-06-28 10:55:33 +04:00
2014-04-11 06:27:13 +04:00
if actEmail == "" {
actEmail = commit . Committer . Email
}
commits = append ( commits ,
2014-04-13 05:35:36 +04:00
& base . PushCommit { commit . Id . String ( ) ,
2014-04-11 06:27:13 +04:00
commit . Message ( ) ,
commit . Author . Email ,
commit . Author . Name } )
2014-09-22 16:25:39 +04:00
if len ( commits ) >= MAX_COMMITS {
2014-04-11 06:27:13 +04:00
break
}
}
2014-05-03 09:37:49 +04:00
if err = CommitRepoAction ( userId , ru . Id , userName , actEmail ,
2014-10-11 05:40:51 +04: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
}