Skip to content

Instantly share code, notes, and snippets.

@ags313
Created June 29, 2022 23:02
Show Gist options
  • Save ags313/9ef404f4f5377122449ed4f7c197efcb to your computer and use it in GitHub Desktop.
Save ags313/9ef404f4f5377122449ed4f7c197efcb to your computer and use it in GitHub Desktop.
Update git repositories recursively
package main
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path"
"path/filepath"
"sync"
)
const MAX_DEPTH = 5
const PARALLELISM = 10
func main() {
directory, _ := os.Getwd()
if len(os.Args) > 1 {
directory = os.Args[1]
}
f, _ := os.Stat(directory)
if !f.IsDir() {
os.Exit(1)
}
fmt.Println("Starting in: ", directory)
abs, _ := filepath.Abs(directory)
fmt.Println("abc", abs)
wg := sync.WaitGroup{}
ch := make(chan string, PARALLELISM)
descend(abs, 0, &wg, &ch)
wg.Wait()
}
func descend(parent string, depth int, wg *sync.WaitGroup, ch *chan string) {
wg.Add(1)
parentFileInfo, _ := os.Stat(parent)
if depth < MAX_DEPTH && parentFileInfo.IsDir() {
children, _ := ioutil.ReadDir(parent)
for _, file := range children {
absChild := path.Join(parent, file.Name())
if file.IsDir() {
maybeGit := path.Join(absChild, ".git")
gitFileInfo, err := os.Stat(maybeGit)
if err == nil && gitFileInfo.IsDir() {
// update git, stop
go update(absChild, wg, ch)
} else {
descend(absChild, depth+1, wg, ch)
}
}
}
}
wg.Done()
}
func update(workDir string, wg *sync.WaitGroup, ch *chan string) {
wg.Add(1)
*ch <- "asd"
gitDir := path.Join(workDir, ".git")
gitDirParam := fmt.Sprintf("--git-dir=%s", gitDir)
workDirParam := fmt.Sprintf("--work-tree=%s", workDir)
executeCommand(exec.Command("/usr/local/bin/git", gitDirParam, workDirParam, "fetch", "--all", "--prune"), gitDir)
executeCommand(exec.Command("/usr/local/bin/git", gitDirParam, workDirParam, "pull", "--prune"), gitDir)
wg.Done()
<-*ch
}
func executeCommand(cmd *exec.Cmd, gitDir string) {
var stdOut bytes.Buffer
var stdErr bytes.Buffer
cmd.Stdout = &stdOut
cmd.Stderr = &stdErr
err := cmd.Run()
if err != nil {
fmt.Println(gitDir, "\n", cmd.String(), stdOut.String(), "\n", stdErr.String())
} else {
fmt.Println(gitDir, "\n", cmd.String(), stdOut.String(), "\n", stdErr.String())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment