aboutsummaryrefslogtreecommitdiffstats
path: root/remote.go
diff options
context:
space:
mode:
authorThibault Jamet <tjamet@users.noreply.github.com>2021-05-26 14:19:07 +0200
committerThibault Jamet <tjamet@users.noreply.github.com>2021-10-28 21:48:32 +0200
commit617ae9f34f46b440f59979cdfc8a399e36decc32 (patch)
tree5df11cb3a89b88e51ca924feb35d579c06ff6c71 /remote.go
parent99457e570d34320b12fb4fcd0f054f3d0b1d3eec (diff)
downloadgo-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.go41
1 files changed, 41 insertions, 0 deletions
diff --git a/remote.go b/remote.go
index 9f2995d..b74f431 100644
--- a/remote.go
+++ b/remote.go
@@ -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 {