diff options
-rw-r--r-- | options.go | 5 | ||||
-rw-r--r-- | remote.go | 9 | ||||
-rw-r--r-- | remote_test.go | 28 |
3 files changed, 41 insertions, 1 deletions
@@ -6,12 +6,12 @@ import ( "strings" "time" - "golang.org/x/crypto/openpgp" "github.com/go-git/go-git/v5/config" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/object" "github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband" "github.com/go-git/go-git/v5/plumbing/transport" + "golang.org/x/crypto/openpgp" ) // SubmoduleRescursivity defines how depth will affect any submodule recursive @@ -190,6 +190,9 @@ type PushOptions struct { // Prune specify that remote refs that match given RefSpecs and that do // not exist locally will be removed. Prune bool + // Force allows the push to update a remote branch even when the local + // branch does not descend from it. + Force bool } // Validate validates the fields and sets the default values. @@ -123,6 +123,15 @@ func (r *Remote) PushContext(ctx context.Context, o *PushOptions) (err error) { return ErrDeleteRefNotSupported } + if o.Force { + for i := 0; i < len(o.RefSpecs); i++ { + rs := &o.RefSpecs[i] + if !rs.IsForceUpdate() { + o.RefSpecs[i] = config.RefSpec("+" + rs.String()) + } + } + } + localRefs, err := r.references() if err != nil { return err diff --git a/remote_test.go b/remote_test.go index 0fc3449..ce46390 100644 --- a/remote_test.go +++ b/remote_test.go @@ -612,6 +612,34 @@ func (s *RemoteSuite) TestPushForce(c *C) { c.Assert(newRef, Not(DeepEquals), oldRef) } +func (s *RemoteSuite) TestPushForceWithOption(c *C) { + f := fixtures.Basic().One() + sto := filesystem.NewStorage(f.DotGit(), cache.NewObjectLRUDefault()) + + dstFs := f.DotGit() + dstSto := filesystem.NewStorage(dstFs, cache.NewObjectLRUDefault()) + + url := dstFs.Root() + r := NewRemote(sto, &config.RemoteConfig{ + Name: DefaultRemoteName, + URLs: []string{url}, + }) + + oldRef, err := dstSto.Reference(plumbing.ReferenceName("refs/heads/branch")) + c.Assert(err, IsNil) + c.Assert(oldRef, NotNil) + + err = r.Push(&PushOptions{ + RefSpecs: []config.RefSpec{"refs/heads/master:refs/heads/branch"}, + Force: true, + }) + c.Assert(err, IsNil) + + newRef, err := dstSto.Reference(plumbing.ReferenceName("refs/heads/branch")) + c.Assert(err, IsNil) + c.Assert(newRef, Not(DeepEquals), oldRef) +} + func (s *RemoteSuite) TestPushPrune(c *C) { fs := fixtures.Basic().One().DotGit() url := c.MkDir() |