Fix bd init to auto-import issues from git on fresh clone
Prevents agents from creating duplicate low-numbered issues when starting with a fresh git clone that already has issues.jsonl in git history. Changes: - bd init now checks for existing issues in git after DB creation - Auto-imports with collision resolution if found - Updates AGENTS.md to simplify onboarding (just 'bd init') Fixes the scenario where: 1. Fresh clone has .beads/issues.jsonl in git (212 issues) 2. Agent runs bd init (creates empty DB) 3. Agent starts creating bd-1, bd-2, etc (collisions with git) Now bd init automatically imports all issues from git on first run. Amp-Thread-ID: https://ampcode.com/threads/T-8a41f14d-d4c3-4c50-a18b-5f112110f138 Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -456,11 +456,9 @@ Happy coding! 🔗
|
|||||||
|
|
||||||
### Quick Start
|
### Quick Start
|
||||||
|
|
||||||
**FIRST TIME?** Import existing issues from git:
|
**FIRST TIME?** Just run `bd init` - it auto-imports issues from git:
|
||||||
```bash
|
```bash
|
||||||
bd import -i .beads/issues.jsonl --json
|
bd init --prefix bd
|
||||||
# Or if issues.jsonl is empty in working tree but exists in git:
|
|
||||||
git show HEAD:.beads/issues.jsonl | bd import -i /dev/stdin --json
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Check for ready work:**
|
**Check for ready work:**
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ func checkAndAutoImport(ctx context.Context, store storage.Storage) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Import from git
|
// Import from git
|
||||||
if err := importFromGit(ctx, store, jsonlPath); err != nil {
|
if err := importFromGit(ctx, dbPath, store, jsonlPath); err != nil {
|
||||||
if !jsonOutput {
|
if !jsonOutput {
|
||||||
fmt.Fprintf(os.Stderr, "Warning: auto-import failed: %v\n", err)
|
fmt.Fprintf(os.Stderr, "Warning: auto-import failed: %v\n", err)
|
||||||
fmt.Fprintf(os.Stderr, "Try manually: git show HEAD:%s | bd import -i /dev/stdin\n", jsonlPath)
|
fmt.Fprintf(os.Stderr, "Try manually: git show HEAD:%s | bd import -i /dev/stdin\n", jsonlPath)
|
||||||
@@ -130,7 +130,7 @@ func findGitRoot() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// importFromGit imports issues from git HEAD
|
// importFromGit imports issues from git HEAD
|
||||||
func importFromGit(ctx context.Context, store storage.Storage, jsonlPath string) error {
|
func importFromGit(ctx context.Context, dbFilePath string, store storage.Storage, jsonlPath string) error {
|
||||||
// Get content from git
|
// Get content from git
|
||||||
cmd := exec.Command("git", "show", fmt.Sprintf("HEAD:%s", jsonlPath))
|
cmd := exec.Command("git", "show", fmt.Sprintf("HEAD:%s", jsonlPath))
|
||||||
jsonlData, err := cmd.Output()
|
jsonlData, err := cmd.Output()
|
||||||
@@ -167,6 +167,6 @@ func importFromGit(ctx context.Context, store storage.Storage, jsonlPath string)
|
|||||||
SkipPrefixValidation: true, // Auto-import is lenient about prefixes
|
SkipPrefixValidation: true, // Auto-import is lenient about prefixes
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = importIssuesCore(ctx, dbPath, store, issues, opts)
|
_, err = importIssuesCore(ctx, dbFilePath, store, issues, opts)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,18 +85,36 @@ bd.db
|
|||||||
|
|
||||||
// Store the bd version in metadata (for version mismatch detection)
|
// Store the bd version in metadata (for version mismatch detection)
|
||||||
if err := store.SetMetadata(ctx, "bd_version", Version); err != nil {
|
if err := store.SetMetadata(ctx, "bd_version", Version); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Warning: failed to store version metadata: %v\n", err)
|
fmt.Fprintf(os.Stderr, "Warning: failed to store version metadata: %v\n", err)
|
||||||
// Non-fatal - continue anyway
|
// Non-fatal - continue anyway
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := store.Close(); err != nil {
|
// Check if git has existing issues to import (fresh clone scenario)
|
||||||
fmt.Fprintf(os.Stderr, "Warning: failed to close database: %v\n", err)
|
issueCount, jsonlPath := checkGitForIssues()
|
||||||
|
if issueCount > 0 {
|
||||||
|
if !quiet {
|
||||||
|
fmt.Fprintf(os.Stderr, "\n✓ Database initialized. Found %d issues in git, importing...\n", issueCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := importFromGit(ctx, dbPath, store, jsonlPath); err != nil {
|
||||||
|
if !quiet {
|
||||||
|
fmt.Fprintf(os.Stderr, "Warning: auto-import failed: %v\n", err)
|
||||||
|
fmt.Fprintf(os.Stderr, "Try manually: git show HEAD:%s | bd import -i /dev/stdin\n", jsonlPath)
|
||||||
|
}
|
||||||
|
// Non-fatal - continue with empty database
|
||||||
|
} else if !quiet {
|
||||||
|
fmt.Fprintf(os.Stderr, "✓ Successfully imported %d issues from git.\n\n", issueCount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Skip output if quiet mode
|
if err := store.Close(); err != nil {
|
||||||
if quiet {
|
fmt.Fprintf(os.Stderr, "Warning: failed to close database: %v\n", err)
|
||||||
return
|
}
|
||||||
}
|
|
||||||
|
// Skip output if quiet mode
|
||||||
|
if quiet {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
green := color.New(color.FgGreen).SprintFunc()
|
green := color.New(color.FgGreen).SprintFunc()
|
||||||
cyan := color.New(color.FgCyan).SprintFunc()
|
cyan := color.New(color.FgCyan).SprintFunc()
|
||||||
|
|||||||
Reference in New Issue
Block a user