diff --git a/options.go b/options.go index 283435b56..d6f0e9f11 100644 --- a/options.go +++ b/options.go @@ -232,6 +232,8 @@ type PushOptions struct { ForceWithLease *ForceWithLease // PushOptions sets options to be transferred to the server during push. Options map[string]string + // Atomic sets option to be an atomic push + Atomic bool } // ForceWithLease sets fields on the lease diff --git a/plumbing/protocol/packp/updreq_encode_test.go b/plumbing/protocol/packp/updreq_encode_test.go index 6ba004310..4370b794f 100644 --- a/plumbing/protocol/packp/updreq_encode_test.go +++ b/plumbing/protocol/packp/updreq_encode_test.go @@ -170,3 +170,22 @@ func (s *UpdReqEncodeSuite) TestPushOptions(c *C) { s.testEncode(c, r, expected) } + +func (s *UpdReqEncodeSuite) TestPushAtomic(c *C) { + hash1 := plumbing.NewHash("1ecf0ef2c2dffb796033e5a02219af86ec6584e5") + hash2 := plumbing.NewHash("2ecf0ef2c2dffb796033e5a02219af86ec6584e5") + name := plumbing.ReferenceName("myref") + + r := NewReferenceUpdateRequest() + r.Capabilities.Set(capability.Atomic) + r.Commands = []*Command{ + {Name: name, Old: hash1, New: hash2}, + } + + expected := pktlines(c, + "1ecf0ef2c2dffb796033e5a02219af86ec6584e5 2ecf0ef2c2dffb796033e5a02219af86ec6584e5 myref\x00atomic", + pktline.FlushString, + ) + + s.testEncode(c, r, expected) +} diff --git a/remote.go b/remote.go index fecdebf4e..0299f9c7d 100644 --- a/remote.go +++ b/remote.go @@ -326,7 +326,12 @@ func (r *Remote) newReferenceUpdateRequest( } } + if o.Atomic && ar.Capabilities.Supports(capability.Atomic) { + _ = req.Capabilities.Set(capability.Atomic) + } + if err := r.addReferencesToUpdate(o.RefSpecs, localRefs, remoteRefs, req, o.Prune, o.ForceWithLease); err != nil { + return nil, err }