fix(trail): fetch existing remote branch before create · Entire
fix(trail): fetch existing remote branch before create
1fd4f9f→main·
dipree·4w ago·1 file·+35 added/-11 removed
Address PR review feedback:
- validate branch names before trail create reaches git subcommands
- reject leading-dash branch names before invoking git
- when a requested branch is missing locally but already exists on origin, fetch it instead of creating a new local branch at HEAD
- make the non-fast-forward hint refer to the target branch
Sessions
b73b63b3e546View transcript
[?
Fix Trail Creation Branch Handling and ValidationPi·Opus 4.8·1 step](/content/gh/entireio/cli/session/019ed956-c81a-74d1-9437-9fb289e1410f#timeline-b73b63b3e546/index.html)
Changes
1
cmd/entire/cli
Mtrail_cmd.go+35/-11
634 unmodified lines
635
636
637
638
639
640
641
642
643
644
645
646
639
640
647
648
649
650
651
652
653
654
655
656
657
658
659
642
643
660
661
662
2 unmodified lines
665
666
667
652
653
654
655
656
657
668
669
660
670
671
672
673
732 unmodified lines
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
634 unmodified lines
localBranchCreated := false
var remoteBranchPushed bool
// Don't delete a remote branch we didn't create during cleanup.
existedOnOrigin, existErr := branchExistsOnOrigin(branch)
if existErr != nil {
fmt.Fprintf(errW, "Warning: could not check whether branch %s already exists on origin: %v\n", branch, existErr)
existedOnOrigin = true
}
if needsCreation {
if err := createBranch(repo, branch); err != nil {
return fmt.Errorf("failed to create branch %q: %w", branch, err)
}
if existedOnOrigin {
if err := fetchBranchFromOrigin(branch); err != nil {
return fmt.Errorf("failed to fetch branch %q from origin: %w", branch, err)
}
localBranchCreated = true
fmt.Fprintf(w, "Fetched branch %s from origin\n", branch)
} else {
if err := createBranch(repo, branch); err != nil {
return fmt.Errorf("failed to create branch %q: %w", branch, err)
}
localBranchCreated = true
fmt.Fprintf(w, "Created branch %s\n", branch)
}
localBranchCreated = true
fmt.Fprintf(w, "Created branch %s\n", branch)
} else if currentBranch != branch {
fmt.Fprintf(w, "Note: trail will be created for branch %q (not the current branch)\n", branch)
}
2 unmodified lines
// deliver it before creating the trail rather than letting the server
// backfill it at the base tip.
{
// Don't delete a remote branch we didn't create during cleanup.
existedOnOrigin, existErr := branchExistsOnOrigin(branch)
if existErr != nil {
fmt.Fprintf(errW, "Warning: could not check whether branch %s already exists on origin: %v\n", branch, existErr)
existedOnOrigin = true
}
if err := pushBranchToOrigin(branch); err != nil {
cleanupCreatedTrailBranch(repo, branch, localBranchCreated, false, errW)
return fmt.Errorf("failed to push branch %q to origin: %w\nhint: the trail was not created because its branch could not be delivered to the remote.\n - if this is an auth error, link your GitHub account and retry\n - if this is a non-fast-forward, update your base (git fetch && git rebase) and retry", branch, err)
}
remoteBranchPushed = !existedOnOrigin
fmt.Fprintf(w, "Pushed branch %s to origin\n", branch)
732 unmodified lines
}
}
func fetchBranchFromOrigin(branchName string) error {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel()
if err := ValidateBranchName(ctx, branchName); err != nil {
return err
}
refspec := fmt.Sprintf("refs/heads/%%s:refs/heads/%%s", branchName, branchName)
cmd := exec.CommandContext(ctx, "git", "fetch", "--no-tags", "origin", refspec)
if output, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("%s: %w", strings.TrimSpace(string(output)), err)
}
return nil
}
// pushBranchToOrigin pushes a branch to the origin remote.
func pushBranchToOrigin(branchName string) error {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)