Skip to content

Commit 6d8103d

Browse files
authored
Merge pull request go-git#71 from kappyhappy/master
Remote.Push: support force option
2 parents 838eb29 + b5b511a commit 6d8103d

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-1
lines changed

options.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ import (
66
"strings"
77
"time"
88

9-
"golang.org/x/crypto/openpgp"
109
"github.com/go-git/go-git/v5/config"
1110
"github.com/go-git/go-git/v5/plumbing"
1211
"github.com/go-git/go-git/v5/plumbing/object"
1312
"github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband"
1413
"github.com/go-git/go-git/v5/plumbing/transport"
14+
"golang.org/x/crypto/openpgp"
1515
)
1616

1717
// SubmoduleRescursivity defines how depth will affect any submodule recursive
@@ -190,6 +190,9 @@ type PushOptions struct {
190190
// Prune specify that remote refs that match given RefSpecs and that do
191191
// not exist locally will be removed.
192192
Prune bool
193+
// Force allows the push to update a remote branch even when the local
194+
// branch does not descend from it.
195+
Force bool
193196
}
194197

195198
// Validate validates the fields and sets the default values.

remote.go

+9
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,15 @@ func (r *Remote) PushContext(ctx context.Context, o *PushOptions) (err error) {
123123
return ErrDeleteRefNotSupported
124124
}
125125

126+
if o.Force {
127+
for i := 0; i < len(o.RefSpecs); i++ {
128+
rs := &o.RefSpecs[i]
129+
if !rs.IsForceUpdate() {
130+
o.RefSpecs[i] = config.RefSpec("+" + rs.String())
131+
}
132+
}
133+
}
134+
126135
localRefs, err := r.references()
127136
if err != nil {
128137
return err

remote_test.go

+28
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,34 @@ func (s *RemoteSuite) TestPushForce(c *C) {
612612
c.Assert(newRef, Not(DeepEquals), oldRef)
613613
}
614614

615+
func (s *RemoteSuite) TestPushForceWithOption(c *C) {
616+
f := fixtures.Basic().One()
617+
sto := filesystem.NewStorage(f.DotGit(), cache.NewObjectLRUDefault())
618+
619+
dstFs := f.DotGit()
620+
dstSto := filesystem.NewStorage(dstFs, cache.NewObjectLRUDefault())
621+
622+
url := dstFs.Root()
623+
r := NewRemote(sto, &config.RemoteConfig{
624+
Name: DefaultRemoteName,
625+
URLs: []string{url},
626+
})
627+
628+
oldRef, err := dstSto.Reference(plumbing.ReferenceName("refs/heads/branch"))
629+
c.Assert(err, IsNil)
630+
c.Assert(oldRef, NotNil)
631+
632+
err = r.Push(&PushOptions{
633+
RefSpecs: []config.RefSpec{"refs/heads/master:refs/heads/branch"},
634+
Force: true,
635+
})
636+
c.Assert(err, IsNil)
637+
638+
newRef, err := dstSto.Reference(plumbing.ReferenceName("refs/heads/branch"))
639+
c.Assert(err, IsNil)
640+
c.Assert(newRef, Not(DeepEquals), oldRef)
641+
}
642+
615643
func (s *RemoteSuite) TestPushPrune(c *C) {
616644
fs := fixtures.Basic().One().DotGit()
617645
url := c.MkDir()

0 commit comments

Comments
 (0)