备份git仓库未提交的文件的程序

git仓库中未提交的改动文件可以使用git stash进行储藏,这在大部分情况下已经够用了。因为我想对所有新增的未跟踪文件和修改文件进行备份,所以写了一个程序来进行备份。

代码很简单,就是获取git status的结果,对未提交文件进行备份。

package main

import (
	"archive/zip"
	"fmt"
	"io"
	"log"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/go-git/go-git/v5"
)

func main() {
	// 替换为你的Git仓库路径
	repoPath, _ := os.Getwd()
	if len(os.Args) > 1 {
		repoPath = os.Args[1]
	}
	log.Println("正在处理Git仓库:", repoPath)

	// 打开Git仓库
	repo, err := git.PlainOpen(repoPath)
	if err != nil {
		log.Printf("无法打开Git仓库: %s\n", err)
		return
	}

	// 获取工作目录
	worktree, err := repo.Worktree()
	if err != nil {
		log.Printf("无法获取工作目录: %s\n", err)
		return
	}

	// 获取被修改的文件列表
	status, err := worktree.Status()
	if err != nil {
		log.Printf("无法获取Git状态: %s\n", err)
		return
	}

	// 创建一个ZIP文件
	zipFilePath := fmt.Sprintf("%s_%s.zip", "uncommit_files", time.Now().Format("20060102_150405"))
	zipFile, err := os.Create(zipFilePath)
	if err != nil {
		log.Printf("无法创建ZIP文件: %s\n", err)
		return
	}
	defer zipFile.Close()

	zipWriter := zip.NewWriter(zipFile)
	defer zipWriter.Close()
	zipWriter.SetComment("Backup of unsubmitted files:" + zipFilePath)

	const excludeExtensions = ".dll .lib .pdb .exe .so .obj .dylib .dll.a .a .dll.lib .dll.pdb .dll.exe .dll.so .dll.dylib .dll.dll.a" +
		" .7z .zip .tar.gz .rar .tar .gz .bz2" + ".log .tlog .tmp"

	backupCount := 0
	skipFiles := make([]string, 0, 1024)
	backupErrorFiles := make([]string, 0, 1024)
	backupFiles := make([]string, 0, 1024)

	// 遍历被修改的文件
	for filePath, fileStatus := range status {
		if fileStatus.Worktree != git.Unmodified {
			// 获取文件后缀名
			ext := filepath.Ext(filePath)
			if strings.Contains(excludeExtensions, ext) {
				skipFiles = append(skipFiles, filePath)
				continue
			}

			// 获取文件的绝对路径
			absPath := filepath.Join(repoPath, filePath)

			// 打开文件
			file, err := os.Open(absPath)
			if err != nil {
				backupErrorFiles = append(backupErrorFiles, filePath+": 文件打开失败")
				continue
			}
			defer file.Close()

			// 在ZIP文件中创建对应的文件
			zipEntry, err := zipWriter.Create(filePath)
			if err != nil {
				backupErrorFiles = append(backupErrorFiles, filePath+": zip条目创建失败")
				continue
			}

			// 将文件内容复制到ZIP文件中
			_, err = io.Copy(zipEntry, file)
			if err != nil {
				backupErrorFiles = append(backupErrorFiles, filePath+": zip写入文件失败")
				continue
			}

			backupFiles = append(backupFiles, filePath)
			backupCount += 1
		}
	}

	if len(skipFiles) > 0 {
		log.Println("=====<< 跳过备份的文件 >>======")
		for _, filePath := range skipFiles {
			fmt.Printf("\t%s\n", filePath)
		}
	}
	if len(backupErrorFiles) > 0 {
		log.Println("=====<< 备份出错的文件 >>======")
		for _, filePath := range backupErrorFiles {
			fmt.Printf("\t%s\n", filePath)
		}
	}

	log.Println("=====<< 已备份文件列表 >>======")
	for _, filePath := range backupFiles {
		fmt.Printf("\t%s\n", filePath)
	}
	log.Println("=====<< 备份文件信息 >>======")
	log.Println("【", zipFilePath, "】备份文件数量:", backupCount, "个")
}
posted @   乌合之众  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2020-02-11 Hyper-V Server 2019 安装使用记录
clear
点击右上角即可分享
微信分享提示