I have a bare repository in which I need to add and commit a set of files. As far as I understand it, adding files to the index requires a worktree. Using git
on the command line, I would set the git-dir
option to point to the bare directory along with setting the work-tree
option to point to a worktree in which the files to be added to the index live. Like so:
$ git --git-dir /path/to/.git --work-tree /path/to/worktree add ...
It's worth mentioning that the ".git" directory is not, and can not, be named simply ".git". It is in fact a "custom" ".git" dir. Like git --git-dir /path/to/.notgit ...
.
I tried setting the core.worktree
config option. However, with core.bare
set to true
this results in a fatal error. Both from the command line:
$ git --git-dir /path/to/.notgit config core.worktree /path/to/worktree
$ git --git-dir /path/to/.notgit add ...
warning: core.bare and core.worktree do not make sense
fatal: unable to set up work tree using invalid config
and using go-git
:
r, err := git.PlainOpen("/path/to/.notgit")
panicOnError(err)
c, err := r.Config()
panicOnError(err)
fmt.Println(c.Core.IsBare) // true
c.Core.Worktree = "/path/to/worktree"
err = r.SetConfig(c)
panicOnError(err)
_, err = r.Worktree() // panic: worktree not available in a bare repository
panicOnError(err)
One thought I had was to lean on the git.PlainOpenWithOptions
function to hopefully allow me to provide a worktree as an option. However, looking at the git.PlainOpenOptions
struct type, this fell apart quickly.
type PlainOpenOptions struct {
// DetectDotGit defines whether parent directories should be
// walked until a .git directory or file is found.
DetectDotGit bool
// Enable .git/commondir support (see https://git-scm.com/docs/gitrepository-layout#Documentation/gitrepository-layout.txt).
// NOTE: This option will only work with the filesystem storage.
EnableDotGitCommonDir bool
}
How do I mimic git --work-tree ...
with go-git
?
Edit 1: Explained that ".git" is not exactly named ".git".
Go-git is an open-source implementation of Git written in pure Go. It is currently used for backing projects as a SQL interface for Git code repositories and providing encryption for Git.
A Git worktree is a linked copy of your Git repository, allowing you to have multiple branches checked out at a time. A worktree has a separate path from your main working copy, but it can be in a different state and on a different branch.
You can now always view the code in your repository at the main branch. To update the worktree, run the git pull command. This will get all the latest commits to the branch and update your worktree.
Git-go is a variation of the word get-go, which means at the start or beginning. It is usually found in the phrase from the get-go.
When you use git.Open()
, it basically sets worktree
field in repository struct as nil
, since it uses PlainOpenWithOptions
internally with the default value of DetectDotGit
as false
. If you use the following constructor, you will see, the untracked files will be added successfully.
r, err := git.PlainOpenWithOptions("/path/to/.git",&git.PlainOpenOptions{DetectDotGit: true})
panicOnError(err)
c, err := r.Config()
panicOnError(err)
fmt.Println(c.Core.IsBare) // true
c.Core.Worktree = "/path/to/worktree"
err = r.SetConfig(c)
panicOnError(err)
_, err = r.Worktree() // panic: worktree not available in a bare repository
panicOnError(err)
// added this part for test
workTree, werr := r.Worktree()
panicOnError(werr)
hash, hashErr := workTree.Add("a.txt")
if hashErr != nil {
log.Fatal(hashErr)
}
fmt.Println(hash)
Before go code execution
After go code execution
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With