-
Notifications
You must be signed in to change notification settings - Fork 12
gitconfig: improve rbm alias base detection #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -31,7 +31,7 @@ | |||||||||
| rba = rebase --abort | ||||||||||
| rbc = rebase --continue | ||||||||||
| rbi = rebase -i | ||||||||||
| rbm = "!fn(){ branch=''; if git show-ref --verify --quiet refs/heads/master; then branch='master'; elif git show-ref --verify --quiet refs/heads/main; then branch='main'; fi; if [ -n '$branch' ]; then git rebase $branch $1; else echo 'Both master and main branch not found!' >&2; return 1; fi; };fn" | ||||||||||
| rbm = "!fn(){ base=''; remote_head=$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null || true); remote_branch=${remote_head#origin/}; if [ -n \"$remote_branch\" ] && [ \"$remote_branch\" != \"$remote_head\" ]; then case \"$remote_branch\" in master|main) if git show-ref --verify --quiet \"refs/heads/$remote_branch\"; then base=$remote_branch; elif git show-ref --verify --quiet \"refs/remotes/origin/$remote_branch\"; then base=origin/$remote_branch; fi;; esac; fi; if [ -z \"$base\" ] && git show-ref --verify --quiet refs/heads/master; then base=master; elif [ -z \"$base\" ] && git show-ref --verify --quiet refs/heads/main; then base=main; fi; if [ -z \"$base\" ] && [ -n \"$remote_branch\" ]; then if git show-ref --verify --quiet \"refs/heads/$remote_branch\"; then base=$remote_branch; elif [ -n \"$remote_head\" ] && git show-ref --verify --quiet \"refs/remotes/$remote_head\"; then base=$remote_head; fi; fi; if [ -z \"$base\" ]; then echo 'Both master and main branch not found!' >&2; return 1; fi; git rebase \"$base\" \"$@\"; };fn" | ||||||||||
|
||||||||||
| rbm = "!fn(){ base=''; remote_head=$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null || true); remote_branch=${remote_head#origin/}; if [ -n \"$remote_branch\" ] && [ \"$remote_branch\" != \"$remote_head\" ]; then case \"$remote_branch\" in master|main) if git show-ref --verify --quiet \"refs/heads/$remote_branch\"; then base=$remote_branch; elif git show-ref --verify --quiet \"refs/remotes/origin/$remote_branch\"; then base=origin/$remote_branch; fi;; esac; fi; if [ -z \"$base\" ] && git show-ref --verify --quiet refs/heads/master; then base=master; elif [ -z \"$base\" ] && git show-ref --verify --quiet refs/heads/main; then base=main; fi; if [ -z \"$base\" ] && [ -n \"$remote_branch\" ]; then if git show-ref --verify --quiet \"refs/heads/$remote_branch\"; then base=$remote_branch; elif [ -n \"$remote_head\" ] && git show-ref --verify --quiet \"refs/remotes/$remote_head\"; then base=$remote_head; fi; fi; if [ -z \"$base\" ]; then echo 'Both master and main branch not found!' >&2; return 1; fi; git rebase \"$base\" \"$@\"; };fn" | |
| rbm = "!fn(){ base=''; remote_head=$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null || true); remote_branch=${remote_head#origin/}; if [ -n \"$remote_branch\" ] && [ \"$remote_branch\" != \"$remote_head\" ]; then case \"$remote_branch\" in master|main) if git show-ref --verify --quiet \"refs/heads/$remote_branch\"; then base=$remote_branch; elif git show-ref --verify --quiet \"refs/remotes/origin/$remote_branch\"; then base=origin/$remote_branch; fi;; esac; fi; if [ -z \"$base\" ] && git show-ref --verify --quiet refs/heads/master; then base=master; elif [ -z \"$base\" ] && git show-ref --verify --quiet refs/heads/main; then base=main; fi; if [ -z \"$base\" ] && [ -n \"$remote_branch\" ]; then if git show-ref --verify --quiet \"refs/heads/$remote_branch\"; then base=$remote_branch; elif [ -n \"$remote_head\" ] && git show-ref --verify --quiet \"refs/remotes/$remote_head\"; then base=$remote_head; fi; fi; if [ -z \"$base\" ]; then echo 'No suitable base branch found!' >&2; return 1; fi; git rebase \"$base\" \"$@\"; };fn" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The shell script for the rbm alias is quite complex and has a confusing order of precedence for branch detection. It could be simplified for better readability and maintainability, while also making the logic more intuitive.
The current logic prioritizes a local master or main branch over the remote's default branch if the default branch is named something other than master or main (e.g., develop). This seems to contradict the goal of detecting the base branch from origin/HEAD first.
Here's a simplified version that has a clearer order of precedence:
- Check
origin/HEADfor the default branch. Prefer a local tracking branch if it exists, otherwise use the remote branch. - If not found, fall back to checking for a local
masterbranch. - If still not found, fall back to checking for a local
mainbranch. - If no branch is found, print an error.
This revised script is shorter, easier to understand, and more robustly follows the intended logic of prioritizing the remote's default branch. I've also updated the error message to be more accurate.
!fn(){ base=''; remote_head=$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null || true); if [ -n "$remote_head" ]; then remote_branch=${remote_head#origin/}; if [ "$remote_branch" != "$remote_head" ]; then if git show-ref --verify --quiet "refs/heads/$remote_branch"; then base=$remote_branch; elif git show-ref --verify --quiet "refs/remotes/$remote_head"; then base=$remote_head; fi; fi; fi; if [ -z "$base" ]; then if git show-ref --verify --quiet refs/heads/master; then base=master; elif git show-ref --verify --quiet refs/heads/main; then base=main; fi; fi; if [ -z "$base" ]; then echo 'Could not determine default branch (main, master, or from origin/HEAD).' >&2; return 1; fi; git rebase "$base" "$@"; };fn
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Preserve rebase options before inserting base branch
The alias now forwards "$@" to git rebase but it prepends the resolved base as the first argument. Git parses options before positional arguments, so running git rbm --autostash or git rbm -i executes git rebase main --autostash, which treats --autostash as a branch name and aborts with fatal: invalid refname. This fails to deliver the stated goal of mirroring git rebase behaviour and breaks any use of the alias with rebase options. The base branch needs to be appended after user options (e.g. git rebase "$@" "$base") to keep flags working.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Respect origin/HEAD before falling back to local master
Line 34: when origin/HEAD points to a branch that isn’t master or main (e.g. trunk), but a stale local master branch still exists, we never reach the remote default fallback—the refs/heads/master check triggers first and forces every git rbm to rebase onto master. This regresses the very case this change set is meant to handle: repositories that renamed their default branch but kept master around. To reproduce, set origin/HEAD to origin/trunk, keep a local master, and run git rbm; it rebases onto master instead of origin/trunk.
Please move the generic remote_branch fallback ahead of the local master/main checks so we always honor the true default branch before considering legacy names.
- rbm = "!fn(){ base=''; remote_head=$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null || true); remote_branch=${remote_head#origin/}; if [ -n \"$remote_branch\" ] && [ \"$remote_branch\" != \"$remote_head\" ]; then case \"$remote_branch\" in master|main) if git show-ref --verify --quiet \"refs/heads/$remote_branch\"; then base=$remote_branch; elif git show-ref --verify --quiet \"refs/remotes/origin/$remote_branch\"; then base=origin/$remote_branch; fi;; esac; fi; if [ -z \"$base\" ] && git show-ref --verify --quiet refs/heads/master; then base=master; elif [ -z \"$base\" ] && git show-ref --verify --quiet refs/heads/main; then base=main; fi; if [ -z \"$base\" ] && [ -n \"$remote_branch\" ]; then if git show-ref --verify --quiet \"refs/heads/$remote_branch\"; then base=$remote_branch; elif [ -n \"$remote_head\" ] && git show-ref --verify --quiet \"refs/remotes/$remote_head\"; then base=$remote_head; fi; fi; if [ -z \"$base\" ]; then echo 'Both master and main branch not found!' >&2; return 1; fi; git rebase \"$base\" \"$@\"; };fn"
+ rbm = "!fn(){ base=''; remote_head=$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null || true); remote_branch=${remote_head#origin/}; if [ -n \"$remote_branch\" ] && [ \"$remote_branch\" != \"$remote_head\" ]; then case \"$remote_branch\" in master|main) if git show-ref --verify --quiet \"refs/heads/$remote_branch\"; then base=$remote_branch; elif git show-ref --verify --quiet \"refs/remotes/origin/$remote_branch\"; then base=origin/$remote_branch; fi;; esac; fi; if [ -z \"$base\" ] && [ -n \"$remote_branch\" ]; then if git show-ref --verify --quiet \"refs/heads/$remote_branch\"; then base=$remote_branch; elif [ -n \"$remote_head\" ] && git show-ref --verify --quiet \"refs/remotes/$remote_head\"; then base=$remote_head; fi; fi; if [ -z \"$base\" ] && git show-ref --verify --quiet refs/heads/master; then base=master; elif [ -z \"$base\" ] && git show-ref --verify --quiet refs/heads/main; then base=main; fi; if [ -z \"$base\" ]; then echo 'Both master and main branch not found!' >&2; return 1; fi; git rebase \"$base\" \"$@\"; };fn"📝 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.
| rbm = "!fn(){ base=''; remote_head=$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null || true); remote_branch=${remote_head#origin/}; if [ -n \"$remote_branch\" ] && [ \"$remote_branch\" != \"$remote_head\" ]; then case \"$remote_branch\" in master|main) if git show-ref --verify --quiet \"refs/heads/$remote_branch\"; then base=$remote_branch; elif git show-ref --verify --quiet \"refs/remotes/origin/$remote_branch\"; then base=origin/$remote_branch; fi;; esac; fi; if [ -z \"$base\" ] && git show-ref --verify --quiet refs/heads/master; then base=master; elif [ -z \"$base\" ] && git show-ref --verify --quiet refs/heads/main; then base=main; fi; if [ -z \"$base\" ] && [ -n \"$remote_branch\" ]; then if git show-ref --verify --quiet \"refs/heads/$remote_branch\"; then base=$remote_branch; elif [ -n \"$remote_head\" ] && git show-ref --verify --quiet \"refs/remotes/$remote_head\"; then base=$remote_head; fi; fi; if [ -z \"$base\" ]; then echo 'Both master and main branch not found!' >&2; return 1; fi; git rebase \"$base\" \"$@\"; };fn" | |
| rbm = "!fn(){ base=''; remote_head=$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null || true); remote_branch=${remote_head#origin/}; if [ -n \"$remote_branch\" ] && [ \"$remote_branch\" != \"$remote_head\" ]; then case \"$remote_branch\" in master|main) if git show-ref --verify --quiet \"refs/heads/$remote_branch\"; then base=$remote_branch; elif git show-ref --verify --quiet \"refs/remotes/origin/$remote_branch\"; then base=origin/$remote_branch; fi;; esac; fi; if [ -z \"$base\" ] && [ -n \"$remote_branch\" ]; then if git show-ref --verify --quiet \"refs/heads/$remote_branch\"; then base=$remote_branch; elif [ -n \"$remote_head\" ] && git show-ref --verify --quiet \"refs/remotes/$remote_head\"; then base=$remote_head; fi; fi; if [ -z \"$base\" ] && git show-ref --verify --quiet refs/heads/master; then base=master; elif [ -z \"$base\" ] && git show-ref --verify --quiet refs/heads/main; then base=main; fi; if [ -z \"$base\" ]; then echo 'Both master and main branch not found!' >&2; return 1; fi; git rebase \"$base\" \"$@\"; };fn" |
Uh oh!
There was an error while loading. Please reload this page.