-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy path.git-helpers
153 lines (131 loc) · 4.57 KB
/
.git-helpers
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#!/bin/bash
# -----------------------------------------------------------------------------
# aliases to avoid the space in gitconfig
alias g='git'
alias gl='git l'
alias gst='git st'
alias gs='git s'
alias gc='git c'
alias gcj='git cj'
alias gcs='git c -S'
alias gdc='git dc'
alias gdcs='git dcs'
alias gd='git d'
alias gds='git ds'
alias gdm='git dm'
alias ga='git a'
alias gf='git f'
alias gu='git u'
alias gut='git ut'
alias gp='git p'
alias gpu='git pu'
alias gpr='git p --rebase'
alias gps='git ps'
alias gt='cd $(git rev-parse --show-toplevel)'
alias gm='git m'
alias gw='git whoami'
alias gws='git ws'
alias gblam='git blam'
# -----------------------------------------------------------------------------
# fuzzy helpers for aliases
# git commit browser
# based on https://gist.github.com/junegunn/f4fca918e937e6bf5bad#gistcomment-1666125
# NB: relies on pager and "git open" alias being set in .gitconfig!
gitlog() {
git log --color=always --no-merges \
--format="%C(auto)%h%d %s <%C(blue)%an%Creset> %C(black)%C(bold)%cr" "$@" |
fzf --ansi --no-sort --reverse --height 100% --tiebreak=index \
--header="enter:show, F3:open, ESC:quit, q:quit-show" \
--bind="ctrl-m:execute:(git show {1} | delta | less -R)" \
--bind="f3:execute:(git open {1})"
}
# git stash browser using fzf
# https://gist.github.com/junegunn/a563d9e3e07fd721d618562762ec619d
gitstash() {
local out k reflog
# shellcheck disable=SC2207,SC2016
out=(
$(git stash list --pretty='%C(yellow)%gd %>(14)%Cgreen%cr %C(blue)%gs' |
fzf --ansi --no-sort --header='enter:show, F3:diff, F4:pop, F5:apply, F6:drop' \
--preview='git stash show --color=always -p $(cut -d" " -f1 <<< {}) | head -'$LINES \
--preview-window=down:50% --reverse \
--bind='enter:execute(git stash show --color=always -p $(cut -d" " -f1 <<< {}) > /dev/tty)' \
--bind='F3:execute(git diff --color=always $(cut -d" " -f1 <<< {}) > /dev/tty)' \
--expect=F4,F5,F6))
k=${out[0]}
reflog=${out[1]}
[ -n "$reflog" ] && case "$k" in
F4) git stash pop "$reflog" ;;
F5) git stash apply "$reflog" ;;
F6) git stash drop "$reflog" ;;
esac
}
gitblame() {
local -r file="${1:-$(fzf)}"
git blame "${file}"
}
# -----------------------------------------------------------------------------
# git for loops to check mass statuses for repos in current dir
# usage glscommand "some command"
# glscommand "git master" -> shows default branches
glscommand() {
local -r command="$1"
dir=$PWD
for d in $(fd . --max-depth 1 --type d); do
cd "$d" || false
echo -en "$(tput setaf 33)${d} "
if [[ -d .git ]]; then
echo -en "$(tput setaf 136)$(zsh -ic "${command}")$(tput sgr0)"
fi
echo
cd ..
done
cd "$dir" || true
}
# ls | git prompt
# re-uses a thing from the non-starship prompt
gls() { glscommand "show_git_differences" ;}
# ls | git whoami
glsd() { glscommand "git whoami" ;}
# -----------------------------------------------------------------------------
# helper that was part of old powerline prompt - now used by gls
show_git_differences() {
[[ $(git rev-parse --is-inside-work-tree 2>/dev/null) == true ]] || return 1
local unmerged=0 modified=0 has_untracked=0 added=0 is_clean=""
# shellcheck disable=SC2046
set -- $(git rev-list --left-right --count "@{upstream}...HEAD" 2>/dev/null)
local behind_count=$1
local ahead_count=$2
# Added (A), Copied (C), Deleted (D), Modified (M), Renamed (R), changed (T), Unmerged (U), Unknown (X), Broken (B)
while read -r line; do
case "$line" in
M*) modified=$(( modified + 1 )) ;;
U*) unmerged=$(( unmerged + 1 )) ;;
esac
done < <(git diff --name-status)
while read -r line; do
case "$line" in
*) added=$(( added + 1 )) ;;
esac
done < <(git diff --name-status --cached)
if [ -n "$(git ls-files --others --exclude-standard)" ]; then
has_untracked=1
fi
local -r stashed=$(( $(git rev-parse --verify refs/stash 2> /dev/null | wc -l) ));
if [ $(( unmerged + modified + has_untracked + added )) -eq 0 ]; then
is_clean=1
fi
local s=""
# We always print at least one of these due to definition of is_clean
# Thus `s` always begins with a leading space
[[ $ahead_count -gt 0 ]] && s+=" ↑$ahead_count"
[[ $behind_count -gt 0 ]] && s+=" ↓$behind_count"
[[ $modified -gt 0 ]] && s+=" +$modified"
[[ $unmerged -gt 0 ]] && s+=" ✗$unmerged"
[[ $added -gt 0 ]] && s+=" ●" #$added
[[ $has_untracked -gt 0 ]] && s+=" …"
[[ $stashed -gt 0 ]] && s+=" ⚑" #$stashed
[[ $is_clean -gt 0 ]] && s+=" ✔"
# remove leading space
echo -e "$s" | sed 's/\s//'
}