Documentation
¶
Overview ¶
Package syncbranch provides sync branch configuration and integrity checking.
Index ¶
- Constants
- func ClearStoredRemoteSHA(ctx context.Context, store storage.Storage) error
- func Get(ctx context.Context, store storage.Storage) (string, error)
- func GetCurrentBranch(ctx context.Context) (string, error)
- func GetFromYAML() string
- func GetRepoRoot(ctx context.Context) (string, error)
- func GetStoredRemoteSHA(ctx context.Context, store storage.Storage) (string, error)
- func HasGitRemote(ctx context.Context) bool
- func IsConfigured() bool
- func IsConfiguredWithDB(dbPath string) bool
- func IsSyncBranchSameAsCurrent(ctx context.Context, syncBranch string) bool
- func PushSyncBranch(ctx context.Context, repoRoot, syncBranch string) error
- func ResetToRemote(ctx context.Context, repoRoot, syncBranch, jsonlPath string) error
- func Set(ctx context.Context, store storage.Storage, branch string) error
- func Unset(ctx context.Context, store storage.Storage) error
- func UpdateStoredRemoteSHA(ctx context.Context, store storage.Storage, repoRoot, syncBranch string) error
- func ValidateBranchName(name string) error
- func ValidateSyncBranchName(name string) error
- type CommitResult
- type DivergenceInfo
- type ForcePushStatus
- type PullResult
Constants ¶
const ( // ConfigKey is the database config key for sync branch ConfigKey = "sync.branch" // ConfigYAMLKey is the config.yaml key for sync branch ConfigYAMLKey = "sync-branch" // EnvVar is the environment variable for sync branch EnvVar = "BEADS_SYNC_BRANCH" )
const ( // RemoteSHAConfigKey stores the last known remote sync branch commit SHA. // This is used to detect force pushes on the remote sync branch. RemoteSHAConfigKey = "sync.remote_sha" )
Config keys for sync branch integrity tracking
const SignificantDivergenceThreshold = 5
SignificantDivergenceThreshold is the number of commits at which divergence is considered significant When both local and remote are ahead by at least this many commits, the user should consider recovery options
Variables ¶
This section is empty.
Functions ¶
func ClearStoredRemoteSHA ¶
ClearStoredRemoteSHA removes the stored remote SHA. Use this when resetting the sync state (e.g., after accepting a rebase).
func Get ¶
Get retrieves the sync branch configuration with the following precedence: 1. BEADS_SYNC_BRANCH environment variable 2. sync-branch from config.yaml (version controlled, shared across clones) 3. sync.branch from database config (legacy, for backward compatibility) 4. Empty string (meaning use current branch)
func GetCurrentBranch ¶
GetCurrentBranch returns the name of the current git branch
func GetFromYAML ¶
func GetFromYAML() string
GetFromYAML retrieves sync branch from config.yaml only (no database lookup). This is useful for hooks and checks that need to know if sync-branch is configured in the version-controlled config without database access.
func GetRepoRoot ¶
GetRepoRoot returns the git repository root directory For worktrees, this returns the main repository root (not the worktree root) The returned path is canonicalized to fix case on case-insensitive filesystems (GH#880)
func GetStoredRemoteSHA ¶
GetStoredRemoteSHA returns the stored remote sync branch SHA.
func HasGitRemote ¶
HasGitRemote checks if any git remote exists
func IsConfigured ¶
func IsConfigured() bool
IsConfigured returns true if sync-branch is configured in config.yaml or env var. This is a fast check that doesn't require database access.
func IsConfiguredWithDB ¶
IsConfiguredWithDB returns true if sync-branch is configured in any source: 1. BEADS_SYNC_BRANCH environment variable 2. sync-branch in config.yaml 3. sync.branch in database config
The dbPath parameter should be the path to the beads.db file. If dbPath is empty, it will use beads.FindDatabasePath() to locate the database. This function is safe to call even if the database doesn't exist (returns false in that case).
func IsSyncBranchSameAsCurrent ¶
IsSyncBranchSameAsCurrent returns true if the sync branch is the same as the current branch. This is used to detect the case where we can't use a worktree because the branch is already checked out. In this case, we should commit directly to the current branch instead. See: https://github.com/untoldecay/BeadsLog/issues/519
func PushSyncBranch ¶
PushSyncBranch pushes the sync branch to remote. This is used after confirmation when sync.require_confirmation_on_mass_delete is enabled and a mass deletion was detected during merge.
Parameters:
- ctx: Context for cancellation
- repoRoot: Path to the git repository root
- syncBranch: Name of the sync branch (e.g., "beads-sync")
Returns error if push fails.
func ResetToRemote ¶
ResetToRemote resets the local sync branch to match the remote state. This discards all local commits on the sync branch and adopts the remote's history. Use this when the sync branch has diverged significantly and you want to discard local changes.
Parameters:
- ctx: Context for cancellation
- repoRoot: Path to the git repository root
- syncBranch: Name of the sync branch (e.g., "beads-sync")
- jsonlPath: Path to the JSONL file in the main repo (will be updated with remote content)
Returns error if reset fails.
func Set ¶
Set stores the sync branch configuration in both config.yaml AND the database. GH#909: Writing to both ensures bd doctor and migrate detection work correctly.
Config precedence on read (from Get function):
- BEADS_SYNC_BRANCH env var
- sync-branch in config.yaml (recommended, version controlled)
- sync.branch in database (legacy, for backward compatibility)
func UpdateStoredRemoteSHA ¶
func UpdateStoredRemoteSHA(ctx context.Context, store storage.Storage, repoRoot, syncBranch string) error
UpdateStoredRemoteSHA stores the current remote sync branch SHA in the database. Call this after a successful sync to track the remote state.
Parameters:
- ctx: Context for cancellation
- store: Storage interface for writing config
- repoRoot: Path to the git repository root
- syncBranch: Name of the sync branch (e.g., "beads-sync")
Returns error if the update fails.
func ValidateBranchName ¶
ValidateBranchName checks if a branch name is valid according to git rules
func ValidateSyncBranchName ¶
ValidateSyncBranchName checks if a branch name is valid for use as sync.branch. GH#807: Setting sync.branch to 'main' or 'master' causes problems because the worktree mechanism will check out that branch, preventing the user from checking it out in their working directory.
Types ¶
type CommitResult ¶
type CommitResult struct {
Committed bool // True if changes were committed
Pushed bool // True if changes were pushed
Branch string // The sync branch name
Message string // Commit message used
}
CommitResult contains information about a worktree commit operation
func CommitToSyncBranch ¶
func CommitToSyncBranch(ctx context.Context, repoRoot, syncBranch, jsonlPath string, push bool) (*CommitResult, error)
CommitToSyncBranch commits JSONL changes to the sync branch using a git worktree. This allows committing to a different branch without changing the user's working directory.
IMPORTANT: Before committing, this function now performs a pre-emptive fetch and fast-forward if possible. This reduces the likelihood of divergence by ensuring we're building on top of the latest remote state when possible.
Parameters:
- ctx: Context for cancellation
- repoRoot: Path to the git repository root
- syncBranch: Name of the sync branch (e.g., "beads-sync")
- jsonlPath: Absolute path to the JSONL file in the main repo
- push: If true, push to remote after commit
Returns CommitResult with details about what was done, or error if failed.
type DivergenceInfo ¶
type DivergenceInfo struct {
LocalAhead int // Number of commits local is ahead of remote
RemoteAhead int // Number of commits remote is ahead of local
Branch string // The sync branch name
Remote string // The remote name (e.g., "origin")
IsDiverged bool // True if both local and remote have commits the other doesn't
IsSignificant bool // True if divergence exceeds threshold (suggests recovery needed)
}
DivergenceInfo contains information about sync branch divergence from remote
func CheckDivergence ¶
func CheckDivergence(ctx context.Context, repoRoot, syncBranch string) (*DivergenceInfo, error)
CheckDivergence checks the divergence between local sync branch and remote. This should be called before attempting sync operations to detect significant divergence that may require user intervention.
Parameters:
- ctx: Context for cancellation
- repoRoot: Path to the git repository root
- syncBranch: Name of the sync branch (e.g., "beads-sync")
Returns DivergenceInfo with details about the divergence, or error if check fails.
type ForcePushStatus ¶
type ForcePushStatus struct {
// Detected is true if a force-push was detected on the remote sync branch.
Detected bool
// StoredSHA is the SHA we stored after the last successful sync.
StoredSHA string
// CurrentRemoteSHA is the current SHA of the remote sync branch.
CurrentRemoteSHA string
// Message provides a human-readable description of the status.
Message string
// Branch is the sync branch name.
Branch string
// Remote is the remote name (e.g., "origin").
Remote string
}
ForcePushStatus represents the result of a force-push detection check.
func CheckForcePush ¶
func CheckForcePush(ctx context.Context, store storage.Storage, repoRoot, syncBranch string) (*ForcePushStatus, error)
CheckForcePush detects if the remote sync branch has been force-pushed since the last sync.
A force-push is detected when: 1. We have a stored remote SHA from a previous sync 2. The stored SHA is NOT an ancestor of the current remote SHA
This means the remote history was rewritten (e.g., via force-push, rebase).
Parameters:
- ctx: Context for cancellation
- store: Storage interface for reading config
- repoRoot: Path to the git repository root
- syncBranch: Name of the sync branch (e.g., "beads-sync")
Returns ForcePushStatus with details about the check.
type PullResult ¶
type PullResult struct {
Pulled bool // True if pull was performed
Branch string // The sync branch name
JSONLPath string // Path to the synced JSONL in main repo
Merged bool // True if divergent histories were merged
FastForwarded bool // True if fast-forward was possible
Pushed bool // True if changes were pushed after merge
// SafetyCheckTriggered indicates mass deletion was detected during merge
// When true, callers should check config option sync.require_confirmation_on_mass_delete
SafetyCheckTriggered bool
// SafetyCheckDetails contains human-readable details about the mass deletion
SafetyCheckDetails string
// SafetyWarnings contains warning messages from the safety check
// Caller should display these to the user as appropriate for their output format
SafetyWarnings []string
}
PullResult contains information about a worktree pull operation
func PullFromSyncBranch ¶
func PullFromSyncBranch(ctx context.Context, repoRoot, syncBranch, jsonlPath string, push bool, requireMassDeleteConfirmation ...bool) (*PullResult, error)
PullFromSyncBranch pulls changes from the sync branch and copies JSONL to the main repo. This fetches remote changes without affecting the user's working directory.
IMPORTANT: This function handles diverged histories gracefully by performing a content-based merge instead of relying on git's commit-level merge. When local and remote sync branches have diverged:
- Fetch remote changes (don't pull)
- Find the merge base
- Extract JSONL from base, local, and remote
- Perform 3-way content merge using bd's merge algorithm
- Reset to remote's history (adopt remote commit graph)
- Commit merged content on top
IMPORTANT: After successful content merge, auto-pushes to remote by default. Includes safety check: warns (but doesn't block) if >50% issues vanished AND >5 existed. "Vanished" means removed from issues.jsonl entirely, NOT status=closed.
IMPORTANT: If requireMassDeleteConfirmation is true and the safety check triggers, the function will NOT auto-push. Instead, it sets SafetyCheckTriggered=true in the result and the caller should prompt for confirmation then call PushSyncBranch.
This ensures sync never fails due to git merge conflicts, as we handle merging at the JSONL content level where we have semantic understanding of the data.
Parameters:
- ctx: Context for cancellation
- repoRoot: Path to the git repository root
- syncBranch: Name of the sync branch (e.g., "beads-sync")
- jsonlPath: Absolute path to the JSONL file in the main repo
- push: If true, push to remote after merge
- requireMassDeleteConfirmation: If true and mass deletion detected, skip push
Returns PullResult with details about what was done, or error if failed.