fix: restore the git head ref when running repo:gc

When git --aggressive is run on a bare repo, it deletes all head refs. This change copies the contents into memory and then writes them out at the end of the repo:gc call.

Closes #6973
This commit is contained in:
Jose Diaz-Gonzalez
2025-03-08 23:00:43 -05:00
parent 07bcc67597
commit da166bc537
2 changed files with 50 additions and 21 deletions

View File

@@ -2,6 +2,8 @@ package repo
import (
"fmt"
"os"
"path/filepath"
"github.com/dokku/dokku/plugins/common"
)
@@ -45,3 +47,50 @@ func PurgeCache(appName string) error {
return nil
}
func RepoGc(appName string) error {
heads := map[string][]byte{}
headsDir := filepath.Join(common.AppRoot(appName), "refs", "heads")
if common.DirectoryExists(headsDir) {
headFiles, err := os.ReadDir(headsDir)
if err != nil {
return fmt.Errorf("Unable to read heads directory: %w", err)
}
for _, head := range headFiles {
if head.IsDir() {
continue
}
headContents, err := os.ReadFile(filepath.Join(headsDir, head.Name()))
if err != nil {
return fmt.Errorf("Unable to read head file: %w", err)
}
heads[head.Name()] = headContents
}
}
defer func() {
for head, contents := range heads {
if err := os.WriteFile(filepath.Join(headsDir, head), contents, 0644); err != nil {
common.LogWarn(fmt.Sprintf("Unable to write head file: %s\n", err))
}
}
}()
appRoot := common.AppRoot(appName)
result, err := common.CallExecCommand(common.ExecCommandInput{
Command: "git",
Args: []string{"gc", "--aggressive"},
Env: map[string]string{
"GIT_DIR": appRoot,
},
StreamStderr: true,
})
if err != nil {
return fmt.Errorf("Unable to run git gc: %w", err)
}
if result.ExitCode != 0 {
return fmt.Errorf("Unable to run git gc: %s", result.StderrContents())
}
return nil
}

View File

@@ -1,8 +1,6 @@
package repo
import (
"fmt"
"github.com/dokku/dokku/plugins/common"
)
@@ -12,25 +10,7 @@ func CommandGc(appName string) error {
return err
}
appRoot := common.AppRoot(appName)
cmdEnv := map[string]string{
"GIT_DIR": appRoot,
}
result, err := common.CallExecCommand(common.ExecCommandInput{
Command: "git",
Args: []string{"gc", "--aggressive"},
Env: cmdEnv,
StreamStdio: true,
})
if err != nil {
return fmt.Errorf("Unable to run git gc: %w", err)
}
if result.ExitCode != 0 {
return fmt.Errorf("Unable to run git gc: %s", result.StderrContents())
}
return nil
return RepoGc(appName)
}
// CommandPurgeCache deletes the contents of the build cache stored in the repository