func main() { flag.Parse() var err error switch flag.NArg() { case 0: // ok default: err = fmt.Errorf("no argument expected") utils.HandleErr(err) } unpushed := make([]string, 0, 2) // cycle all branches cmd := exec.Command( "git", "branch", "-vv", "--no-color", //"--no-merged", ) //debug(cmd) bout, err := cmd.Output() utils.HandleErr(err) lines := utils.SplitLines(bout) //printf(">>> lines:\n%v\n", lines) branch_re := regexp.MustCompile( `\* (?P<branch>.*?) (?P<hash>(\w|\d)*?) .*`, ) remote_re := regexp.MustCompile( `^(\*| ) (?P<branch>.*?) (?P<hash>(\w|\d)*?) [[](?P<remote>.*?)[]].*?`, ) ahead_re := regexp.MustCompile( `.*?: ahead \(.(?P<ahead>.*?)*\)`, ) for _, line := range lines { //printf(">>> %q\n", line) sub := branch_re.FindStringSubmatch(line) if sub == nil { continue } // printf(" sub: %q\n", strings.Join(sub, ",")) // printf(" branch=%q\n", sub[1]) // printf(" hash=%q\n", sub[2]) if remote_re.MatchString(line) { // printf(" ==> remote branch\n") continue } ahead_sub := ahead_re.FindStringSubmatch(line) if ahead_sub == nil { continue } unpushed = append( unpushed, fmt.Sprintf("branch [%v] is ahead [%s] commit(s)", sub[1], ahead_sub[1]), ) } if len(unpushed) == 0 { return } for _, msg := range unpushed { fmt.Fprintf(os.Stderr, "%s\n", msg) } if *g_exitcode { os.Exit(1) } }
func main() { flag.Parse() var err error pwd, err := os.Getwd() utils.HandleErr(err) switch flag.NArg() { case 0: // ok default: err = fmt.Errorf("no argument expected") utils.HandleErr(err) } var git *exec.Cmd if *g_ignoresub != "" { git = exec.Command( "git", "status", "--porcelain", fmt.Sprintf("--ignore-submodules=%s", *g_ignoresub), ) } else { git = exec.Command("git", "status", "--porcelain") } bout, err := git.Output() utils.HandleErr(err) g_lines := utils.SplitLines(bout) //status := string(bout) if *g_unstaged { var matched bool for _, line := range g_lines { // echo "$status" | grep -E '^[ MARC][MD]' -q var i bool i, err = regexp.MatchString("^( |M|A|R|C)(M|D)", line) utils.HandleErr(err) if !i && line != "" { matched = true break } } if matched { if *g_exitcode { os.Exit(1) } output("There are unstaged changes. Use \"git add <file>\" to add.\n") } if *g_ignoresub != "" { // git ls-files --error-unmatch --stage | grep -E '^160000' | sed -e 's/^.* //' | tr '\n' ' ' bout, err = exec.Command( "git", "ls-files", "--error-unmatch", "--stage", ).Output() utils.HandleErr(err) lines := utils.SplitLines(bout) matched := false subm := []string{} for _, line := range lines { var i bool i, err = regexp.MatchString("^160000", line) utils.HandleErr(err) if !i { matched = true subm = append(subm, line) } } if matched { cmdargs := []string{"status", "--porcelain", "--"} cmdargs = append(cmdargs, subm...) bout, err = exec.Command( "git", cmdargs..., ).Output() utils.HandleErr(err) lines = utils.SplitLines(bout) matched = false for _, line := range lines { var i bool i, err = regexp.MatchString("^( |M|A|R|C)(M|D)", line) if !i { matched = true output("There is modified content in submodules.\n") break } } } } } testfct := func(lines []string, pattern, message string) { var matched bool for _, line := range lines { var i bool i, err = regexp.MatchString(pattern, line) utils.HandleErr(err) if !i && line != "" { matched = true break } } if matched { if *g_exitcode { os.Exit(1) } output(message) } } if *g_unmerged { testfct( g_lines, "^(DD|AU|UD|UA|DU|AU|UU)", "There are unmerged files. Use \"git add <file>\" when merged.\n", ) } if *g_uncommitted { testfct( g_lines, "^(M|A|D|R|C)", "There are uncommitted files. Use \"git commit\" to commit.\n", ) } if *g_untracked { testfct( g_lines, "^?.*", "There are untracked files not in .gitignore. Try \"make clean\" to remove temporary files.\n", ) } if g_output { if *g_warn { fmt.Fprintf(os.Stderr, "Warning in %s\n", pwd) os.Exit(0) } else { fmt.Fprintf(os.Stderr, "Error in %s\n", pwd) os.Exit(1) } } }
func main() { flag.Parse() var err error dir := "" switch flag.NArg() { case 0: err = fmt.Errorf("you need to give a submodule directory to remove") utils.HandleErr(err) case 1: dir = flag.Args()[0] default: // TODO: allow to remove n submodules in one go... err = fmt.Errorf("you need to give a submodule directory to remove") utils.HandleErr(err) } // make sure we get the correct collation stuff err = os.Setenv("LC_MESSAGES", "C") utils.HandleErr(err) // check 'dir' is a valid submodule if !utils.PathExists(dir) { err = fmt.Errorf("no such directory [%s]", dir) utils.HandleErr(err) } git := exec.Command( "git", "ls-files", "--error-unmatch", "--stage", "--", dir, ) bout, err := git.Output() utils.HandleErr(err) out := strings.Trim(string(bout), " \r\n") if out == "" { err = fmt.Errorf("no such submodule [%s]", dir) utils.HandleErr(err) } // get the full path of the submodule git = exec.Command("git", "ls-files", "--full-name", dir) bout, err = git.Output() utils.HandleErr(err) lines := utils.SplitLines(bout) dir = strings.Trim(lines[0], " \r\n") if *g_verbose { fmt.Printf("found submodule [%s]\n", dir) } // ensure we are in the toplevel directory git = exec.Command("git", "rev-parse", "--show-toplevel") bout, err = git.Output() utils.HandleErr(err) top := strings.Trim(string(bout), " \r\n") top, err = filepath.Abs(top) utils.HandleErr(err) pwd, err := os.Getwd() utils.HandleErr(err) defer os.Chdir(pwd) err = os.Chdir(top) utils.HandleErr(err) if *g_verbose { fmt.Printf("root [%s]\n", top) } // check if submodule is clean git = exec.Command("git", "check-clean") debug(git) utils.HandleErr(git.Run()) // check for unpushed changes git = exec.Command("git", "check-unpushed") debug(git) utils.HandleErr(git.Run()) // check for local non-tracking-branches git = exec.Command("git", "check-non-tracking") debug(git) utils.HandleErr(git.Run()) // find the real git-dir git = exec.Command("git", "rev-parse", "--git-dir") bout, err = git.Output() utils.HandleErr(err) gitdir := strings.Trim(string(bout), " \r\n") gitdir, err = filepath.Abs(gitdir) utils.HandleErr(err) if *g_verbose { fmt.Printf("gitdir [%s]\n", gitdir) } // get submodule url url := "unknown" git = exec.Command( "git", "config", "--get", fmt.Sprintf("submodule.%s.url", dir), ) bout, err = git.Output() if err == nil { url = strings.Trim(string(bout), " \r\n") } // remove config entries git = exec.Command( "git", "config", "-f", ".gitmodules", "--remove-section", fmt.Sprintf("submodule.%s", dir), ) debug(git) err = git.Run() utils.HandleErr(err) git = exec.Command( "git", "config", "--remove-section", fmt.Sprintf("submodule.%s", dir), ) debug(git) err = git.Run() utils.HandleErr(err) git = exec.Command("git", "rm", "--cached", dir) debug(git) err = git.Run() utils.HandleErr(err) err = os.RemoveAll(dir) utils.HandleErr(err) // remove git dir as well. if utils.PathExists(filepath.Join(gitdir, "modules", dir)) { err = os.RemoveAll(filepath.Join(gitdir, "modules", dir)) utils.HandleErr(err) } if *g_no_commit { return } // commit changes git = exec.Command("git", "add", ".gitmodules") debug(git) err = git.Run() utils.HandleErr(err) git = exec.Command( "git", "commit", "-m", fmt.Sprintf("removed submodule [%s] (url=%s)", dir, url), ) debug(git) err = git.Run() utils.HandleErr(err) // TODO: commit in super repositories of this one as well }