mirror of
https://github.com/danielmiessler/Fabric.git
synced 2026-01-07 21:44:02 -05:00
fix: use native git CLI for add/commit in worktrees
go-git has issues with worktrees where the object database isn't properly shared, causing 'invalid object' errors when trying to commit. Switching to native git CLI for add and commit operations resolves this. This fixes generate_changelog failing in worktrees with errors like: - 'cannot create empty commit: clean working tree' - 'error: invalid object ... Error building trees' Co-Authored-By: Warp <agent@warp.dev>
This commit is contained in:
@@ -3,6 +3,7 @@ package git
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
@@ -485,57 +486,53 @@ func (w *Walker) GetStatusDetails() (string, error) {
|
||||
}
|
||||
|
||||
// AddFile adds a file to the git index
|
||||
// Uses native git CLI instead of go-git to properly handle worktree scenarios
|
||||
func (w *Walker) AddFile(filename string) error {
|
||||
worktree, err := w.repo.Worktree()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get worktree: %w", err)
|
||||
}
|
||||
|
||||
_, err = worktree.Add(filename)
|
||||
worktreePath := worktree.Filesystem.Root()
|
||||
|
||||
// Use native git add command to avoid go-git worktree issues
|
||||
cmd := exec.Command("git", "add", filename)
|
||||
cmd.Dir = worktreePath
|
||||
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to add file %s: %w", filename, err)
|
||||
return fmt.Errorf("failed to add file %s: %w (output: %s)", filename, err, string(output))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CommitChanges creates a commit with the given message
|
||||
// Uses native git CLI instead of go-git to properly handle worktree scenarios
|
||||
func (w *Walker) CommitChanges(message string) (plumbing.Hash, error) {
|
||||
worktree, err := w.repo.Worktree()
|
||||
if err != nil {
|
||||
return plumbing.ZeroHash, fmt.Errorf("failed to get worktree: %w", err)
|
||||
}
|
||||
|
||||
// Get git config for author information
|
||||
cfg, err := w.repo.Config()
|
||||
worktreePath := worktree.Filesystem.Root()
|
||||
|
||||
// Use native git commit command to avoid go-git worktree issues
|
||||
cmd := exec.Command("git", "commit", "-m", message)
|
||||
cmd.Dir = worktreePath
|
||||
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return plumbing.ZeroHash, fmt.Errorf("failed to get git config: %w", err)
|
||||
return plumbing.ZeroHash, fmt.Errorf("failed to commit: %w (output: %s)", err, string(output))
|
||||
}
|
||||
|
||||
var authorName, authorEmail string
|
||||
if cfg.User.Name != "" {
|
||||
authorName = cfg.User.Name
|
||||
} else {
|
||||
authorName = "Changelog Bot"
|
||||
}
|
||||
if cfg.User.Email != "" {
|
||||
authorEmail = cfg.User.Email
|
||||
} else {
|
||||
authorEmail = "bot@changelog.local"
|
||||
}
|
||||
|
||||
commit, err := worktree.Commit(message, &git.CommitOptions{
|
||||
Author: &object.Signature{
|
||||
Name: authorName,
|
||||
Email: authorEmail,
|
||||
When: time.Now(),
|
||||
},
|
||||
})
|
||||
// Get the commit hash from HEAD
|
||||
ref, err := w.repo.Head()
|
||||
if err != nil {
|
||||
return plumbing.ZeroHash, fmt.Errorf("failed to commit: %w", err)
|
||||
return plumbing.ZeroHash, fmt.Errorf("failed to get HEAD after commit: %w", err)
|
||||
}
|
||||
|
||||
return commit, nil
|
||||
return ref.Hash(), nil
|
||||
}
|
||||
|
||||
// PushToRemote pushes the current branch to the remote repository
|
||||
|
||||
Reference in New Issue
Block a user