support git worktrees for sync

This commit is contained in:
Stephen Macke 2024-10-14 16:47:42 -07:00
parent ab20624206
commit 74a1c22a3a
2 changed files with 55 additions and 8 deletions

View File

@ -1,6 +1,7 @@
package git package git
import ( import (
"bufio"
"errors" "errors"
"fmt" "fmt"
"io/fs" "io/fs"
@ -119,13 +120,54 @@ func (r *Repository) OriginUrl() string {
return parsedUrl.String() return parsedUrl.String()
} }
func readGitDir(root vfs.Path) (string, error) {
file, err := root.Open(".git")
if err != nil {
return "", fmt.Errorf("error opening file: %w", err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
if strings.HasPrefix(line, "gitdir: ") {
// Extract the path after "gitdir: "
return strings.TrimSpace(strings.TrimPrefix(line, "gitdir: ")), nil
}
}
if err := scanner.Err(); err != nil {
return "", fmt.Errorf("error reading file: %w", err)
}
return "", errors.New("gitdir line not found")
}
func (r *Repository) resolveGitRoot() vfs.Path {
fileInfo, err := r.root.Stat(".git")
if err != nil {
return r.root
}
if fileInfo.IsDir() {
return r.root
}
gitDir, err := readGitDir(r.root)
if err != nil {
return r.root
}
return vfs.MustNew(gitDir)
}
// loadConfig loads and combines user specific and repository specific configuration files. // loadConfig loads and combines user specific and repository specific configuration files.
func (r *Repository) loadConfig() error { func (r *Repository) loadConfig() error {
config, err := globalGitConfig() config, err := globalGitConfig()
if err != nil { if err != nil {
return fmt.Errorf("unable to load user specific gitconfig: %w", err) return fmt.Errorf("unable to load user specific gitconfig: %w", err)
} }
err = config.loadFile(r.root, ".git/config") root := r.resolveGitRoot()
if root == nil {
return fmt.Errorf("unable to resolve git root")
}
err = config.loadFile(root, ".git/config")
if err != nil { if err != nil {
return fmt.Errorf("unable to load repository specific gitconfig: %w", err) return fmt.Errorf("unable to load repository specific gitconfig: %w", err)
} }
@ -136,7 +178,7 @@ func (r *Repository) loadConfig() error {
// newIgnoreFile constructs a new [ignoreRules] implementation backed by // newIgnoreFile constructs a new [ignoreRules] implementation backed by
// a file using the specified path relative to the repository root. // a file using the specified path relative to the repository root.
func (r *Repository) newIgnoreFile(relativeIgnoreFilePath string) ignoreRules { func (r *Repository) newIgnoreFile(relativeIgnoreFilePath string) ignoreRules {
return newIgnoreFile(r.root, relativeIgnoreFilePath) return newIgnoreFile(r.resolveGitRoot(), relativeIgnoreFilePath)
} }
// getIgnoreRules returns a slice of [ignoreRules] that apply // getIgnoreRules returns a slice of [ignoreRules] that apply

View File

@ -107,6 +107,17 @@ func (v *View) EnsureValidGitIgnoreExists() error {
return nil return nil
} }
// Hard code .databricks ignore pattern so that we never sync it (irrespective)
// of .gitignore patterns
v.repo.addIgnoreRule(newStringIgnoreRules([]string{
".databricks",
}))
// Bail if we are in a worktree
if v.repo.Root() != v.repo.resolveGitRoot().Native() {
return nil
}
// Create .gitignore with .databricks entry // Create .gitignore with .databricks entry
gitIgnorePath := filepath.Join(v.repo.Root(), v.targetPath, ".gitignore") gitIgnorePath := filepath.Join(v.repo.Root(), v.targetPath, ".gitignore")
file, err := os.OpenFile(gitIgnorePath, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644) file, err := os.OpenFile(gitIgnorePath, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644)
@ -115,12 +126,6 @@ func (v *View) EnsureValidGitIgnoreExists() error {
} }
defer file.Close() defer file.Close()
// Hard code .databricks ignore pattern so that we never sync it (irrespective)
// of .gitignore patterns
v.repo.addIgnoreRule(newStringIgnoreRules([]string{
".databricks",
}))
_, err = file.WriteString("\n.databricks\n") _, err = file.WriteString("\n.databricks\n")
if err != nil { if err != nil {
return err return err