@@ -11,11 +11,13 @@ const (
1111 refSpecWildcard = "*"
1212 refSpecForce = "+"
1313 refSpecSeparator = ":"
14+ refSpecNegative = "^"
1415)
1516
1617var (
1718 ErrRefSpecMalformedSeparator = errors .New ("malformed refspec, separators are wrong" )
1819 ErrRefSpecMalformedWildcard = errors .New ("malformed refspec, mismatched number of wildcards" )
20+ ErrRefSpecMalformedNegative = errors .New ("malformed negative refspec, one ^ and no separators allowed" )
1921)
2022
2123// RefSpec is a mapping from local branches to remote references.
@@ -31,6 +33,24 @@ type RefSpec string
3133// Validate validates the RefSpec
3234func (s RefSpec ) Validate () error {
3335 spec := string (s )
36+
37+ if strings .Index (spec , refSpecNegative ) == 0 {
38+ // This is a negative refspec
39+ if strings .Count (spec , refSpecNegative ) != 1 {
40+ return ErrRefSpecMalformedNegative
41+ }
42+
43+ if strings .Count (spec , refSpecSeparator ) != 0 {
44+ return ErrRefSpecMalformedNegative
45+ }
46+
47+ if strings .Count (spec , refSpecWildcard ) > 1 {
48+ return ErrRefSpecMalformedWildcard
49+ }
50+
51+ return nil
52+ }
53+
3454 if strings .Count (spec , refSpecSeparator ) != 1 {
3555 return ErrRefSpecMalformedSeparator
3656 }
@@ -64,12 +84,17 @@ func (s RefSpec) IsExactSHA1() bool {
6484 return plumbing .IsHash (s .Src ())
6585}
6686
87+ // IsNegative returns if the refspec is a negative one
88+ func (s RefSpec ) IsNegative () bool {
89+ return s [0 ] == refSpecNegative [0 ]
90+ }
91+
6792// Src return the src side.
6893func (s RefSpec ) Src () string {
6994 spec := string (s )
7095
7196 var start int
72- if s .IsForceUpdate () {
97+ if s .IsForceUpdate () || s . IsNegative () {
7398 start = 1
7499 } else {
75100 start = 0
0 commit comments