From 0c30a9da2f9a30a9f41c755879ea5be266180ce0 Mon Sep 17 00:00:00 2001 From: Jeff Carr Date: Sat, 18 Jan 2025 10:34:58 -0600 Subject: parse .git/config --- reloadGitConfig.go | 176 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 reloadGitConfig.go (limited to 'reloadGitConfig.go') diff --git a/reloadGitConfig.go b/reloadGitConfig.go new file mode 100644 index 0000000..367bd69 --- /dev/null +++ b/reloadGitConfig.go @@ -0,0 +1,176 @@ +package gitpb + +import ( + "bufio" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "strings" + + "go.wit.com/log" +) + +// does processing on the go.mod and go.sum files + +func (repo *Repo) updateGitConfig() error { + if repo == nil { + return fmt.Errorf("gitpb.updateGitConfig() repo == nil") + } + if repo.GitConfig == nil { + repo.GitConfig = new(GitConfig) + } + + repo.GitConfig.Core = make(map[string]string) + repo.GitConfig.Remotes = make(map[string]*GitRemote) + repo.GitConfig.Branches = make(map[string]*GitBranch) + repo.GitConfig.Submodules = make(map[string]string) + repo.GitConfig.Versions = make(map[string]string) + repo.GitConfig.Hashes = make(map[string]string) + return repo.readGitConfig() +} + +// readGitConfig reads and parses the .git/config file +func (repo *Repo) readGitConfig() error { + filename := filepath.Join(repo.GetFullPath(), ".git/config") + file, err := os.Open(filename) + defer file.Close() + if err != nil { + return err + } + + var currentSection string = "" + var currentName string = "" + + scanner := bufio.NewScanner(file) + for scanner.Scan() { + line := strings.TrimSpace(scanner.Text()) + + // Skip empty lines and comments + if line == "" || strings.HasPrefix(line, "#") || strings.HasPrefix(line, ";") { + continue + } + + // Check for section headers + if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") { + line = strings.Trim(line, "[]") + parts := strings.Split(line, " ") + currentSection = parts[0] + + if len(parts) == 2 { + line = strings.Trim(line, "[]") + currentName = strings.Trim(parts[1], "\"") + } + continue + } + + partsNew := strings.SplitN(line, "=", 2) + if len(partsNew) != 2 { + log.Log(WARN, "error on config section:", currentSection, "line:", line) + } + + key := strings.TrimSpace(partsNew[0]) + key = strings.TrimSuffix(key, "\"") + + value := strings.TrimSpace(partsNew[1]) + value = strings.TrimSuffix(value, "\"") + + switch currentSection { + case "core": + repo.GitConfig.Core[key] = value + case "gui": + // don't really need gui stuff right now + case "pull": + // don't store git config pull settings here + // git config probably has 'rebase = false' + case "remote": + test, ok := repo.GitConfig.Remotes[currentName] + if !ok { + test = new(GitRemote) + repo.GitConfig.Remotes[currentName] = test + } + log.Log(INFO, "switch currentSection", currentSection, currentName) + switch key { + case "url": + if test.Url == value { + continue + } + if test.Url == "" { + test.Url = value + continue + } + log.Log(INFO, "error url mismatch", test.Url, value) + case "fetch": + if test.Fetch == value { + continue + } + if test.Fetch == "" { + test.Fetch = value + continue + } + log.Log(INFO, "error fetch mismatch", test.Fetch, value) + default: + log.Log(INFO, "unknown remote:", line) + } + case "branch": + test, ok := repo.GitConfig.Branches[currentName] + if !ok { + test = new(GitBranch) + repo.GitConfig.Branches[currentName] = test + repo.processBranch(currentName) + } + switch key { + case "remote": + repo.GitConfig.Branches[currentName].Remote = value + case "merge": + repo.GitConfig.Branches[currentName].Merge = value + default: + log.Log(INFO, "error unknown remote:", currentSection, currentName, key, value) + log.Log(INFO, "unknown branch:", line) + } + case "submodule": + // test, ok := rs.gitConfig.submodules[currentName] + switch key { + case "active": + // probably 'true' or 'false' + case "url": + repo.GitConfig.Submodules[currentName] = value + default: + log.Log(WARN, "unknown submodule line:", line) + } + default: + log.Log(WARN, "unknown line:", line) + } + } + + if err := scanner.Err(); err != nil { + return err + } + + return nil +} + +func (repo *Repo) processBranch(branch string) { + log.Log(INFO, " ", branch) + hash, ok := repo.GitConfig.Hashes[branch] + filename := filepath.Join(repo.GetFullPath() + "/.git/refs/heads/" + branch) + log.Log(INFO, " hash: need to open", filename) + + data, err := ioutil.ReadFile(filename) + if err != nil { + log.Log(WARN, "hash: read failed", filename) + return + } + newhash := strings.TrimSpace(string(data)) + log.Log(INFO, " hash:", newhash) + repo.GitConfig.Hashes[branch] = newhash + if ok { + if hash != newhash { + log.Log(WARN, "hash changed", hash) + } + } + + name, _ := repo.gitDescribeByHash(newhash) + repo.GitConfig.Versions[newhash] = name + log.Log(INFO, " hash: version", name) +} -- cgit v1.2.3