-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathgit_query.sh
184 lines (179 loc) · 6.3 KB
/
git_query.sh
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#!/usr/bin/env bash
#
# helper functions to obtain git related information
#######################################
# let user select a commit interactively
# Arguments:
# $1: the helper message to display in the fzf header
# $2: files to show diff against HEAD
# Outputs:
# the selected commit 6 char code
# e.g. b60b330
#######################################
# TODO: line33 "${files[*]}" cannot handle space in file names, but "${files[@]}" won't get properly
# processed by git for whatever reason just in this preview situation but works every where else, HELP needed.
# although this won't affect any real functionality or break the code, it will just print a error message in preview.
function get_commit() {
local header="${1:-select a commit}"
local files=("${@:2}")
if [[ "${#files[@]}" -eq 0 ]]; then
/usr/bin/git --git-dir="${DOTBARE_DIR}" --work-tree="${DOTBARE_TREE}" \
log --oneline --color=always --decorate=short \
| fzf --no-multi --header="${header}" \
--preview "echo {} \
| awk '{print \$1}' \
| xargs -I __ /usr/bin/git --git-dir=${DOTBARE_DIR} --work-tree=${DOTBARE_TREE} \
show --color=always __" \
| awk '{print $1}'
else
/usr/bin/git --git-dir="${DOTBARE_DIR}" --work-tree="${DOTBARE_TREE}" \
log --oneline --color=always --decorate=short \
| fzf --no-multi --header="${header}" --preview "echo {} \
| awk '{print \$1}' \
| xargs -I __ /usr/bin/git --git-dir=${DOTBARE_DIR} --work-tree=${DOTBARE_TREE} \
diff --color=always __ ${files[*]}" \
| awk '{print $1}'
fi
}
#######################################
# let user select a branch interactively
# Arguments:
# $1: the helper message to display in the fzf header
# Outputs:
# the selected branch name
# e.g. master
#######################################
function get_branch() {
local header="${1:-select a branch}"
/usr/bin/git --git-dir="${DOTBARE_DIR}" --work-tree="${DOTBARE_TREE}" branch -a \
| awk '{
if ($0 ~ /\*.*\(HEAD.*/) {
gsub(/\* /, "", $0)
print "\033[32m" $0 "\033[0m"
} else if (match($1, "\\*") != 0) {
print "\033[32m" $2 "\033[0m"
} else if ($0 ~ /^[ \t]+remotes\/.*/) {
gsub(/[ \t]+/, "", $0)
print "\033[31m" $0 "\033[0m"
} else {
gsub(/^[ \t]+/, "", $0)
print $0
}
}' \
| fzf --no-multi --header="${header}" \
--preview="echo {} \
| awk '{
if (\$0 ~ /.*HEAD.*/) {
print \"HEAD\"
} else {
print \$0
}
}' \
| xargs -I __ /usr/bin/git --git-dir=${DOTBARE_DIR} --work-tree=${DOTBARE_TREE} \
log --oneline --graph --color=always --decorate=short __"
}
#######################################
# let user select a dotbare tracked file interactively
# Arguments:
# $1: the helper message to display in the fzf header
# $2: print option, values (full|raw)
# $3: if exist, don't do multi selection, do single
# Outputs:
# the selected file path
# e.g.$HOME/.config/nvim/init.vim
#######################################
function get_git_file() {
local header="${1:-select tracked file}"
local print_opt="${2:-full}"
set_fzf_multi "$3"
/usr/bin/git --git-dir="${DOTBARE_DIR}" --work-tree="${DOTBARE_TREE}" \
ls-files --full-name --directory "${DOTBARE_TREE}" \
| fzf --header="${header}" \
--preview "cat ${DOTBARE_TREE}/{}" \
| awk -v home="${DOTBARE_TREE}" -v print_opt="${print_opt}" '{
if (print_opt == "full") {
print home "/" $0
} else {
print $0
}
}'
}
#######################################
# let user select a modified file interactively
# Arguments:
# $1: the helper message to display in the fzf header
# $2: display mode of modified files.
# default: true
# all: display all modified, include staged and unstaged
# staged: display only staged files
# unstaged: display only unstaged files
# $3: output_format
# default: name
# name: formatted name of the file
# raw: raw file name with status
# $4: if exists, don't do multi selection, do single
# Outputs:
# the selected file path
# e.g.$HOME/.config/nvim/init.vim
#######################################
function get_modified_file() {
local header="${1:-select a modified file}"
local display_mode="${2:-all}"
local output_format="${3:-name}"
set_fzf_multi "$4"
/usr/bin/git --git-dir="${DOTBARE_DIR}" --work-tree="${DOTBARE_TREE}" \
status --porcelain \
| awk -v display_mode="${display_mode}" '{
if ($0 ~ /^[A-Za-z][A-Za-z].*$/) {
print "\033[32m" substr($0, 1, 1) "\033[31m" substr($0, 2) "\033[0m"
} else if ($0 ~ /^[A-Za-z][ \t].*$/) {
if (display_mode == "all" || display_mode == "staged") {
print "\033[32m" $0 "\033[0m"
}
} else {
if (display_mode == "all" || display_mode == "unstaged") {
print "\033[31m" $0 "\033[0m"
}
}
}' \
| fzf --header="${header}" --preview "echo {} \
| awk '{sub(\$1 FS,\"\");print \$0}' \
| xargs -I __ /usr/bin/git --git-dir=${DOTBARE_DIR} --work-tree=${DOTBARE_TREE} \
diff HEAD --color=always -- ${DOTBARE_TREE}/__" \
| awk -v home="${DOTBARE_TREE}" -v format="${output_format}" '{
if (format == "name") {
$1=""
gsub(/^[ \t]/, "", $0)
gsub(/"/, "", $0)
print home "/" $0
} else {
print $0
}
}'
}
#######################################
# let user select a stash interactively
# Arguments:
# $1: the helpe message to display in header
# $2: if exists, don't do multi select, only allow single selection
# Outputs:
# the selected stash identifier
# e.g. stash@{0}
#######################################
function get_stash() {
local header="${1:-select a stash}"
set_fzf_multi "$2"
/usr/bin/git --git-dir="${DOTBARE_DIR}" --work-tree="${DOTBARE_TREE}" \
stash list \
| fzf --header="${header}" --preview "echo {} \
| awk '{
gsub(/:/, \"\", \$1)
print \$1
}' \
| xargs -I __ /usr/bin/git --git-dir=${DOTBARE_DIR} --work-tree=${DOTBARE_TREE} \
show -p __ --color=always" \
| awk '{
gsub(/:/, "", $1)
print $1
}'
}