From 702718fd59be0aa4b8bf8492403c465107ca17af Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Sat, 22 Jul 2017 09:50:40 +0100 Subject: Support non-force fetches --- remote.go | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'remote.go') diff --git a/remote.go b/remote.go index 2416152..91ae2fa 100644 --- a/remote.go +++ b/remote.go @@ -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 } -- cgit From 3834e571da171844efecc4e26fd89082419079a1 Mon Sep 17 00:00:00 2001 From: Taru Karttunen Date: Tue, 12 Sep 2017 19:06:47 +0300 Subject: Use optionally locking when updating refs --- remote.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'remote.go') diff --git a/remote.go b/remote.go index 91ae2fa..ca93916 100644 --- a/remote.go +++ b/remote.go @@ -811,7 +811,7 @@ func (r *Remote) updateLocalReferenceStorage( } } - refUpdated, err := updateReferenceStorerIfNeeded(r.s, new) + refUpdated, err := checkAndUpdateReferenceStorerIfNeeded(r.s, new, old) if err != nil { return updated, err } -- cgit From 77482f9ac6095ad4a863e348ab1ac9bf9ab2e0b2 Mon Sep 17 00:00:00 2001 From: Taru Karttunen Date: Tue, 19 Sep 2017 14:29:01 +0300 Subject: Fetch - honor per refspec force flag --- remote.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'remote.go') diff --git a/remote.go b/remote.go index ca93916..81d0ede 100644 --- a/remote.go +++ b/remote.go @@ -799,7 +799,7 @@ func (r *Remote) updateLocalReferenceStorage( // 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 { + if old != nil && old.Name().IsBranch() && !force && !spec.IsForceUpdate() { ff, err := isFastForward(r.s, old.Hash(), new.Hash()) if err != nil { return updated, err -- cgit