NOTE: make sure you you use git-flow-avh (not the default one with brew).
I’ve created a repo with my ZSH setup: https://github.com/justin808/justin808-dotfiles/blob/master/zsh/git-flow.zsh
I’ve got the following setup scripts for zsh with git and git-flow, along with a couple other convenience methods. gist: git-helpers.zsh. That depends on some functions defined here: gist: utility.zsh. The code for these is also shown below. The scripts also have some cleanup commands for removing local branches that are fully merged and then cleaning up the remote branches.
The basic flow I use is:
-
create the branch This command creates branch
feature/some-good-branch-description
. Note the sanitization of whatever goes in the feature name parameter.
gffs "some good branch description"
- Make changes on that branch, commit, commit, rebase to make commits cleaner
- When ready to push new branch to remote at github:
gpthis
-
If you will have conflicts in what’s on your branch with other changes in
develop
, then merge whatever’s indevelop
(ormaster
for hot fix) over to your feature branch so you don’t have merge commits. If you don’t do this, you’ll have to manually finish up the merging and other actions of the git flow scripts. Be sure that you’ve done the proper updating of your develop branch etc. with the remote, before you merge what you think is the latest on thedevelop
branch! Otherwise, your merge might incorrectly do nothing.
# If you want to merge what's in develop to your feature branch
# make sure develop branch is current with remote
gco develop
gup
# be sure to be on correct branch
gco feature/some-good-branch-description
# Bring over latest
git merge origin/develop
# Alternately, you might
# git rebase origin/develop
# But that creates new commits, and anybody else working on that branch needs to be aware of this.
-
Then create pull request on github. Be sure to note if the source branch is
develop
for a feature andmaster
for a hot fix. That’s critical! -
After code is reviewed and ready to close the pull request (don’t do it on github), you’ll run this command. Note, be sure that
develop
branch is current with remote!
# Be sure that you've sync'd up develop with remote
gco develop
gup
# be sure to be on correct branch, as next command uses the current branch
gco feature/some-good-branch-description
gfff
Mnemonic:
- gf = git flow
- f = feature
- r = release
- h = hotfix
- s = start
- f = finish
So we have:
gffs
gfff
gfhs
gfhf
gfrs
gfrf
Here’s the code:
# Generic Utilities
using_port() {
#lsof -i:${1}
ps -p $(lsof -i:$1 -Fp | cut -c 2-)
}
most_used() {
history | awk '{a[$4]++}END{for(i in a){print a[i] " " i}}' | sort -rn | head -20
}
echoRun() {
START=$(date +%s)
echo "> $1"
eval time $1
END=$(date +%s)
DIFF=$(( $END - $START ))
echo "It took $DIFF seconds"
}
sanitize() {
echo $1 | tr ": /." "-" | tr -d ",'\""
}
# history grep tail
hgt() {
fc -l 1 | grep -i --color=auto $1 | tail -n 40
}
#### GIT ####
# http://notes.envato.com/developers/rebasing-merge-commits-in-git/
# https://gist.github.com/590895
function git_current_branch() {
git symbolic-ref HEAD 2> /dev/null | sed -e 's/refs\/heads\///'
}
alias gpthis='git push origin HEAD:$(git_current_branch) && git branch -u origin/$(git_current_branch) $(git_current_branch) && echo "pushed current branch and set upstream to origin"'
alias s='git status --short'
alias gh='git log --name-status -n'
alias gm='git merge --no-ff'
alias gl='git log'
alias gs='git stash'
alias grhard='git reset --hard'
alias grsoft='git reset --soft'
git-branch-current() {
printf "%s\n" $(git branch 2> /dev/null | grep -e ^* | tr -d "\* ")
}
git-log-last-pushed-hash() {
local currentBranch=$(git-branch-current);
git log --format="%h" -n 1 origin/${currentBranch}
}
git-rebase-unpushed() {
git rebase --interactive $(git-log-last-pushed-hash)
}
gitk_everything() {
gitk --all --date-order $(git log -g --pretty=%H)
}
gitFlowNameForCurrentBranch() {
# next line using sed is greedy
# git_current_branch | sed -e 's/.*\///'
# This is the non-greedy match
git_current_branch | perl -pe "s|.*?/||"
}
alias gfn=gitFlowNameForCurrentBranch
gffs() {
feature=`sanitize $1`
echoRun "git flow feature start $feature"
}
gffp() {
feature=`sanitize $1`
echoRun "git flow feature publish $feature"
}
gfff() {
echoRun "git flow feature finish $(gitFlowNameForCurrentBranch)"
}
gfrs() {
release=`sanitize $1`
echoRun "git flow release start $release"
}
gfrp() {
release=`sanitize $1`
echoRun "git flow release publish $release"
}
gfrf() {
echoRun "git flow release finish -Fpn $(gitFlowNameForCurrentBranch)"
}
gfhs() {
release=`sanitize $1`
echoRun "git flow hotfix start $release"
}
gfhp() {
release=`sanitize $1`
echoRun "git flow hotfix publish $release"
}
gfhf() {
echoRun "git flow hotfix finish -Fpn $(gitFlowNameForCurrentBranch)"
}
alias git-diff-master-develop='git log --left-right --graph --cherry-pick master..develop'
alias git-cleanup-merged-branches='git branch --merged develop | grep -v develop | xargs git branch -d'
alias git-cleanup-origin='git remote prune origin'
alias git-cleanup-octopress-merged-branches='git branch --merged source | grep -v source | grep -v master | xargs git branch -d'
git-list-remote-branches-to-remove() {
git branch -r --merged | grep 'origin/' | grep -v "origin/master$" | grep -v "origin/develop$" | sed 's/\s*origin\///'
}
git-list-remote-branches-to-remove-do-it() {
git-list-remote-branches-to-remove | xargs -n 1 git push --delete origin
}