Skip to content

fix: use origin/ ref when branching from default branch#149

Open
averyjennings wants to merge 1 commit intomainfrom
fix/use-origin-for-default-branch
Open

fix: use origin/ ref when branching from default branch#149
averyjennings wants to merge 1 commit intomainfrom
fix/use-origin-for-default-branch

Conversation

@averyjennings
Copy link

@averyjennings averyjennings commented Mar 4, 2026

Summary

  • New worktrees created with git gtr new <name> branch from the local default branch (e.g. main), which may be stale
  • git fetch updates origin/main but doesn't fast-forward the local main branch
  • The resolved_ref logic in create_worktree compounds this: git rev-parse "main^{commit}" succeeds with the stale local SHA, so the origin/ fallback never runs
  • This causes new worktrees to silently start several commits behind remote

Fix: Prefix resolve_default_branch() result with origin/ in _create_resolve_from_ref(), so new branches always start from the freshly-fetched remote state.

Test plan

  • git gtr new test-branch creates worktree at origin/main HEAD (not stale local main)
  • git gtr new test-branch --from-current still branches from current local branch (not affected)
  • git gtr new test-branch --from some-ref still uses the explicit ref (not affected)
  • Detached HEAD fallback also uses origin/main

Summary by CodeRabbit

  • Bug Fixes
    • Refined how the system selects and references the base branch when creating new branches without an explicit base specified. The improvement ensures consistent reference naming in all scenarios, including when the current branch state is unclear or when using default branches, providing more predictable behavior across various repository configurations.

resolve_default_branch returns a bare branch name (e.g. "main") which
points to the local branch. After git fetch, origin/main is up to date
but the local main may be stale — causing new worktrees to start from
an old commit.

The resolved_ref logic in create_worktree compounds this: it tries
git rev-parse "main^{commit}" first, which succeeds with the stale
local SHA, so the origin/ fallback never runs.

Prefix with origin/ so new branches always start from the latest remote.
@averyjennings averyjennings requested a review from NatoBoram as a code owner March 4, 2026 08:40
@coderabbitai
Copy link

coderabbitai bot commented Mar 4, 2026

Walkthrough

The _create_resolve_from_ref function now prefixes the resolved default branch with origin/ when deriving the base reference. This applies to both the detached HEAD fallback path and the general default-path scenario, changing from bare branch names to remote-tracking refs.

Changes

Cohort / File(s) Summary
Reference Resolution
lib/commands/create.sh
Modified _create_resolve_from_ref to prefix resolved default branch with origin/ in detached HEAD fallback and general default paths, affecting how from_ref is determined.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

🐰 A little tweak to refs so fine,
Now origin/ marks the line,
Detached heads find their way,
With prefixes leading the day! 🌿

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: use origin/ ref when branching from default branch' directly describes the main change: prefixing the default branch reference with 'origin/' to use the remote ref instead of a potentially stale local branch.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/use-origin-for-default-branch

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@lib/commands/create.sh`:
- Around line 76-81: The code unconditionally prefixes origin/ onto the value
returned by resolve_default_branch which can produce origin/origin/main; update
the logic around from_ref assignment in create.sh to normalize the resolved
branch: check the string returned by resolve_default_branch (used where from_ref
is set) and if it already starts with "origin/" (or a full ref like
"refs/heads/"), use it as-is, otherwise prepend "origin/"; apply this
normalization in both places where from_ref is assigned so existing configs like
"origin/main" remain unchanged and new values get the correct prefix.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f01bef52-b39c-4c49-8777-d44cb1cef59b

📥 Commits

Reviewing files that changed from the base of the PR and between 4a4e21b and 261ca3a.

📒 Files selected for processing (1)
  • lib/commands/create.sh

Comment on lines +76 to +81
from_ref="origin/$(resolve_default_branch "$repo_root")"
else
log_info "Creating from current branch: $from_ref"
fi
else
from_ref=$(resolve_default_branch "$repo_root")
from_ref="origin/$(resolve_default_branch "$repo_root")"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Avoid unconditional origin/ prefixing for default branch values.

On Line 76 and Line 81, if resolve_default_branch already returns origin/main (from existing config), this becomes origin/origin/main and ref resolution can fail. Normalize the value before prefixing.

Proposed fix
 _create_resolve_from_ref() {
   local from_ref="$1" from_current="$2" repo_root="$3"
+  local default_branch

   if [ -z "$from_ref" ]; then
     if [ "$from_current" -eq 1 ]; then
       from_ref=$(get_current_branch)
       if [ -z "$from_ref" ] || [ "$from_ref" = "HEAD" ]; then
         log_warn "Currently in detached HEAD state - falling back to default branch"
-        from_ref="origin/$(resolve_default_branch "$repo_root")"
+        default_branch=$(resolve_default_branch "$repo_root")
+        case "$default_branch" in
+          origin/*) from_ref="$default_branch" ;;
+          refs/remotes/origin/*) from_ref="${default_branch#refs/remotes/}" ;;
+          *) from_ref="origin/$default_branch" ;;
+        esac
       else
         log_info "Creating from current branch: $from_ref"
       fi
     else
-      from_ref="origin/$(resolve_default_branch "$repo_root")"
+      default_branch=$(resolve_default_branch "$repo_root")
+      case "$default_branch" in
+        origin/*) from_ref="$default_branch" ;;
+        refs/remotes/origin/*) from_ref="${default_branch#refs/remotes/}" ;;
+        *) from_ref="origin/$default_branch" ;;
+      esac
     fi
   fi

   printf "%s" "$from_ref"
 }

As per coding guidelines, "Maintain backwards compatibility with existing configs in shell scripts."

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
from_ref="origin/$(resolve_default_branch "$repo_root")"
else
log_info "Creating from current branch: $from_ref"
fi
else
from_ref=$(resolve_default_branch "$repo_root")
from_ref="origin/$(resolve_default_branch "$repo_root")"
default_branch=$(resolve_default_branch "$repo_root")
case "$default_branch" in
origin/*) from_ref="$default_branch" ;;
refs/remotes/origin/*) from_ref="${default_branch#refs/remotes/}" ;;
*) from_ref="origin/$default_branch" ;;
esac
else
log_info "Creating from current branch: $from_ref"
fi
else
default_branch=$(resolve_default_branch "$repo_root")
case "$default_branch" in
origin/*) from_ref="$default_branch" ;;
refs/remotes/origin/*) from_ref="${default_branch#refs/remotes/}" ;;
*) from_ref="origin/$default_branch" ;;
esac
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/commands/create.sh` around lines 76 - 81, The code unconditionally
prefixes origin/ onto the value returned by resolve_default_branch which can
produce origin/origin/main; update the logic around from_ref assignment in
create.sh to normalize the resolved branch: check the string returned by
resolve_default_branch (used where from_ref is set) and if it already starts
with "origin/" (or a full ref like "refs/heads/"), use it as-is, otherwise
prepend "origin/"; apply this normalization in both places where from_ref is
assigned so existing configs like "origin/main" remain unchanged and new values
get the correct prefix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant