code.gitea.io/gitea@v1.19.3/modules/repository/push.go (about)

     1  // Copyright 2020 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package repository
     5  
     6  import (
     7  	"context"
     8  	"strings"
     9  
    10  	repo_model "code.gitea.io/gitea/models/repo"
    11  	"code.gitea.io/gitea/modules/git"
    12  )
    13  
    14  // PushUpdateOptions defines the push update options
    15  type PushUpdateOptions struct {
    16  	PusherID     int64
    17  	PusherName   string
    18  	RepoUserName string
    19  	RepoName     string
    20  	RefFullName  string // branch, tag or other name to push
    21  	OldCommitID  string
    22  	NewCommitID  string
    23  }
    24  
    25  // IsNewRef return true if it's a first-time push to a branch, tag or etc.
    26  func (opts *PushUpdateOptions) IsNewRef() bool {
    27  	return opts.OldCommitID == git.EmptySHA
    28  }
    29  
    30  // IsDelRef return true if it's a deletion to a branch or tag
    31  func (opts *PushUpdateOptions) IsDelRef() bool {
    32  	return opts.NewCommitID == git.EmptySHA
    33  }
    34  
    35  // IsUpdateRef return true if it's an update operation
    36  func (opts *PushUpdateOptions) IsUpdateRef() bool {
    37  	return !opts.IsNewRef() && !opts.IsDelRef()
    38  }
    39  
    40  // IsTag return true if it's an operation to a tag
    41  func (opts *PushUpdateOptions) IsTag() bool {
    42  	return strings.HasPrefix(opts.RefFullName, git.TagPrefix)
    43  }
    44  
    45  // IsNewTag return true if it's a creation to a tag
    46  func (opts *PushUpdateOptions) IsNewTag() bool {
    47  	return opts.IsTag() && opts.IsNewRef()
    48  }
    49  
    50  // IsDelTag return true if it's a deletion to a tag
    51  func (opts *PushUpdateOptions) IsDelTag() bool {
    52  	return opts.IsTag() && opts.IsDelRef()
    53  }
    54  
    55  // IsBranch return true if it's a push to branch
    56  func (opts *PushUpdateOptions) IsBranch() bool {
    57  	return strings.HasPrefix(opts.RefFullName, git.BranchPrefix)
    58  }
    59  
    60  // IsNewBranch return true if it's the first-time push to a branch
    61  func (opts *PushUpdateOptions) IsNewBranch() bool {
    62  	return opts.IsBranch() && opts.IsNewRef()
    63  }
    64  
    65  // IsUpdateBranch return true if it's not the first push to a branch
    66  func (opts *PushUpdateOptions) IsUpdateBranch() bool {
    67  	return opts.IsBranch() && opts.IsUpdateRef()
    68  }
    69  
    70  // IsDelBranch return true if it's a deletion to a branch
    71  func (opts *PushUpdateOptions) IsDelBranch() bool {
    72  	return opts.IsBranch() && opts.IsDelRef()
    73  }
    74  
    75  // TagName returns simple tag name if it's an operation to a tag
    76  func (opts *PushUpdateOptions) TagName() string {
    77  	return opts.RefFullName[len(git.TagPrefix):]
    78  }
    79  
    80  // BranchName returns simple branch name if it's an operation to branch
    81  func (opts *PushUpdateOptions) BranchName() string {
    82  	return opts.RefFullName[len(git.BranchPrefix):]
    83  }
    84  
    85  // RefName returns simple name for ref
    86  func (opts *PushUpdateOptions) RefName() string {
    87  	if strings.HasPrefix(opts.RefFullName, git.TagPrefix) {
    88  		return opts.RefFullName[len(git.TagPrefix):]
    89  	} else if strings.HasPrefix(opts.RefFullName, git.BranchPrefix) {
    90  		return opts.RefFullName[len(git.BranchPrefix):]
    91  	}
    92  	return ""
    93  }
    94  
    95  // RepoFullName returns repo full name
    96  func (opts *PushUpdateOptions) RepoFullName() string {
    97  	return opts.RepoUserName + "/" + opts.RepoName
    98  }
    99  
   100  // IsForcePush detect if a push is a force push
   101  func IsForcePush(ctx context.Context, opts *PushUpdateOptions) (bool, error) {
   102  	if !opts.IsUpdateBranch() {
   103  		return false, nil
   104  	}
   105  
   106  	output, _, err := git.NewCommand(ctx, "rev-list", "--max-count=1").AddDynamicArguments(opts.OldCommitID, "^"+opts.NewCommitID).
   107  		RunStdString(&git.RunOpts{Dir: repo_model.RepoPath(opts.RepoUserName, opts.RepoName)})
   108  	if err != nil {
   109  		return false, err
   110  	} else if len(output) > 0 {
   111  		return true, nil
   112  	}
   113  	return false, nil
   114  }