mirror of
https://github.com/therootcompany/golib.git
synced 2026-04-24 20:58:00 +00:00
refactor: GCInterval replaces LightGC; Sync/Init drop lightGC param
gitshallow.Repo.GCInterval int: 0 (default) = git auto gc (no explicit call) N = aggressive gc + prune every Nth successful pull GC() simplified to always aggressive+prune (the only mode we use). Sync(), Init(), Fetch() all parameter-free; GCInterval baked into Repo.
This commit is contained in:
parent
10c4b6dbc3
commit
7c0cd26da1
@ -57,7 +57,7 @@ func main() {
|
|||||||
|
|
||||||
repo := gitshallow.New(url, absPath, defaultDepth, defaultBranch)
|
repo := gitshallow.New(url, absPath, defaultDepth, defaultBranch)
|
||||||
|
|
||||||
updated, err := repo.Sync(false)
|
updated, err := repo.Sync()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Sync failed: %v\n", err)
|
fmt.Fprintf(os.Stderr, "Sync failed: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
|||||||
@ -15,9 +15,15 @@ type Repo struct {
|
|||||||
Path string
|
Path string
|
||||||
Depth int // 0 defaults to 1, -1 for all
|
Depth int // 0 defaults to 1, -1 for all
|
||||||
Branch string // Optional: specific branch to clone/pull
|
Branch string // Optional: specific branch to clone/pull
|
||||||
LightGC bool // true = skip aggressive GC; false (default) = aggressive+prune
|
|
||||||
|
// GCInterval controls explicit aggressive GC after pulls.
|
||||||
|
// 0 (default) — no explicit gc; git runs gc.auto on its own schedule
|
||||||
|
// 1 — aggressive gc after every pull
|
||||||
|
// N — aggressive gc after every Nth pull
|
||||||
|
GCInterval int
|
||||||
|
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
|
pullCount int
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new Repo instance.
|
// New creates a new Repo instance.
|
||||||
@ -35,23 +41,20 @@ func New(url, path string, depth int, branch string) *Repo {
|
|||||||
|
|
||||||
// Init clones the repo if missing, then syncs once.
|
// Init clones the repo if missing, then syncs once.
|
||||||
// Returns whether anything new was fetched.
|
// Returns whether anything new was fetched.
|
||||||
func (r *Repo) Init(lightGC bool) (bool, error) {
|
func (r *Repo) Init() (bool, error) {
|
||||||
gitDir := filepath.Join(r.Path, ".git")
|
gitDir := filepath.Join(r.Path, ".git")
|
||||||
if _, err := os.Stat(gitDir); err != nil {
|
if _, err := os.Stat(gitDir); err != nil {
|
||||||
if _, err := r.Clone(); err != nil {
|
if _, err := r.Clone(); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return r.syncGit()
|
||||||
updated, err := r.syncGit(lightGC)
|
|
||||||
return updated, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clone performs a shallow clone (--depth N --single-branch --no-tags).
|
// Clone performs a shallow clone (--depth N --single-branch --no-tags).
|
||||||
func (r *Repo) Clone() (bool, error) {
|
func (r *Repo) Clone() (bool, error) {
|
||||||
r.mu.Lock()
|
r.mu.Lock()
|
||||||
defer r.mu.Unlock()
|
defer r.mu.Unlock()
|
||||||
|
|
||||||
return r.clone()
|
return r.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +62,6 @@ func (r *Repo) clone() (bool, error) {
|
|||||||
if r.exists() {
|
if r.exists() {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.URL == "" {
|
if r.URL == "" {
|
||||||
return false, fmt.Errorf("repository URL is required")
|
return false, fmt.Errorf("repository URL is required")
|
||||||
}
|
}
|
||||||
@ -93,18 +95,15 @@ func (r *Repo) exists() bool {
|
|||||||
// runGit executes a git command in the repo directory (or parent for clone).
|
// runGit executes a git command in the repo directory (or parent for clone).
|
||||||
func (r *Repo) runGit(args ...string) (string, error) {
|
func (r *Repo) runGit(args ...string) (string, error) {
|
||||||
cmd := exec.Command("git", args...)
|
cmd := exec.Command("git", args...)
|
||||||
|
|
||||||
if _, err := os.Stat(r.Path); err == nil && r.exists() {
|
if _, err := os.Stat(r.Path); err == nil && r.exists() {
|
||||||
cmd.Dir = r.Path
|
cmd.Dir = r.Path
|
||||||
} else {
|
} else {
|
||||||
cmd.Dir = filepath.Dir(r.Path)
|
cmd.Dir = filepath.Dir(r.Path)
|
||||||
}
|
}
|
||||||
|
|
||||||
output, err := cmd.CombinedOutput()
|
output, err := cmd.CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("git %s failed: %v\n%s", strings.Join(args, " "), err, output)
|
return "", fmt.Errorf("git %s failed: %v\n%s", strings.Join(args, " "), err, output)
|
||||||
}
|
}
|
||||||
|
|
||||||
return strings.TrimSpace(string(output)), nil
|
return strings.TrimSpace(string(output)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,7 +111,6 @@ func (r *Repo) runGit(args ...string) (string, error) {
|
|||||||
func (r *Repo) Pull() (updated bool, err error) {
|
func (r *Repo) Pull() (updated bool, err error) {
|
||||||
r.mu.Lock()
|
r.mu.Lock()
|
||||||
defer r.mu.Unlock()
|
defer r.mu.Unlock()
|
||||||
|
|
||||||
return r.pull()
|
return r.pull()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,47 +142,36 @@ func (r *Repo) pull() (updated bool, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return oldHead != newHead, nil
|
return oldHead != newHead, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GC runs git gc. aggressiveGC adds --aggressive; pruneNow adds --prune=now.
|
// GC runs git gc --aggressive --prune=now.
|
||||||
func (r *Repo) GC(aggressiveGC, pruneNow bool) error {
|
func (r *Repo) GC() error {
|
||||||
r.mu.Lock()
|
r.mu.Lock()
|
||||||
defer r.mu.Unlock()
|
defer r.mu.Unlock()
|
||||||
|
return r.gc()
|
||||||
return r.gc(aggressiveGC, pruneNow)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repo) gc(aggressiveGC, pruneNow bool) error {
|
func (r *Repo) gc() error {
|
||||||
if !r.exists() {
|
if !r.exists() {
|
||||||
return fmt.Errorf("repository does not exist at %s", r.Path)
|
return fmt.Errorf("repository does not exist at %s", r.Path)
|
||||||
}
|
}
|
||||||
|
_, err := r.runGit("gc", "--aggressive", "--prune=now")
|
||||||
args := []string{"gc"}
|
|
||||||
if aggressiveGC {
|
|
||||||
args = append(args, "--aggressive")
|
|
||||||
}
|
|
||||||
if pruneNow {
|
|
||||||
args = append(args, "--prune=now")
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := r.runGit(args...)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sync clones if missing, pulls, and runs GC. Returns whether HEAD changed.
|
// Sync clones if missing, pulls, and conditionally runs GC based on GCEvery.
|
||||||
// lightGC=false runs aggressive GC with --prune=now to minimize disk use.
|
// Returns whether HEAD changed.
|
||||||
func (r *Repo) Sync(lightGC bool) (bool, error) {
|
func (r *Repo) Sync() (bool, error) {
|
||||||
return r.syncGit(lightGC)
|
return r.syncGit()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch satisfies httpcache.Syncer using the Repo's LightGC setting.
|
// Fetch satisfies httpcache.Syncer.
|
||||||
func (r *Repo) Fetch() (bool, error) {
|
func (r *Repo) Fetch() (bool, error) {
|
||||||
return r.syncGit(r.LightGC)
|
return r.syncGit()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repo) syncGit(lightGC bool) (updated bool, err error) {
|
func (r *Repo) syncGit() (updated bool, err error) {
|
||||||
r.mu.Lock()
|
r.mu.Lock()
|
||||||
defer r.mu.Unlock()
|
defer r.mu.Unlock()
|
||||||
|
|
||||||
@ -199,5 +186,12 @@ func (r *Repo) syncGit(lightGC bool) (updated bool, err error) {
|
|||||||
return updated, err
|
return updated, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return true, r.gc(!lightGC, !lightGC)
|
if r.GCInterval > 0 {
|
||||||
|
r.pullCount++
|
||||||
|
if r.pullCount%r.GCInterval == 0 {
|
||||||
|
return true, r.gc()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -82,7 +82,7 @@ func (s *Sources) Fetch() (bool, error) {
|
|||||||
// For HTTP: fetches each cacher unconditionally on first run.
|
// For HTTP: fetches each cacher unconditionally on first run.
|
||||||
func (s *Sources) Init() error {
|
func (s *Sources) Init() error {
|
||||||
if s.gitRepo != nil {
|
if s.gitRepo != nil {
|
||||||
_, err := s.gitRepo.Init(s.gitRepo.LightGC)
|
_, err := s.gitRepo.Init()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, syn := range s.syncs {
|
for _, syn := range s.syncs {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user