Example #1
0
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)
	}
}
Example #2
0
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)
		}
	}
}
Example #3
0
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
}