Teach rebase -i to honor pre-rebase hook
The original git-rebase honored pre-rebase hook so that public branches can be protected from getting rebased, but rebase --interactive ignored the hook entirely. This fixes it. Signed-off-by: Nanako Shiraishi <nanako3@lavabit.com> Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Nanako Shiraishi committed
Oct 6, 2008 at 14:14 UTC
d70b4a8f4ba79fb83dc95e9483f9fb3feaf578b7
3 files changed
+148
-7
git-rebase--interactive.sh
+11
@@ -65,6 +65,16 @@ output () {
65
esac
66
}
67
68
+run_pre_rebase_hook () {
69
+ if test -x "$GIT_DIR/hooks/pre-rebase"
70
+ then
71
+ "$GIT_DIR/hooks/pre-rebase" ${1+"$@"} || {
72
+ echo >&2 "The pre-rebase hook refused to rebase."
73
+ exit 1
74
+ }
75
+ fi
76
+}
77
+
78
require_clean_work_tree () {
79
# test if working tree is dirty
80
git rev-parse --verify HEAD > /dev/null &&
@@ -507,6 +517,7 @@ first and then run 'git rebase --continue' again."
517
;;
518
--)
519
shift
520
+ run_pre_rebase_hook ${1+"$@"}
521
test $# -eq 1 -o $# -eq 2 || usage
522
test -d "$DOTEST" &&
523
die "Interactive rebase already started"
git-rebase.sh
+11
-7
@@ -144,6 +144,16 @@ is_interactive () {
144
done && test -n "$1"
145
}
146
147
+run_pre_rebase_hook () {
148
+ if test -x "$GIT_DIR/hooks/pre-rebase"
149
+ then
150
+ "$GIT_DIR/hooks/pre-rebase" ${1+"$@"} || {
151
+ echo >&2 "The pre-rebase hook refused to rebase."
152
+ exit 1
153
+ }
154
+ fi
155
+}
156
+
157
test -f "$GIT_DIR"/rebase-apply/applying &&
158
die 'It looks like git-am is in progress. Cannot rebase.'
159
@@ -320,13 +330,7 @@ onto_name=${newbase-"$upstream_name"}
330
onto=$(git rev-parse --verify "${onto_name}^0") || exit
331
332
# If a hook exists, give it a chance to interrupt
323
-if test -x "$GIT_DIR/hooks/pre-rebase"
324
-then
325
- "$GIT_DIR/hooks/pre-rebase" ${1+"$@"} || {
326
- echo >&2 "The pre-rebase hook refused to rebase."
327
- exit 1
328
- }
329
-fi
333
+run_pre_rebase_hook ${1+"$@"}
334
335
# If the branch to rebase is given, that is the branch we will rebase
336
# $branch_name -- branch being rebased, or HEAD (already detached)
t/t3409-rebase-hook.sh
new
+126
@@ -0,0 +1,126 @@
1
+#!/bin/sh
2
+
3
+test_description='git rebase with its hook(s)'
4
+
5
+. ./test-lib.sh
6
+
7
+test_expect_success setup '
8
+ echo hello >file &&
9
+ git add file &&
10
+ test_tick &&
11
+ git commit -m initial &&
12
+ echo goodbye >file &&
13
+ git add file &&
14
+ test_tick &&
15
+ git commit -m second &&
16
+ git checkout -b side HEAD^ &&
17
+ echo world >git &&
18
+ git add git &&
19
+ test_tick &&
20
+ git commit -m side &&
21
+ git checkout master &&
22
+ git log --pretty=oneline --abbrev-commit --graph --all &&
23
+ git branch test side
24
+'
25
+
26
+test_expect_success 'rebase' '
27
+ git checkout test &&
28
+ git reset --hard side &&
29
+ git rebase master &&
30
+ test "z$(cat git)" = zworld
31
+'
32
+
33
+test_expect_success 'rebase -i' '
34
+ git checkout test &&
35
+ git reset --hard side &&
36
+ EDITOR=true git rebase -i master &&
37
+ test "z$(cat git)" = zworld
38
+'
39
+
40
+test_expect_success 'setup pre-rebase hook' '
41
+ mkdir -p .git/hooks &&
42
+ cat >.git/hooks/pre-rebase <<EOF &&
43
+#!$SHELL_PATH
44
+echo "\$1,\$2" >.git/PRE-REBASE-INPUT
45
+EOF
46
+ chmod +x .git/hooks/pre-rebase
47
+'
48
+
49
+test_expect_success 'pre-rebase hook gets correct input (1)' '
50
+ git checkout test &&
51
+ git reset --hard side &&
52
+ git rebase master &&
53
+ test "z$(cat git)" = zworld &&
54
+ test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,
55
+
56
+'
57
+
58
+test_expect_success 'pre-rebase hook gets correct input (2)' '
59
+ git checkout test &&
60
+ git reset --hard side &&
61
+ git rebase master test &&
62
+ test "z$(cat git)" = zworld &&
63
+ test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,test
64
+'
65
+
66
+test_expect_success 'pre-rebase hook gets correct input (3)' '
67
+ git checkout test &&
68
+ git reset --hard side &&
69
+ git checkout master &&
70
+ git rebase master test &&
71
+ test "z$(cat git)" = zworld &&
72
+ test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,test
73
+'
74
+
75
+test_expect_success 'pre-rebase hook gets correct input (4)' '
76
+ git checkout test &&
77
+ git reset --hard side &&
78
+ EDITOR=true git rebase -i master &&
79
+ test "z$(cat git)" = zworld &&
80
+ test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,
81
+
82
+'
83
+
84
+test_expect_success 'pre-rebase hook gets correct input (5)' '
85
+ git checkout test &&
86
+ git reset --hard side &&
87
+ EDITOR=true git rebase -i master test &&
88
+ test "z$(cat git)" = zworld &&
89
+ test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,test
90
+'
91
+
92
+test_expect_success 'pre-rebase hook gets correct input (6)' '
93
+ git checkout test &&
94
+ git reset --hard side &&
95
+ git checkout master &&
96
+ EDITOR=true git rebase -i master test &&
97
+ test "z$(cat git)" = zworld &&
98
+ test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,test
99
+'
100
+
101
+test_expect_success 'setup pre-rebase hook that fails' '
102
+ mkdir -p .git/hooks &&
103
+ cat >.git/hooks/pre-rebase <<EOF &&
104
+#!$SHELL_PATH
105
+false
106
+EOF
107
+ chmod +x .git/hooks/pre-rebase
108
+'
109
+
110
+test_expect_success 'pre-rebase hook stops rebase (1)' '
111
+ git checkout test &&
112
+ git reset --hard side &&
113
+ test_must_fail git rebase master &&
114
+ test "z$(git symbolic-ref HEAD)" = zrefs/heads/test &&
115
+ test 0 = $(git rev-list HEAD...side | wc -l)
116
+'
117
+
118
+test_expect_success 'pre-rebase hook stops rebase (2)' '
119
+ git checkout test &&
120
+ git reset --hard side &&
121
+ EDITOR=true test_must_fail git rebase -i master &&
122
+ test "z$(git symbolic-ref HEAD)" = zrefs/heads/test &&
123
+ test 0 = $(git rev-list HEAD...side | wc -l)
124
+'
125
+
126
+test_done