项目集成 github.com/go-git/go-git

概要

项目集成使用 github.com/go-git/go-git

go-git 介绍
一个用 Go 语言编写的 git 实现库:它的官方仓库地址:go-git

为什么我们需要它?
举个例子:

如果我们需要获取 git log 的信息,需要通过 Go 调用 cmd 命令来获取:获取 git 的 last commit hash 的话需要耗费的时间大概在 50ms 左右(不同运行环境可能不一样)

它的慢原因是什么呢 ?
Go 调用 cmd 命令本身存在着性能原因
其次,如果想要获取其它仓库的 git log 信息,还存在着跨文件调用的消耗

所以这里 go-git 的作用就体现出来了!由于它是 go 编写的 git 实现库,所以对 cmd 命令调用的消耗就可以避免了。测试之后,使用时间在 500μs 左右,巨大的提升!

技术细节,上代码


package gogit

import (
	"context"
	"fmt"
	"os"
	"time"

	"github.com/go-git/go-billy/v5/osfs" // 使用 osfs 作为文件系统抽象
	"github.com/go-git/go-git/v5"
	"github.com/go-git/go-git/v5/config"
	"github.com/go-git/go-git/v5/plumbing"
	"github.com/go-git/go-git/v5/plumbing/object"
	"github.com/go-git/go-git/v5/plumbing/transport/http"
	"github.com/go-git/go-git/v5/storage/memory"
)

// git fetch | localPath:本地代码实际路径
func Fetch(gitLabUserName, gitLabPassW, localPath, gitUrl string) error {
	// 创建一个基于操作系统文件系统的 worktree
	worktree := osfs.New(localPath)
	if localPath == "" {
		worktree = nil
	}

	r, err := git.Init(memory.NewStorage(), worktree)
	if err != nil {
		return err
	}

	_, err = r.CreateRemote(&config.RemoteConfig{Name: "origin", Mirror: false, URLs: []string{gitUrl}})
	if err != nil {
		return err
	}
	opts := &git.FetchOptions{
		RemoteName: "origin",
		// 指定分支
		// ReferenceName:   plumbing.NewBranchReferenceName(),
		RemoteURL:       gitUrl,
		InsecureSkipTLS: true,
	}

	opts.Auth = &http.BasicAuth{Username: gitLabUserName, Password: gitLabPassW}
	return r.FetchContext(context.Background(), opts)
}

// git clone  |	localPath := "/path/to/your/local/repo" // 替换为您想要克隆到的实际路径
func Clone(gitLabUserName, gitLabPassW, localPath, gitUrl string) (*git.Repository, error) {
	// 创建一个基于操作系统文件系统的 worktree
	worktree := osfs.New(localPath)
	if localPath == "" {
		worktree = nil
	}

	// r.CreateRemote(c)
	opts := &git.CloneOptions{
		// 指定分支
		// ReferenceName:   plumbing.NewBranchReferenceName(),
		URL:             gitUrl,
		InsecureSkipTLS: true,
	}
	opts.Auth = &http.BasicAuth{Username: gitLabUserName, Password: gitLabPassW}

	// 打开仓库
	return git.Clone(memory.NewStorage(), worktree, opts)
}

// git branch
func GetBranch(gitLabUserName, gitLabPassW, gitUrl string) ([]string, error) {
	brans := make([]string, 0)
	repo, err := Clone(gitLabUserName, gitLabPassW, "", gitUrl)
	if err != nil {
		return brans, err
	}
	// 获取所有分支
	branches, err := repo.References()
	if err != nil {
		return brans, err
	}

	// 遍历分支并打印
	err = branches.ForEach(func(ref *plumbing.Reference) error {
		if ref.Name().IsRemote() {
			fmt.Println(ref.Name().Short())
			brans = append(brans, ref.Name().Short())
		}
		return nil
	})

	return brans, err
}

// git push  repoPath := "/path/to/your/repo"  替换为本地仓库路径  gitUrl: git 仓库地址
func Push(gitLabUserName, gitLabPassW, repoPath, gitUrl string) error {
	// 克隆仓库到本地
	_, err := git.PlainClone(repoPath, false, &git.CloneOptions{
		Auth: &http.BasicAuth{
			Username: gitLabUserName,
			Password: gitLabPassW,
		},
		URL:             gitUrl,
		Progress:        os.Stdout,
		InsecureSkipTLS: true,
	})
	if err != nil {
		fmt.Println("Failed to clone repository:", err)
		return err
	}

	// 打开已存在的Git仓库
	r, err := git.PlainOpen(repoPath)
	if err != nil {
		fmt.Println(err)
		return err
	}

	// 获取工作树
	w, err := r.Worktree()
	if err != nil {
		fmt.Println(err)
		return err
	}

	// 添加所有更改到暂存区
	_, err = w.Add(".")
	if err != nil {
		fmt.Println(err)
		return err
	}

	// 提交更改
	commitMsg := "init commit"
	commit, err := w.Commit(commitMsg, &git.CommitOptions{
		Author: &object.Signature{
			Name:  gitLabUserName,
			Email: gitLabPassW,
			When:  time.Now(),
		},
	})
	if err != nil {
		fmt.Println(err)
		return err
	}
	fmt.Println("Commit:", commit)

	// 获取远程仓库配置
	remotes, err := r.Remotes()
	if err != nil {
		fmt.Println(err)
		return err
	}

	// 假设我们使用的是第一个远程仓库(通常是"origin")
	remote := remotes[0]

	// 创建一个推送选项对象
	pushOptions := &git.PushOptions{
		RemoteName: remote.Config().Name,
		RefSpecs:   []config.RefSpec{config.RefSpec("+refs/heads/master:refs/heads/master")},
		Auth: &http.BasicAuth{
			Username: gitLabUserName,
			Password: gitLabPassW,
		},
		InsecureSkipTLS: true,
	}

	// 执行推送操作
	if err = r.Push(pushOptions); err != nil {
		fmt.Println(err)
		return err
	}

	fmt.Println("Changes have been pushed to the remote repository.")
	return nil
}

小结

直接将此文件复制到项目中即可使用,封装api接口不太完善,可按需引入其他接口。

项目地址:github.com/go-git/go-git

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值