Created
May 3, 2011 22:45
-
-
Save gf3/954425 to your computer and use it in GitHub Desktop.
Git Feature Command – Feature Branches
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env zsh | |
# git-feature | |
# Written by: Gianni Chiappetta <gianni@runlevel6.org> | |
# Requires: git 1.7.5+, zsh 4.3.11+ | |
# Screenshot: http://cloud.gf3.ca/6TPb | |
function c_list { echo " \033[1;32m✔\033[0m $1"; } | |
function e_list { echo " \033[1;31m✖\033[0m $1"; } | |
function git_branch() { | |
ref=$(git symbolic-ref HEAD 2> /dev/null) || return | |
echo ${ref#refs/heads/} | |
} | |
function upstream_branch() { | |
echo "refs/heads/feature/$1" | |
} | |
function get_simple_name() { | |
echo $1 | sed 's/^feature\///g' | |
} | |
# Help | |
read -d '' help_text <<"EOS" | |
Git Feature - A tool to help you manage feature branches | |
Written by: Gianni Chiappetta <gianni@runlevel6.org> | |
Usage: | |
git feature <command> [arguments...] | |
Commands: | |
start: | |
Start a new feature. Creates a new branch, and sets up a remote upstream. | |
git feature <name> | |
git feature start <name> | |
done: | |
Finishing a feature. Marks a feature as finished when listing. | |
git feature done [<name>] If no <name> is passed the | |
current branch name is used. | |
remove: | |
Remove a feature. Deletes the remote branch, but not the local branch. | |
git feature remove [<name>] If no <name> is passed the | |
current branch name is used. | |
list: | |
List features and their status. | |
git feature list Show only feature branches. | |
git feature list -a Show feature branches and | |
local branches. | |
help: | |
Show this help. | |
git feature help | |
EOS | |
# Command normalisation | |
cmds=( start done remove list help ) | |
if [[ ${cmds[(i)$1]} -le ${#cmds} ]]; then | |
cmd=$1 | |
else | |
cmd="start" | |
fi | |
# Meat... mmm | |
if [[ $cmd = 'done' ]]; then | |
local branch=$(git_branch) | |
if [ $# -eq 2 ]; then | |
branch=$2 | |
fi | |
branch=$(get_simple_name $branch) | |
git config --bool "branch.feature/$branch.peer-review" true && \ | |
c_list "Finished feature: \033[1;35m$branch\033[0m" && return | |
e_list "Error finishing: \033[1;35m$branch\033[0m" | |
elif [[ $cmd = 'remove' ]]; then | |
local branch=$(git_branch) | |
if [ $# -eq 2 ]; then | |
branch=$2 | |
fi | |
branch=$(get_simple_name $branch) | |
if git push origin :feature/$branch >/dev/null; then | |
git config --unset "branch.feature/$branch.peer-review" | |
c_list "Finished feature: \033[1;35m$branch\033[0m" && return | |
else | |
e_list "Error removing: \033[1;35m$branch\033[0m" && return 1 | |
fi | |
elif [[ $cmd = 'list' ]]; then | |
if [[ $2 = '-a' ]]; then | |
eval $'branches=( ${(s.\n.)"$(git branch --no-color)"} )' | |
else | |
eval $'branches=( ${(s.\n.)"$(git branch --no-color | grep \'feature/\')"} )' | |
fi | |
for b in $branches; do | |
local bname=$(echo $b | grep -oE "[-_0-9A-Za-z/]+" | tail -1) | |
local review=" " | |
# Review | |
if ( $(git config --bool branch.$bname.peer-review) ); then | |
review=" \033[1;32m✔\033[0m " | |
fi | |
# Name | |
if echo $bname | grep -q "/"; then | |
cname=$(echo " \033[0;32m$bname\033[0m") | |
elif [[ $bname == $(git_branch) ]]; then | |
cname=$(echo "→ \033[3;43;30m$bname\033[0m") | |
else | |
cname=$(echo " \033[0;33m$bname\033[0m") | |
fi | |
echo "$review$cname" | |
done | |
elif [[ $cmd = 'start' ]]; then | |
local branch=$1 | |
if [[ $cmd = $1 ]]; then | |
branch=$2 | |
fi | |
branch=$(get_simple_name $branch) | |
# Branch exists? | |
if ( ! $(git ls-remote --heads origin | grep -q "$(upstream_branch $branch)") ); then | |
if ( ! $(git push --set-upstream origin origin/master:$(upstream_branch $branch)) ); then | |
e_list "Error: Couldn't create remote branch" && return 1 | |
fi | |
fi | |
if git checkout feature/$branch >/dev/null; then | |
c_list "Starting feature: \033[1;35m$branch\033[0m" && return | |
else | |
e_list "Error: Couldn't checkout new branch and track remote" && return 1 | |
fi | |
return | |
elif [[ $cmd = 'help' ]]; then | |
echo $help_text | |
return | |
fi | |
# vim: set filetype=zsh : |
We use develop
as our main dev branch. master
is our stable branch. All feature branches branch from master
so as they start clean, and can be merged directly to master if needed (but usually merged to develop
).
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In this model, are you using master as your main dev branch? How are you tracking stable code? As tags?