1

I want to be able to do run-time git manipulations with go.

I recently discovered the go-git package which comes in very handy to this end.

I was also able to perform pull operations, more or less as follows:

import {
  git "gopkg.in/src-d/go-git.v4"
}

repo, err := git.Clone(memory.NewStorage(), nil, &git.CloneOptions{
    URL: "https://github.com/pkaramol/myrepo",
})

err := repo.Pull(&git.PullOptions{
    RemoteName: "origin"
})

My question is, assuming I am using in-memory checkout of the repo as above), how will I be able to read in (my go program) a file from the repository? i.e. assuming the file

https://github.com/pkaramol/myrepo/someConfig.yaml

Would it be preferable (in case I need just this particular file) to perform a git clone (still in mem) of only the particular file?

pkaramol
  • 16,451
  • 43
  • 149
  • 324

1 Answers1

9

From the docs:

Clone a repository into the given Storer and worktree Filesystem with the given options, if worktree is nil a bare repository is created.

Don't pass a nil filesystem if you want access to the worktree. Use something like gopkg.in/src-d/go-billy.v4/memfs.Memory:

package main

import (
    "gopkg.in/src-d/go-git.v4"
    "gopkg.in/src-d/go-git.v4/storage/memory"
    "gopkg.in/src-d/go-billy.v4/memfs"
)

func main() {
    fs := memfs.New()

    repo, err := git.Clone(memory.NewStorage(), fs, &git.CloneOptions{
        URL: "https://github.com/pkaramol/myrepo",
    })

    file, err := fs.Open("someConfig.yaml")
}

You cannot clone a single file (that's not how git works), but you can limit the number of commits that are downloaded using CloneOptions.Depth.

Peter
  • 29,454
  • 5
  • 48
  • 60
  • 1
    This is not an answer to the question. fs.Open returns a File struct, which is not an os.File, but a subset of it. So how to get file content from it? – Nikita Petrov Nov 28 '22 at 08:22
  • 1
    Answer: ``` fileContent, err := ioutil.ReadAll(file) fmt.Println("File content: %+v\n", string(fileContent)) ``` – Nikita Petrov Nov 28 '22 at 08:25