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:
@@ -2,6 +2,8 @@ package repo
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/dokku/dokku/plugins/common"
|
"github.com/dokku/dokku/plugins/common"
|
||||||
)
|
)
|
||||||
@@ -45,3 +47,50 @@ func PurgeCache(appName string) error {
|
|||||||
|
|
||||||
return nil
|
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
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package repo
|
package repo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/dokku/dokku/plugins/common"
|
"github.com/dokku/dokku/plugins/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -12,25 +10,7 @@ func CommandGc(appName string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
appRoot := common.AppRoot(appName)
|
return RepoGc(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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommandPurgeCache deletes the contents of the build cache stored in the repository
|
// CommandPurgeCache deletes the contents of the build cache stored in the repository
|
||||||
|
|||||||
Reference in New Issue
Block a user