Created
October 14, 2011 15:25
-
-
Save hchbaw/1287423 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
#!/bin/zsh | |
dashless=${${0:t}/-/ } | |
USAGE="[-f|--force] [-s|--stashify] <commit>..." | |
LONG_USAGE="$dashless <commit>... | |
save <commit>... in the stash ref namespace. | |
Basically $dashless deals with stashed <commit> but it could be: | |
[-f|--force] force operation | |
[-s|--stashify][-2] convert existing <commit> as if it were stashed. | |
[-2] means create stash as the base commit <commit>~2, | |
<commit>~1 as the index and <commit> as the work tree. | |
default: base commit <commit>~1, and <commit> as index | |
and work tree. (In other words, assume index and work | |
tree are being kept intact.)" | |
typeset -a _A; set -A _A "$@" | |
_0="${0-}" | |
() { | |
() { | |
local 0=${_0} | |
set -- "${_A[@]}" | |
emulate -L sh | |
OPTIONS_SPEC= | |
SUBDIRECTORY_OK=t | |
. git-sh-setup | |
require_work_tree | |
cd_to_toplevel | |
} | |
eval "die_with_status () { ${functions[die_with_status]//status/_status} }" | |
} | |
git-stash~ () { | |
local stashproc="$1"; shift | |
local stashishp="$1"; shift | |
local gitstash_refstash=refs/stash | |
local c=; for c in "$@"; do | |
git-stash~~ $stashproc $stashishp "$c" git-stash~~-update-ref | |
done | |
} | |
git-stash~~ () { | |
local stashf="$1" | |
local stashp="$2" | |
local commitish="$3" | |
local k="$4" | |
setopt localoptions no_ksharrays no_kshzerosubscript extendedglob | |
local commit="$(git rev-parse "$commitish" 2> /dev/null)" || | |
die "commit '$commitish' doesn't exist" | |
"$stashf" "$stashp" "$commit" "$commitish" "$k" | |
} | |
git-stash~~-update-ref () { | |
local stashmsg="$1" | |
local stashcommit="$2" | |
local commit="$3" | |
local abbrevcommit="$(git rev-parse --short $commit)" | |
: >>"$GIT_DIR/logs/$gitstash_refstash" | |
git update-ref -m "$stashmsg" $gitstash_refstash $stashcommit || | |
die "Cannot save the commit status" | |
say Saved stashish commit $abbrevcommit "$stashmsg" | |
} | |
git-stash~-restash () { | |
local stashp="$1" | |
local commit="$2" | |
local commitish="$3" | |
local k="$4" | |
local -a cs; : ${(A)cs::=${(@f)"$(git log -3 -s --format=%s ${commit})"}} | |
"$stashp" "$cs[@]" && { | |
"$k" "$cs[1]" "$commit" "$commit" | |
} || die "'$commitish' doesn't seem like stash" | |
} | |
git-stash~-stashify-1-raw () { | |
local commit="$1" | |
local k="$2" | |
local kk="$3" | |
local wtree= icommit= imesg= bcommit= bmesg= | |
local -a tmp; | |
git-stash~-stashify-fetch-commit-or-lose tmp '%H%n%s\ \(%h\)%n%T' "${commit}" | |
icommit="$tmp[2]"; imesg="$tmp[3]"; wtree="$tmp[4]" | |
# TODO: tweak the commit here. | |
git-stash~-stashify-fetch-commit-or-lose tmp '%H%n%s\ \(%h\)' "${commit}~1" | |
bcommit="$tmp[2]"; bmesg="$tmp[3]" | |
"$k" "WIP $imesg; $bmesg" $wtree $bcommit $icommit "$kk" | |
} | |
git-stash~-stashify-2-raw () { | |
local commit="$1" | |
local k="$2" | |
local kk="$3" | |
local wtree= wmesg= icommit= imesg= bcommit= bmesg= | |
local -a tmp; | |
# TODO: tweak the commit. | |
git-stash~-stashify-fetch-commit-or-lose tmp '%T%n%s\ \(%h\)' ${commit} | |
wtree="$tmp[2]"; wmesg="$tmp[3]" | |
git-stash~-stashify-fetch-commit-or-lose tmp '%H%n%s\ \(%h\)' "${commit}~1" | |
icommit="$tmp[2]"; imesg="$tmp[3]" | |
git-stash~-stashify-fetch-commit-or-lose tmp '%H%n%s\ \(%h\)' "${commit}~2" | |
bcommit="$tmp[2]"; bmesg="$tmp[3]" | |
"$k" "WIP $wmesg; $imesg; $bmesg" $wtree $bcommit $icommit "$kk" | |
} | |
git-stash~-stashify-fetch-commit-or-lose () { | |
local place="$1" | |
local fmt="$2" | |
local c="$3" | |
: ${(PA)place::=${(@f)"$(git rev-list --no-walk --format=${(Q)fmt} $c)"}} | |
[[ ${${(PA)place}[1]} == (#s)commit\ * ]] || | |
die "Cannot fetch the commit '$c'." | |
} | |
git-stash~-stashify-k () { | |
local stashmsg="$1" | |
local wtree="$2" | |
local bcommit="$3" | |
local icommit="$4" | |
local k="$5" | |
local commitmaybe=$(echo "$stashmsg"| | |
git commit-tree $wtree -p $bcommit -p $icommit) || | |
die "Cannot record stashified commit" | |
"$k" "$stashmsg" "$commitmaybe" "$commit" | |
} | |
def-git-stash~-stashify-n () { | |
eval ${${:-' | |
git-stash~-stashify-_N_ () { | |
local _stashp="$1" | |
local commit="$2" | |
local _commitish="$3" | |
local k="$4" | |
git-stash~-stashify-_N_-raw "$commit" git-stash~-stashify-k "$k" | |
} | |
'}//_N_/$1} | |
} | |
def-git-stash~-stashify-n 2 | |
def-git-stash~-stashify-n 1 | |
git-stash~-stashish-p () { | |
# XXX: This may not be accurate though | |
[[ -n "${1-}" ]] && [[ "${1}" == (#s)WIP\ on* ]] && | |
[[ -n "${2-}" ]] && [[ "${2}" == (#s)index\ on* ]] && | |
[[ -n "${3-}" ]] | |
} | |
zparseopts -E -D \ | |
f=force -force=force s=stashify -stashify=stashify 2=grandparentasbase | |
(($#==0)) && usage | |
if [[ -z "${force}" ]]; then | |
set -- git-stash~-stashish-p "$@" | |
else | |
set -- : "$@" | |
fi | |
if [[ -z "${stashify}" ]]; then | |
set -- git-stash~-restash "$@" | |
else | |
if [[ -z "${grandparentasbase}" ]]; then | |
set -- git-stash~-stashify-1 "$@" | |
else | |
set -- git-stash~-stashify-2 "$@" | |
fi | |
fi | |
git-stash~ "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment