aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--options.go5
-rw-r--r--remote.go9
-rw-r--r--remote_test.go28
3 files changed, 41 insertions, 1 deletions
diff --git a/options.go b/options.go
index a147f58..2a9727c 100644
--- a/options.go
+++ b/options.go
@@ -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.
diff --git a/remote.go b/remote.go
index 98c4acf..e642c57 100644
--- a/remote.go
+++ b/remote.go
@@ -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()