diff options
author | Nick Thomas <nick@gitlab.com> | 2017-07-22 09:50:40 +0100 |
---|---|---|
committer | Jeremy Stribling <strib@alum.mit.edu> | 2017-11-27 11:38:14 -0800 |
commit | 702718fd59be0aa4b8bf8492403c465107ca17af (patch) | |
tree | 00724b2409b9dee0f9fe5fc6b86d9da2cf91f0ce /remote.go | |
parent | 147a1b7d2e8a08d5c6228de0f98b3f5a1497f95a (diff) | |
download | go-git-702718fd59be0aa4b8bf8492403c465107ca17af.tar.gz |
Support non-force fetches
Diffstat (limited to 'remote.go')
-rw-r--r-- | remote.go | 28 |
1 files changed, 26 insertions, 2 deletions
@@ -25,6 +25,7 @@ import ( var ( NoErrAlreadyUpToDate = errors.New("already up-to-date") ErrDeleteRefNotSupported = errors.New("server does not support delete-refs") + ErrForceNeeded = errors.New("some refs were not updated") ) const ( @@ -302,7 +303,7 @@ func (r *Remote) fetch(ctx context.Context, o *FetchOptions) (storer.ReferenceSt } } - updated, err := r.updateLocalReferenceStorage(o.RefSpecs, refs, remoteRefs, o.Tags) + updated, err := r.updateLocalReferenceStorage(o.RefSpecs, refs, remoteRefs, o.Tags, o.Force) if err != nil { return nil, err } @@ -773,8 +774,11 @@ func (r *Remote) updateLocalReferenceStorage( specs []config.RefSpec, fetchedRefs, remoteRefs memory.ReferenceStorage, tagMode TagMode, + force bool, ) (updated bool, err error) { isWildcard := true + forceNeeded := false + for _, spec := range specs { if !spec.IsWildcard() { isWildcard = false @@ -789,7 +793,23 @@ func (r *Remote) updateLocalReferenceStorage( continue } - new := plumbing.NewHashReference(spec.Dst(ref.Name()), ref.Hash()) + localName := spec.Dst(ref.Name()) + old, _ := storer.ResolveReference(r.s, localName) + new := plumbing.NewHashReference(localName, ref.Hash()) + + // If the ref exists locally as a branch and force is not specified, + // only update if the new ref is an ancestor of the old + if old != nil && old.Name().IsBranch() && !force { + ff, err := isFastForward(r.s, old.Hash(), new.Hash()) + if err != nil { + return updated, err + } + + if !ff { + forceNeeded = true + continue + } + } refUpdated, err := updateReferenceStorerIfNeeded(r.s, new) if err != nil { @@ -819,6 +839,10 @@ func (r *Remote) updateLocalReferenceStorage( updated = true } + if err == nil && forceNeeded { + err = ErrForceNeeded + } + return } |