首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >git 配置文件读取和写入

git 配置文件读取和写入

原创
作者头像
ge3m0r
发布2024-12-02 20:14:10
发布2024-12-02 20:14:10
2881
举报

今天主题相对来说简单一些, 我们就纯编程, 我们用 go 实现 git 配置文件读取和写入.

git 配置文件格式如下:

代码语言:shell
复制
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
	ignorecase = true
	precomposeunicode = true
[submodule]
	active = .
[remote "origin"]
	url = https://github.com/xxx/xxx.git
	fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
	remote = origin
	merge = refs/heads/master
[submodule "lib/xxx"]
	url = https://github.com/xxx/xxx
[submodule "lib/xxx"]
	url = https://github.com/xxx/xxx

可以看到子模块中主要包含五项,因此定义如下

代码语言:go
复制
type ConfFile struct {
	core       map[string]string
	submodule  map[string]string
	remote     map[string]map[string]string
	branch     map[string]map[string]string
	submodules map[string]map[string]string
}

对数据结构操作,首先就是初始化,当我们从零开始创建一个 conf 文件时候,我们的数据结构如下:

代码语言:go
复制
func NewConfFle() ConfFile {
	return ConfFile{
		core: map[string]string{
			"repositoryformatversion": "0",
			"filemode":                "true",
			"bare":                    "false",
			"logallrefupdates":        "true",
			"ignorecase":              "true",
			"precomposeunicode":       "true",
		},
	}
}

初始化中只有 core 有内容.

从 config 中读取到数据结构

代码语言:go
复制
func ReadFileToConf(path string) (*ConfFile, error) {
	confFile := &ConfFile{}
	var currentSection string
	var currentSubSection string
	file, err := os.Open(path)
	if err != nil {
		panic("配置文件不存在")
	}
	defer file.Close()

    // 读取每行内容
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		line := strings.TrimSpace(scanner.Text())

		//约定注释为 # 跳过注释和空行
		if strings.HasPrefix(line, "#") || line == "" {
			continue
		}

		if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") {
			sectionLine := line[1 : len(line)-1]
			currentSection = ""
			currentSubSection = ""

			if sectionSplit := strings.SplitN(sectionLine, " ", 2); len(sectionSplit) == 2 {
				currentSection = sectionSplit[0]
				currentSubSection = sectionSplit[1]
			} else {
				currentSection = sectionLine
			}
			continue
		}
		if currentSection != "" {
			parts := strings.SplitN(line, "=", 2)
			if len(parts) != 2 {
				continue
			}
			key := parts[0]
			value := parts[1]

			switch currentSection {
			case "core":
				confFile.core[key] = value
			case "submodule":
				if currentSubSection == "" {
					confFile.submodule[key] = value
				} else {
					confFile.submodules[currentSubSection][key] = value
				}
			case "remote":
				if currentSubSection == "" {
					panic("conf 文件格式不正确")
				}
				confFile.remote[currentSubSection][key] = value
			case "branch":
				if currentSubSection == "" {
					panic("conf 文件格式不正确")
				}
				confFile.branch[currentSubSection][key] = value
			}

		}

	}
	if err := scanner.Err(); err != nil {
		return nil, err
	}
	return confFile, nil
}

上述内容逻辑很简单,就是读取文件内容,然后解析每行,匹配对应字段.

将数据结构写入文件

由于添加内容比较困难,因此采用覆写方式,而不是在文件中 append ,这样比较简单.

代码语言:go
复制
func (c *ConfFile) WriteToFile(path string) error {
	if _, err := os.Stat(path); os.IsNotExist(err) {
		panic("不是一个 git目录,无法写入文件")
	}
	file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
	if err != nil {
		panic("打开文件失败")
	}
	defer func(file *os.File) {
		err := file.Close()
		if err != nil {

		}
	}(file)

	// 写入  core
	_, err = file.WriteString("[core]\n")
	if err != nil {
		panic("写入失败")
	}
	for k, v := range c.core {
		_, err := file.WriteString("        " + k + "=" + v + "\n")
		if err != nil {
			panic("写入失败")
		}
	}

	// 写入  submodule
	if c.submodule != nil {
		_, err = file.WriteString("[submodule]\n")
		if err != nil {
			return err
		}
		for k, v := range c.submodule {
			_, err := file.WriteString("        " + k + "=" + v + "\n")
			if err != nil {
				panic("写入失败")
			}
		}
	}

	// 写入 remote
	if c.remote != nil {
		for k1, v1 := range c.submodules {
			_, err := file.WriteString("[remote " + k1 + "]\n")
			if err != nil {
				return err
			}
			if v1 == nil {
				continue
			}
			for k2, v2 := range v1 {
				_, err := file.WriteString("        " + k2 + "=" + v2 + "\n")
				if err != nil {
					panic("写入失败")
				}
			}
		}
	}

	// 写入  branch
	if c.branch != nil {
		for k1, v1 := range c.branch {
			_, err := file.WriteString("[branch " + k1 + "]\n")
			if err != nil {
				return err
			}
			if v1 == nil {
				continue
			}
			for k2, v2 := range v1 {
				_, err := file.WriteString("        " + k2 + "=" + v2 + "\n")
				if err != nil {
					panic("写入失败")
				}
			}
		}
	}

	// 写入  submodules
	if c.submodules != nil {
		for k1, v1 := range c.branch {
			_, err := file.WriteString("[submodules " + k1 + "]\n")
			if err != nil {
				return err
			}
			if v1 == nil {
				continue
			}
			for k2, v2 := range v1 {
				_, err := file.WriteString("        " + k2 + "=" + v2 + "\n")
				if err != nil {
					panic("写入失败")
				}
			}
		}
	}
	return nil
}

上述内容比较简单,具体逻辑不再解释.

上述内容就是简单实现一个功能玩一下.

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 从 config 中读取到数据结构
  • 将数据结构写入文件
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档