17

If I have the following branches in git

1194-qa-server
master
remotes/origin/1178-authentication
remotes/origin/1194-qa-server
remotes/origin/HEAD -> origin/master
remotes/origin/master

I want to switch to a branch using --just-- the number, even if that requires calling a script For example:

switch_branch 1178

and the script/solution should do the following

  1. git branch -a (find all branches local and remote in my repository)
  2. filter by the given parameter ('1178' above)
  3. extract the name of the branch that git can use
  4. switch to that branch

What is the recommended way to do it without having to perform all these steps manually?

I am using Mac OSX, if that matters here.

update -- bash-it (github.com/revans/bash-it) serves my purpose

Welcome to Bash It!

Here is a list of commands you can use to get help screens for specific pieces of Bash it:

  rails-help                  list out all aliases you can use with rails.
  git-help                    list out all aliases you can use with git.
  todo-help                   list out all aliases you can use with todo.txt-cli
  brew-help                   list out all aliases you can use with Homebrew
  aliases-help                generic list of aliases.
  plugins-help                list out all functions you have installed with bash-it
  bash-it-plugins             summarize bash-it plugins, and their installation status
  reference <function name>   detailed help for a specific function
nwinkler
  • 52,665
  • 21
  • 154
  • 168
Ram on Rails
  • 1,299
  • 11
  • 25
  • 1
    Using bash you can use `git checkout 1178[TAB]` ;) – KingCrunch Jul 05 '12 at 08:21
  • And using some [fancy](https://github.com/robbyrussell/oh-my-zsh/) [helper](https://github.com/revans/bash-it/) it's just `gco 1178[TAB]` – Stefan Jul 05 '12 at 08:52
  • Not really working for me. I did find some references on the web for auto-completion for hash, but that is not what I am looking for. – Ram on Rails Jul 05 '12 at 10:42
  • 1
    you actually need to install git autocomplete for `git checkout 1178[TAB]` to work. More info here: https://apple.stackexchange.com/a/55886 – crogers Apr 19 '20 at 18:46

3 Answers3

14

There are very few occasions where you'd want to checkout remotes/origin/*. They exist but for the purposes of this shortcut, let's not worry about them. This will get you what you want on OSX:

git config --global alias.sco '!sh -c "git branch -a | grep -v remotes | grep $1 | xargs git checkout"'

You can then issue git sco <number> to checkout a branch that includes <number> but excludes "remotes". You can change sco to be anything you'd like. I just picked it for "super checkout".

Of course this won't work terribly well if you've got more than one branch that matches <number>. It should, however, be a decent starting point.

Christopher
  • 42,720
  • 11
  • 81
  • 99
8

Here is my solution with fuzzy checkout: Add the alias to your ~/.gitconfig by run

git config --global alias.fc '!f() { git branch -a | grep -m1 -e ${1}.*${2} | sed "s/remotes\/origin\///" | xargs git checkout; }; f'

The command above will add the alias to your ~/.gitconfig:

[alias]
    # fuzzy checkout branch, e.g: git cb feature 739, will checkout branch feature/PGIA-739-deploy-maximum
    fc = "!f() { git branch -a | grep -m1 -e ${1}.*${2} | sed \"s/remotes\\/origin\\///\" | xargs git checkout; }; f" 

The alias can have 2 parameters for the fuzzy matching, you can use it like:

git fc <keyword1> <keyword2>

It will find the checkout the branch first match

For example, if you want to checkout your branch 1178, you can run:

git fc 1178

the alias fc supports two parameters, if you want more accurate matching, you also can run:

git fc 1178 auth

You also can find my other favorite snippets here

DàChún
  • 4,751
  • 1
  • 36
  • 39
  • This works great, thanks! There is one small issue though. If you want to switch to a branch which has same number(match) as the current branch does have, it fails to pick any with message. Example: I am on`V3F-95` and there is another branch `some-long-Matching-test-V3F-95`. I do `git fc 95` then it shows `error: pathspec 'V3F-95' did not match any file(s) known to git` – Arvind K. Feb 04 '23 at 06:29
  • Another strange thing happened. I have a branch `Development` and I tried `git fc dev`. The result was, `git fc dev`\n`branch 'develop' set up to track 'origin/develop'.`\n`Switched to a new branch 'develop'`. It created new branch named develop and switched to it. I do not have any local or remote branch with `develop`. Any idea? – Arvind K. Feb 04 '23 at 06:35
  • Btw, is there a way to use branch name matching pattern with other git commands? For example I am also fed up doing `git pull origin Development`, `git merge Development` etc. :) – Arvind K. Feb 04 '23 at 06:47
3

Here's the solution I came up with for myself.

[ ${#} -ne 1 ] && { echo -e "Please provide one search string" ; exit 1 ; }
MATCHES=( $(git branch -a --color=never | sed -r 's|^[* ] (remotes/origin/)?||' | sort -u | grep -E "^((feature|bugfix|release|hotfix)/)?([A-Z]+-[1-9][0-9]*-)?${1}") )
case ${#MATCHES[@]} in
  ( 0 ) echo "No branches matched '${1}'" ; exit 1  ;;
  ( 1 ) git checkout "${MATCHES[0]}"      ; exit $? ;;
esac
echo "Ambiguous search '${1}'; returned ${#MATCHES[@]} matches:"

for ITEM in "${MATCHES[@]}" ; do
  echo -e "  ${ITEM}"
done
exit 1

I called it git-rcheckout ("r" for regex, for want of a better name) and placed it in my path (it's a little too long to shoehorn into my .gitconfig.)

It will attempt to match against local and remote branches (though only checks out locals), and will tolerate (IE disregard for the purposes of searching) some JIRA stylings, such as branches starting with common prefixes and things styled like JIRA ticket IDs.

e.g. Typing this:

git rcheckout this

Should match things like

this-branch
feature/this-branch
bugfix/JIRA-123-this-branch
JIRA-123-this-branch
remotes/origin/this-branch
remotes/origin/feature/this-branch
remotes/origin/bugfix/JIRA-123-this-branch
remotes/origin/JIRA-123-this-branch

But the regexes I've used are sufficiently tolerant that you could also do:

git rcheckout JIRA-123

To access:

bugfix/JIRA-123-this-branch
JIRA-123-this-branch
remotes/origin/bugfix/JIRA-123-this-branch
remotes/origin/JIRA-123-this-branch

It defaults to searching for branch prefixes, but actually you can use regexes to do fancier things if desired, like so:

git rcheckout '.*bran'
git rcheckout '.*is-br.*h'
bxm
  • 484
  • 4
  • 10
  • 1
    Works will for the large branch names that are normally created by Jira. Also supports the `git flow` paradigm. Excellent. – bvj Feb 27 '18 at 04:23