fix: respect sync.remote config in bd sync (GH#872, bd-ypvj)
The sync.remote config was being set via `bd config set sync.remote <name>` but `bd sync` was still using 'origin' for git pull/push operations. Changes: - Updated gitPull() and gitPush() in sync_git.go to accept a configuredRemote parameter that takes precedence over git's branch tracking config - Updated sync.go to read sync.remote config and pass it to gitPull/gitPush - Updated daemon_sync.go to read sync.remote config for all daemon sync ops - Added user-facing messages to show which remote is being used 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> Executed-By: beads/crew/dave Rig: beads Role: crew
This commit is contained in:
@@ -327,6 +327,85 @@ func runGitRebaseContinue(ctx context.Context) error {
|
||||
|
||||
// gitPull pulls from the current branch's upstream
|
||||
// Returns nil if no remote configured (local-only mode)
|
||||
// If configuredRemote is non-empty, uses that instead of the branch's configured remote.
|
||||
// This allows respecting the sync.remote bd config.
|
||||
func gitPull(ctx context.Context, configuredRemote string) error {
|
||||
// Check if any remote exists (support local-only repos)
|
||||
if !hasGitRemote(ctx) {
|
||||
return nil // Gracefully skip - local-only mode
|
||||
}
|
||||
|
||||
// Get current branch name
|
||||
// Use symbolic-ref to work in fresh repos without commits
|
||||
branchCmd := exec.CommandContext(ctx, "git", "symbolic-ref", "--short", "HEAD")
|
||||
branchOutput, err := branchCmd.Output()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get current branch: %w", err)
|
||||
}
|
||||
branch := strings.TrimSpace(string(branchOutput))
|
||||
|
||||
// Determine remote to use:
|
||||
// 1. If configuredRemote (from sync.remote bd config) is set, use that
|
||||
// 2. Otherwise, get from git branch tracking config
|
||||
// 3. Fall back to "origin"
|
||||
remote := configuredRemote
|
||||
if remote == "" {
|
||||
remoteCmd := exec.CommandContext(ctx, "git", "config", "--get", fmt.Sprintf("branch.%s.remote", branch)) //nolint:gosec // G204: branch from git symbolic-ref
|
||||
remoteOutput, err := remoteCmd.Output()
|
||||
if err != nil {
|
||||
// If no remote configured, default to "origin"
|
||||
remote = "origin"
|
||||
} else {
|
||||
remote = strings.TrimSpace(string(remoteOutput))
|
||||
}
|
||||
}
|
||||
|
||||
// Pull with explicit remote and branch
|
||||
cmd := exec.CommandContext(ctx, "git", "pull", remote, branch) //nolint:gosec // G204: remote/branch from git config, not user input
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("git pull failed: %w\n%s", err, output)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// gitPush pushes to the current branch's upstream
|
||||
// Returns nil if no remote configured (local-only mode)
|
||||
// If configuredRemote is non-empty, pushes to that remote explicitly.
|
||||
// This allows respecting the sync.remote bd config.
|
||||
func gitPush(ctx context.Context, configuredRemote string) error {
|
||||
// Check if any remote exists (support local-only repos)
|
||||
if !hasGitRemote(ctx) {
|
||||
return nil // Gracefully skip - local-only mode
|
||||
}
|
||||
|
||||
// If configuredRemote is set, push explicitly to that remote with current branch
|
||||
if configuredRemote != "" {
|
||||
// Get current branch name
|
||||
branchCmd := exec.CommandContext(ctx, "git", "symbolic-ref", "--short", "HEAD")
|
||||
branchOutput, err := branchCmd.Output()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get current branch: %w", err)
|
||||
}
|
||||
branch := strings.TrimSpace(string(branchOutput))
|
||||
|
||||
cmd := exec.CommandContext(ctx, "git", "push", configuredRemote, branch) //nolint:gosec // G204: configuredRemote from bd config
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("git push failed: %w\n%s", err, output)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Default: use git's default push behavior
|
||||
cmd := exec.CommandContext(ctx, "git", "push")
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("git push failed: %w\n%s", err, output)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkMergeDriverConfig() {
|
||||
// Get current merge driver configuration
|
||||
cmd := exec.Command("git", "config", "merge.beads.driver")
|
||||
@@ -349,55 +428,6 @@ func checkMergeDriverConfig() {
|
||||
}
|
||||
}
|
||||
|
||||
func gitPull(ctx context.Context) error {
|
||||
// Check if any remote exists (support local-only repos)
|
||||
if !hasGitRemote(ctx) {
|
||||
return nil // Gracefully skip - local-only mode
|
||||
}
|
||||
|
||||
// Get current branch name
|
||||
// Use symbolic-ref to work in fresh repos without commits
|
||||
branchCmd := exec.CommandContext(ctx, "git", "symbolic-ref", "--short", "HEAD")
|
||||
branchOutput, err := branchCmd.Output()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get current branch: %w", err)
|
||||
}
|
||||
branch := strings.TrimSpace(string(branchOutput))
|
||||
|
||||
// Get remote name for current branch (usually "origin")
|
||||
remoteCmd := exec.CommandContext(ctx, "git", "config", "--get", fmt.Sprintf("branch.%s.remote", branch)) //nolint:gosec // G204: branch from git symbolic-ref
|
||||
remoteOutput, err := remoteCmd.Output()
|
||||
if err != nil {
|
||||
// If no remote configured, default to "origin"
|
||||
remoteOutput = []byte("origin\n")
|
||||
}
|
||||
remote := strings.TrimSpace(string(remoteOutput))
|
||||
|
||||
// Pull with explicit remote and branch
|
||||
cmd := exec.CommandContext(ctx, "git", "pull", remote, branch) //nolint:gosec // G204: remote/branch from git config, not user input
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("git pull failed: %w\n%s", err, output)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// gitPush pushes to the current branch's upstream
|
||||
// Returns nil if no remote configured (local-only mode)
|
||||
func gitPush(ctx context.Context) error {
|
||||
// Check if any remote exists (support local-only repos)
|
||||
if !hasGitRemote(ctx) {
|
||||
return nil // Gracefully skip - local-only mode
|
||||
}
|
||||
|
||||
cmd := exec.CommandContext(ctx, "git", "push")
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("git push failed: %w\n%s", err, output)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// restoreBeadsDirFromBranch restores .beads/ directory from the current branch's committed state.
|
||||
// This is used after sync when sync.branch is configured to keep the working directory clean.
|
||||
// The actual beads data lives on the sync branch; the main branch's .beads/ is just a snapshot.
|
||||
|
||||
Reference in New Issue
Block a user