diff --git a/internal/git/updateref/updateref.go b/internal/git/updateref/updateref.go index 7230acc05e4b48cdcabbd35f05766817eed98584..f820986262e8e91b2f11087cd06e706a51476e98 100644 --- a/internal/git/updateref/updateref.go +++ b/internal/git/updateref/updateref.go @@ -65,6 +65,20 @@ func New(ctx context.Context, repo repository.GitRepo, opts ...UpdaterOpt) (*Upd return &Updater{repo: repo, cmd: cmd}, nil } +// CreateUpdateDelete dispatches to Create()/Update()/Delete() as needed +// +// The underlying "update-ref" does the same dispatching depending on +// what it get passed. +func (u *Updater) CreateUpdateDelete(ref, newvalue, oldvalue string) error { + if newvalue == git.NullSHA { + return u.Delete(ref, oldvalue) + } else if oldvalue == git.NullSHA { + return u.Create(ref, newvalue) + } else { + return u.Update(ref, newvalue, oldvalue) + } +} + // Create commands the reference to be created with the sha specified in value func (u *Updater) Create(ref, value string) error { _, err := fmt.Fprintf(u.cmd, "create %s\x00%s\x00", ref, value) @@ -79,8 +93,8 @@ func (u *Updater) Update(ref, newvalue, oldvalue string) error { } // Delete commands the reference to be removed from the repository -func (u *Updater) Delete(ref string) error { - _, err := fmt.Fprintf(u.cmd, "delete %s\x00\x00", ref) +func (u *Updater) Delete(ref string, oldvalue string) error { + _, err := fmt.Fprintf(u.cmd, "delete %s\x00%s\x00", ref, oldvalue) return err } diff --git a/internal/git/updateref/updateref_test.go b/internal/git/updateref/updateref_test.go index 270c04de340cb41969ff52bda5fadc622efde980..ba6074a2754e51ad64d900dd982545f8eeceb173 100644 --- a/internal/git/updateref/updateref_test.go +++ b/internal/git/updateref/updateref_test.go @@ -105,7 +105,9 @@ func TestDelete(t *testing.T) { ref := "refs/heads/feature" - require.NoError(t, updater.Delete(ref)) + refValue, err := git.NewRepository(testRepo).GetReference(ctx, ref) + require.NoError(t, err) + require.NoError(t, updater.Delete(ref, refValue.Target)) require.NoError(t, updater.Wait()) // check the ref was removed diff --git a/internal/gitaly/service/cleanup/internalrefs/cleaner.go b/internal/gitaly/service/cleanup/internalrefs/cleaner.go index 8e75649da86ea0e95209cfad6096b4236931e836..85f4c763bb624478cd2b9b858226406797a3cfb7 100644 --- a/internal/gitaly/service/cleanup/internalrefs/cleaner.go +++ b/internal/gitaly/service/cleanup/internalrefs/cleaner.go @@ -117,7 +117,7 @@ func (c *Cleaner) processEntry(ctx context.Context, oldSHA, newSHA string) error // Remove the internal refs pointing to oldSHA for _, ref := range refs { - if err := c.updater.Delete(ref); err != nil { + if err := c.updater.Delete(ref, git.NullSHA); err != nil { return err } } diff --git a/internal/gitaly/service/operations/update_with_hooks.go b/internal/gitaly/service/operations/update_with_hooks.go index 134466236228747bf5ecedee5a0deb26e8041abc..f14be027b139c6db75d7e6524d1db914da618b01 100644 --- a/internal/gitaly/service/operations/update_with_hooks.go +++ b/internal/gitaly/service/operations/update_with_hooks.go @@ -81,7 +81,7 @@ func (s *Server) updateReferenceWithHooks(ctx context.Context, repo *gitalypb.Re return err } - if err := updater.Update(reference, newrev, oldrev); err != nil { + if err := updater.CreateUpdateDelete(reference, newrev, oldrev); err != nil { return err } diff --git a/internal/gitaly/service/ref/delete_refs.go b/internal/gitaly/service/ref/delete_refs.go index 6444c5743a04937cbe5b6a6d2f5fc98d1503b259..c4d7716901e642a77f87b7f8f42a895066e9ee40 100644 --- a/internal/gitaly/service/ref/delete_refs.go +++ b/internal/gitaly/service/ref/delete_refs.go @@ -34,7 +34,7 @@ func (s *server) DeleteRefs(ctx context.Context, in *gitalypb.DeleteRefsRequest) } for _, ref := range refnames { - if err := updater.Delete(ref); err != nil { + if err := updater.Delete(ref, git.NullSHA); err != nil { return &gitalypb.DeleteRefsResponse{GitError: err.Error()}, nil } }