Skip to content

Commit ebb8815

Browse files
committed
feat: porting the script to plain POSIX shell
1 parent fa331bc commit ebb8815

File tree

1 file changed

+44
-31
lines changed

1 file changed

+44
-31
lines changed

git-fixup

Lines changed: 44 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
#!/usr/bin/env bash
1+
#!/bin/sh
2+
# shellcheck disable=SC2059
23
# git-fixup (https://github.com/keis/git-fixup)
34
# We cannot set -u, because included git libraries don't support it.
45
set -e
@@ -29,10 +30,13 @@ SUBDIRECTORY_OK=yes
2930
grok_diff='/^--- .*/p ;
3031
s/^@@ -\([0-9]*\),\([0-9]*\).*/\1 \2/p'
3132

33+
# EOL in the POSIX compatible way
34+
NL="$(printf '\nx')"; NL="${NL%x}"
35+
3236
# Produce suggestion of commits by finding the sections of files with changes
3337
# staged (U1 to diff is used to give some context for when adding items to
3438
# lists etc) and looking up the previous commits touching those sections.
35-
function fixup_candidates_lines () {
39+
fixup_candidates_lines () {
3640
git diff --cached -U1 --no-prefix | sed -n "$grok_diff" | (
3741
file=''
3842
while read -r offs len ; do
@@ -51,7 +55,7 @@ function fixup_candidates_lines () {
5155

5256
# Produce suggestion of commits by taking the latest commit to each file with
5357
# staged changes
54-
function fixup_candidates_files () {
58+
fixup_candidates_files () {
5559
git diff --cached --name-only | (
5660
while read -r file; do
5761
git rev-list -n 1 -E --invert-grep --grep='^(fixup|squash)' "$rev_range" -- "$file"
@@ -60,35 +64,36 @@ function fixup_candidates_files () {
6064
}
6165

6266
# Produce suggestion of all commits in $rev_range
63-
function fixup_candidates_all_commits () {
67+
fixup_candidates_all_commits () {
6468
git rev-list "$rev_range" | sed 's/^/F /g'
6569
}
6670

6771
# Pretty print details of a commit
68-
function print_sha () {
69-
local sha=$1
70-
local type=$2
72+
print_sha () {
73+
sha=$1
74+
type=$2
7175

7276
git --no-pager log --format="%H [$type] %s <%ae>" -n 1 "$sha"
7377
}
7478

7579
# Call git commit
76-
function call_commit() {
77-
local flag=$op
78-
local target=$1
80+
call_commit() {
81+
set -x
82+
flag=$op
83+
target=$1
7984

8085
if [ "$op" = "amend" ] ; then
8186
flag=fixup
8287
target="amend:$target"
8388
fi
8489

8590
# shellcheck disable=SC2086
86-
git commit "${git_commit_args[@]}" "--$flag=$target" || die
91+
git commit ${git_commit_args} "--$flag=$target" || die
8792
}
8893

8994
# Call git rebase
90-
function call_rebase() {
91-
local target=$1
95+
call_rebase() {
96+
target=$1
9297

9398
# If our target-commit has a parent, we call a rebase with that
9499
# shellcheck disable=SC1083
@@ -102,42 +107,53 @@ function call_rebase() {
102107
}
103108

104109
# Print list of fixup/squash candidates
105-
function print_candidates() {
110+
print_candidates() {
106111
(
107112
if [ "$show_all" = "false" ] ; then
108113
fixup_candidates_lines
109114
fixup_candidates_files
110115
else
111116
fixup_candidates_all_commits
112117
fi
113-
) | sort -uk2 | while read -r type sha; do
118+
) | sort -uk2 | while read -r type sha ; do
114119
if [ -n "$sha" ] ; then
115120
print_sha "$sha" "$type"
116121
fi
117122
done
118123
}
119124

120-
function fallback_menu() {
125+
fallback_menu() {
121126
(
122-
IFS=$'\n'
123-
read -d '' -ra options
124-
PS3="Which commit should I $op? "
125-
select line in "${options[@]}"; do
126-
if [ -z "$line" ] ; then
127-
declare -a args=("$REPLY")
128-
case ${args[0]} in
127+
IFS="$NL"
128+
counter=0
129+
TMPINPUT="$(mktemp --tmpdir gitfixup-menu-XXXX)"
130+
trap 'rm -f "$TMPINPUT"' EXIT
131+
cat >"$TMPINPUT"
132+
133+
while read -r line ; do
134+
counter=$((counter + 1))
135+
printf "%d) %s\n" $counter "$line" >&2
136+
done < "$TMPINPUT"
137+
printf "Which commit should I fixup? " >&2
138+
while read -r REPLY ; do
139+
if ( printf "%s\n" "$REPLY" | grep -q "^[0-9]\+$" ) && [ "$REPLY" -le "$counter" ] ; then
140+
printf "%s\n" "$(sed -n -e "${REPLY}p" "$TMPINPUT")"
141+
break
142+
else
143+
args="${REPLY%% *}"
144+
case ${args} in
129145
quit|q)
130146
echo "Alright, no action taken." >&2
131147
break
132148
;;
133149
show|s)
134-
idx=$((args[1] - 1))
150+
idx="${REPLY#"$args" *}"
135151
if [ "$idx" -ge 0 ] ; then
136-
git show "${options[$idx]%% *}" >&2
152+
git show "$(awk 'FNR == '"${idx}"' {print $1}' "$TMPINPUT")" >&2
137153
fi
138154
;;
139155
help|h)
140-
local fmt="%s\n %s\n"
156+
fmt="%s\n %s\n"
141157
# shellcheck disable=SC2059
142158
printf "$fmt" "<n>" "$op the <n>-th commit from the list" >&2
143159
# shellcheck disable=SC2059
@@ -148,9 +164,6 @@ function fallback_menu() {
148164
printf "$fmt" "h[elp]" "show this help message" >&2
149165
;;
150166
esac
151-
else
152-
echo "$line"
153-
break
154167
fi
155168
done < /dev/tty
156169
)
@@ -164,7 +177,7 @@ show_menu () {
164177
fi
165178
}
166179

167-
git_commit_args=()
180+
git_commit_args=""
168181
target=
169182
op=${GITFIXUPACTION:-$(git config --default=fixup fixup.action)}
170183
rebase=${GITFIXUPREBASE:-$(git config --default=false fixup.rebase)}
@@ -197,7 +210,7 @@ while [ $# -gt 0 ] ; do
197210
rebase=false
198211
;;
199212
-n|--no-verify)
200-
git_commit_args+=("$1")
213+
git_commit_args="$git_commit_args $1"
201214
;;
202215
-b|--base)
203216
shift

0 commit comments

Comments
 (0)