diff options
author | Thibault Jamet <tjamet@users.noreply.github.com> | 2021-05-26 14:19:07 +0200 |
---|---|---|
committer | Thibault Jamet <tjamet@users.noreply.github.com> | 2021-10-28 21:48:32 +0200 |
commit | 617ae9f34f46b440f59979cdfc8a399e36decc32 (patch) | |
tree | 5df11cb3a89b88e51ca924feb35d579c06ff6c71 /remote.go | |
parent | 99457e570d34320b12fb4fcd0f054f3d0b1d3eec (diff) | |
download | go-git-617ae9f34f46b440f59979cdfc8a399e36decc32.tar.gz |
Add support to push commits per hashes
Using plain git, the command `git push ${sha}:refs/heads/some-branch`
actually ensures that the remote branch `some-branch` points to the
commit `${sha}`.
In the current version of go-git, this results in an "everything is
up to date" error.
When a source reference is not found, check the object storage to find
the sha. If it is found, consider pushing this exact commit.
fixes: #105
Diffstat (limited to 'remote.go')
-rw-r--r-- | remote.go | 41 |
1 files changed, 41 insertions, 0 deletions
@@ -602,6 +602,10 @@ func (r *Remote) addOrUpdateReferences( if !rs.IsWildcard() { ref, ok := refsDict[rs.Src()] if !ok { + commit, err := object.GetCommit(r.s, plumbing.NewHash(rs.Src())) + if err == nil { + return r.addCommit(rs, remoteRefs, commit.Hash, req) + } return nil } @@ -656,6 +660,43 @@ func (r *Remote) deleteReferences(rs config.RefSpec, }) } +func (r *Remote) addCommit(rs config.RefSpec, + remoteRefs storer.ReferenceStorer, localCommit plumbing.Hash, + req *packp.ReferenceUpdateRequest) error { + + if rs.IsWildcard() { + return errors.New("can't use wildcard together with hash refspecs") + } + + cmd := &packp.Command{ + Name: rs.Dst(""), + Old: plumbing.ZeroHash, + New: localCommit, + } + remoteRef, err := remoteRefs.Reference(cmd.Name) + if err == nil { + if remoteRef.Type() != plumbing.HashReference { + //TODO: check actual git behavior here + return nil + } + + cmd.Old = remoteRef.Hash() + } else if err != plumbing.ErrReferenceNotFound { + return err + } + if cmd.Old == cmd.New { + return nil + } + if !rs.IsForceUpdate() { + if err := checkFastForwardUpdate(r.s, remoteRefs, cmd); err != nil { + return err + } + } + + req.Commands = append(req.Commands, cmd) + return nil +} + func (r *Remote) addReferenceIfRefSpecMatches(rs config.RefSpec, remoteRefs storer.ReferenceStorer, localRef *plumbing.Reference, req *packp.ReferenceUpdateRequest) error { |