2020-10-31 05:59:02 +08:00
// Copyright 2020 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package repository
import (
2022-01-19 23:26:57 +00:00
"context"
2020-10-31 05:59:02 +08:00
"strings"
2021-12-10 09:27:50 +08:00
repo_model "code.gitea.io/gitea/models/repo"
2020-10-31 05:59:02 +08:00
"code.gitea.io/gitea/modules/git"
)
// PushUpdateOptions defines the push update options
type PushUpdateOptions struct {
PusherID int64
PusherName string
RepoUserName string
RepoName string
RefFullName string // branch, tag or other name to push
OldCommitID string
NewCommitID string
}
// IsNewRef return true if it's a first-time push to a branch, tag or etc.
2021-11-24 09:08:13 +00:00
func ( opts * PushUpdateOptions ) IsNewRef ( ) bool {
2020-10-31 05:59:02 +08:00
return opts . OldCommitID == git . EmptySHA
}
// IsDelRef return true if it's a deletion to a branch or tag
2021-11-24 09:08:13 +00:00
func ( opts * PushUpdateOptions ) IsDelRef ( ) bool {
2020-10-31 05:59:02 +08:00
return opts . NewCommitID == git . EmptySHA
}
// IsUpdateRef return true if it's an update operation
2021-11-24 09:08:13 +00:00
func ( opts * PushUpdateOptions ) IsUpdateRef ( ) bool {
2020-10-31 05:59:02 +08:00
return ! opts . IsNewRef ( ) && ! opts . IsDelRef ( )
}
// IsTag return true if it's an operation to a tag
2021-11-24 09:08:13 +00:00
func ( opts * PushUpdateOptions ) IsTag ( ) bool {
2020-10-31 05:59:02 +08:00
return strings . HasPrefix ( opts . RefFullName , git . TagPrefix )
}
// IsNewTag return true if it's a creation to a tag
2021-11-24 09:08:13 +00:00
func ( opts * PushUpdateOptions ) IsNewTag ( ) bool {
2020-10-31 05:59:02 +08:00
return opts . IsTag ( ) && opts . IsNewRef ( )
}
// IsDelTag return true if it's a deletion to a tag
2021-11-24 09:08:13 +00:00
func ( opts * PushUpdateOptions ) IsDelTag ( ) bool {
2020-10-31 05:59:02 +08:00
return opts . IsTag ( ) && opts . IsDelRef ( )
}
// IsBranch return true if it's a push to branch
2021-11-24 09:08:13 +00:00
func ( opts * PushUpdateOptions ) IsBranch ( ) bool {
2020-10-31 05:59:02 +08:00
return strings . HasPrefix ( opts . RefFullName , git . BranchPrefix )
}
// IsNewBranch return true if it's the first-time push to a branch
2021-11-24 09:08:13 +00:00
func ( opts * PushUpdateOptions ) IsNewBranch ( ) bool {
2020-10-31 05:59:02 +08:00
return opts . IsBranch ( ) && opts . IsNewRef ( )
}
// IsUpdateBranch return true if it's not the first push to a branch
2021-11-24 09:08:13 +00:00
func ( opts * PushUpdateOptions ) IsUpdateBranch ( ) bool {
2020-10-31 05:59:02 +08:00
return opts . IsBranch ( ) && opts . IsUpdateRef ( )
}
// IsDelBranch return true if it's a deletion to a branch
2021-11-24 09:08:13 +00:00
func ( opts * PushUpdateOptions ) IsDelBranch ( ) bool {
2020-10-31 05:59:02 +08:00
return opts . IsBranch ( ) && opts . IsDelRef ( )
}
// TagName returns simple tag name if it's an operation to a tag
2021-11-24 09:08:13 +00:00
func ( opts * PushUpdateOptions ) TagName ( ) string {
2020-10-31 05:59:02 +08:00
return opts . RefFullName [ len ( git . TagPrefix ) : ]
}
// BranchName returns simple branch name if it's an operation to branch
2021-11-24 09:08:13 +00:00
func ( opts * PushUpdateOptions ) BranchName ( ) string {
2020-10-31 05:59:02 +08:00
return opts . RefFullName [ len ( git . BranchPrefix ) : ]
}
// RefName returns simple name for ref
2021-11-24 09:08:13 +00:00
func ( opts * PushUpdateOptions ) RefName ( ) string {
2020-10-31 05:59:02 +08:00
if strings . HasPrefix ( opts . RefFullName , git . TagPrefix ) {
return opts . RefFullName [ len ( git . TagPrefix ) : ]
} else if strings . HasPrefix ( opts . RefFullName , git . BranchPrefix ) {
return opts . RefFullName [ len ( git . BranchPrefix ) : ]
}
return ""
}
// RepoFullName returns repo full name
2021-11-24 09:08:13 +00:00
func ( opts * PushUpdateOptions ) RepoFullName ( ) string {
2020-10-31 05:59:02 +08:00
return opts . RepoUserName + "/" + opts . RepoName
}
// IsForcePush detect if a push is a force push
2022-01-19 23:26:57 +00:00
func IsForcePush ( ctx context . Context , opts * PushUpdateOptions ) ( bool , error ) {
2020-10-31 05:59:02 +08:00
if ! opts . IsUpdateBranch ( ) {
return false , nil
}
2022-04-01 10:55:30 +08:00
output , _ , err := git . NewCommand ( ctx , "rev-list" , "--max-count=1" , opts . OldCommitID , "^" + opts . NewCommitID ) .
RunStdString ( & git . RunOpts { Dir : repo_model . RepoPath ( opts . RepoUserName , opts . RepoName ) } )
2020-10-31 05:59:02 +08:00
if err != nil {
return false , err
} else if len ( output ) > 0 {
return true , nil
}
return false , nil
}