-
Notifications
You must be signed in to change notification settings - Fork 7
/
git-rewind-rebase
executable file
·91 lines (72 loc) · 1.95 KB
/
git-rewind-rebase
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
#!/bin/bash
set -e
SCRIPT_FILENAME=$(basename "${BASH_SOURCE[0]}")
ARG_COMMIT=
usage() {
echo -n "\
USAGE:
$SCRIPT_FILENAME [OPTIONS] <commit>
While in an interactive git-rebase, this allows to go back to a previous
commit without losing the changes already done so far.
In other words, it allows the user to do \"multiple passes\" on the
revision range being updated in the same rebase section (i.e. no need to
finish this rebase and start a new one just because of a missed
changed).
This is achieved by hard-reseting to the commit passed as argument, and
prepending the range <commit>..HEAD to the git-rebase's todo file.
OPTIONS:
-h
Show this help message.
"
}
argerr() {
echo "invalid argument: $*" >&2
echo >&2
usage >&2
exit 1
}
parse_args() {
while (( $# > 0 )); do
case "$1" in
-h)
usage
exit 0
;;
-*)
argerr "Unknown option $1."
;;
*)
if [[ -n $ARG_COMMIT ]]; then
argerr "Commit specified more than once."
fi
ARG_COMMIT=$1
;;
esac
shift
done
if [[ -z $ARG_COMMIT ]]; then
argerr "Missing commit to rebase onto."
fi
}
generate_new_todo() {
local git_dir
local todo
local new_todo
git_dir=$(git rev-parse --git-dir)
todo="$git_dir/rebase-merge/git-rebase-todo"
if [ ! -f "$todo" ]; then
echo "Not in an interactive rebase?" > /dev/stderr
exit 1
fi
new_todo=$(mktemp --tmpdir git-rewind-rebase.XXXXXXXXXX)
git log --reverse "$ARG_COMMIT..HEAD" --format="pick %H %s" > "$new_todo"
# insert a break so we are back to the previously stopped place
echo "x echo \"rewind-rebase previously stopped here\"" >> "$new_todo"
echo "break" >> "$new_todo"
cat "$todo" >> "$new_todo"
# replace todo
mv "$new_todo" "$todo"
}
parse_args "$@"
generate_new_todo
git reset --hard "$ARG_COMMIT"