feat: support commit hash in --base flag#11
Conversation
The --base flag previously only accepted branch names (local or remote). Now it also accepts commit hashes (full or short SHA), falling back to git rev-parse verification when branch resolution fails.
ea8bc7d to
cd61d96
Compare
There was a problem hiding this comment.
Pull request overview
This PR extends bt add -b --base to accept commit hashes (full or short SHA) in addition to branch names, updating the CLI help/docs and adding E2E coverage for the new behavior.
Changes:
- Add git executor support for validating whether a ref resolves to a commit.
- Update
bt addbase resolution to fall back to commit-hash validation when a branch isn’t found. - Add E2E coverage + documentation updates for
--base <commit>usage.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
internal/git/branch.go |
Adds a helper to validate that an input resolves to a commit object via git rev-parse. |
cmd/bt/add.go |
Adds commit-hash fallback for --base and updates CLI help text. |
e2e/journey_remote_test.go |
Adds E2E coverage for full hash, short hash, and invalid hash base cases. |
e2e/README.md |
Documents the new E2E test case. |
README.md |
Updates the command reference to mention --base supports branch/commit. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // IsCommitHash checks if the given string resolves to a valid commit object | ||
| func (e *Executor) IsCommitHash(ref string) bool { |
There was a problem hiding this comment.
IsCommitHash is named like it validates a hex SHA, but git rev-parse --verify <ref>^{commit} will also succeed for non-hash commit-ish values (e.g. HEAD, tags, or other refs). This makes the API misleading and can unintentionally broaden what --base accepts. Consider either renaming this to something like IsCommitRef/IsCommitish, or tightening the check (e.g., first require the input to match a hex SHA pattern of an acceptable length) so the behavior matches the name/help text.
| // IsCommitHash checks if the given string resolves to a valid commit object | |
| func (e *Executor) IsCommitHash(ref string) bool { | |
| // IsCommitHash checks if the given string looks like a hex SHA and resolves to a valid commit object | |
| func (e *Executor) IsCommitHash(ref string) bool { | |
| ref = strings.TrimSpace(ref) | |
| // Require a plausible abbreviated or full SHA-1 (Git allows abbreviations, typically >= 4 chars) | |
| if len(ref) < 4 || len(ref) > 40 { | |
| return false | |
| } | |
| for _, c := range ref { | |
| if !((c >= '0' && c <= '9') || | |
| (c >= 'a' && c <= 'f') || | |
| (c >= 'A' && c <= 'F')) { | |
| return false | |
| } | |
| } |
| } | ||
| baseDisplayInfo = shortHash + " (commit)" | ||
| } else { | ||
| return fmt.Errorf("base branch '%s' not found locally or on any remote", addBaseBranch) |
There was a problem hiding this comment.
Now that --base supports commit hashes, this error message is misleading for invalid hashes because it only mentions branches/remotes. Consider updating it to indicate the value wasn’t found as either a branch or a commit, so users understand why a hash-like value failed.
| return fmt.Errorf("base branch '%s' not found locally or on any remote", addBaseBranch) | |
| return fmt.Errorf("base '%s' not found as a local/remote branch or commit", addBaseBranch) |
| | Command | Description | | ||
| |---------|-------------| | ||
| | `bt add <branch>` | Add worktree (`-b` for new branch, auto-fetches remotes, `--no-fetch` to skip) | | ||
| | `bt add <branch>` | Add worktree (`-b` for new branch, `--base` for base branch/commit, auto-fetches remotes) | |
There was a problem hiding this comment.
This command reference row previously documented --no-fetch but now omits it. If --no-fetch is still supported, consider keeping it in the short description while adding the new --base mention to avoid a docs regression.
| | `bt add <branch>` | Add worktree (`-b` for new branch, `--base` for base branch/commit, auto-fetches remotes) | | |
| | `bt add <branch>` | Add worktree (`-b` for new branch, `--base` for base branch/commit, auto-fetches remotes unless \`--no-fetch\`) | |
Summary
bt add -b --baseto accept commit hashes (full or short SHA) in addition to branch namesIsCommitHashmethod to git executor usinggit rev-parse --verify--basevalue doesn't match any local/remote branch, fall back to commit hash validation before erroringChanges
internal/git/branch.go: AddIsCommitHash()methodcmd/bt/add.go: Add commit hash fallback in--baseresolution, update help textREADME.md: Add--basewith commit example, update command referencee2e/journey_remote_test.go: AddTestAddNewBranchWithCommitBase(full hash, short hash, invalid hash)e2e/README.md: Document new test caseTest plan
task buildpassestask testpasses (unit + E2E)golangci-lint run ./...passesbt add -b feat/test --base <commit-hash>creates worktree correctlybt add -b feat/test --base <invalid-hash>shows error