#!/bin/sh -e # The git [c]ommit st[ash] # Given a committish, this command saves a list of commits between the HEAD and the given committish into the .git directory. # Without parameters it applies the saved list of commits onto the current HEAD. # NOTE: You should prefer rebase -i to this brewery. local verbosity=1 while test $# -gt 0; do case $1 in (-v) verbosity=2; shift 1;; (-q|--quiet) verbosity=0; shift 1;; (--theirs) local params=(-X theirs); shift 1;; (*) break;; esac done local stashed="$(git rev-parse --git-path stashed-commits)" if [ $1 ]; then if [ $verbosity -eq 0 ] then git rev-list --reverse "HEAD...$1" >$stashed else git rev-list --reverse "HEAD...$1" | tee $stashed fi else local aborted for commit in $(cat $stashed); do [ $aborted ] && rest+=($commit) && continue [ $verbosity -gt 0 ] && git --no-pager log --oneline -1 $commit git-withdate $commit cherry-pick $commit ${params:0} >/dev/null local last=$? [ $last -gt 0 ] && local aborted=true && typeset -a rest && continue [ $verbosity -gt 0 ] && echo -e "\e[1A$(git log --color=always --pretty=format:"%C(yellow)$(git rev-parse --short 'HEAD^^')%C(bold) -> %Creset%C(yellow)%h%Creset %s" -1)" [ $verbosity -gt 1 ] && git status -s done echo $rest >$stashed [ $aborted ] && echo "A problem was encountered. Fix it and run '$0' again to apply the remaining ${#rest} commits." fi