From 2b40cdaf60b33a1f302e773d0d527c771d20e0a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=BD=D0=B0=D0=B1?= Date: Thu, 30 Jul 2020 18:00:20 +0200 Subject: [PATCH] Add default-branch-updating logic to post-update hook If the default branch doesn't exist, it will now try to pick another branch from this push; if none exist, it will set it to the first branch in iteration order This, for the very most part, DWIMs, is a no-op for repos with "master" branches, and a one-time first-push update for repos that use a different default name Similarly, "git push origin :trunk trunk:new-trunk" should behave as expected, changing the default branch from trunk to new-trunk --- gitsrht-update-hook/post-update.go | 46 ++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/gitsrht-update-hook/post-update.go b/gitsrht-update-hook/post-update.go index 296cafa..1021efc 100644 --- a/gitsrht-update-hook/post-update.go +++ b/gitsrht-update-hook/post-update.go @@ -14,6 +14,7 @@ import ( "gopkg.in/src-d/go-git.v4" "gopkg.in/src-d/go-git.v4/plumbing" "gopkg.in/src-d/go-git.v4/plumbing/object" + "gopkg.in/src-d/go-git.v4/plumbing/storer" ) func printAutocreateInfo(context PushContext) { @@ -268,6 +269,51 @@ func postUpdate() { } } + // Check if HEAD's dangling (i.e. the default branch doesn't exist) + // if so, try to find a branch from this push to set as the default + // if none were found, set the first branch in iteration order as default + head, err := repo.Reference("HEAD", false) + if err != nil { + logger.Fatalf("repo.Reference(\"HEAD\"): %v", err) + } + + danglingHead := false + if _, err = repo.Reference(head.Target(), false); err != nil { + danglingHead = true + } + + if danglingHead { + logger.Printf("HEAD dangling at %s", head.Target()) + + cbk := func(ref *plumbing.Reference) error { + if ref == nil { + return nil + } + + logger.Printf("Setting HEAD to %s", ref.Name()) + log.Printf("Default branch updated to %s", ref.Name()[len("refs/heads/"):]) + repo.Storer.SetReference(plumbing.NewSymbolicReference("HEAD", ref.Name())) + danglingHead = false + return storer.ErrStop + } + for _, refName := range refs { + if !strings.HasPrefix(refName, "refs/heads/") { + continue + } + + ref, _ := repo.Reference(plumbing.ReferenceName(refName), false) + if cbk(ref) != nil { + break + } + } + + if danglingHead { + if branches, _ := repo.Branches(); branches != nil { + branches.ForEach(cbk) + } + } + } + payloadBytes, err := json.Marshal(&payload) if err != nil { logger.Fatalf("Failed to marshal webhook payload: %v", err) -- 2.38.4