Skip to content
This repository has been archived by the owner on Nov 9, 2017. It is now read-only.

Commit

Permalink
Teach rebase -i to honor pre-rebase hook
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Nanako Shiraishi authored and spearce committed Oct 6, 2008
1 parent 00e5d48 commit d70b4a8
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 7 deletions.
11 changes: 11 additions & 0 deletions git-rebase--interactive.sh
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,16 @@ output () {
esac
}

run_pre_rebase_hook () {
if test -x "$GIT_DIR/hooks/pre-rebase"
then
"$GIT_DIR/hooks/pre-rebase" ${1+"$@"} || {
echo >&2 "The pre-rebase hook refused to rebase."
exit 1
}
fi
}

require_clean_work_tree () {
# test if working tree is dirty
git rev-parse --verify HEAD > /dev/null &&
Expand Down Expand Up @@ -507,6 +517,7 @@ first and then run 'git rebase --continue' again."
;;
--)
shift
run_pre_rebase_hook ${1+"$@"}
test $# -eq 1 -o $# -eq 2 || usage
test -d "$DOTEST" &&
die "Interactive rebase already started"
Expand Down
18 changes: 11 additions & 7 deletions git-rebase.sh
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,16 @@ is_interactive () {
done && test -n "$1"
}

run_pre_rebase_hook () {
if test -x "$GIT_DIR/hooks/pre-rebase"
then
"$GIT_DIR/hooks/pre-rebase" ${1+"$@"} || {
echo >&2 "The pre-rebase hook refused to rebase."
exit 1
}
fi
}

test -f "$GIT_DIR"/rebase-apply/applying &&
die 'It looks like git-am is in progress. Cannot rebase.'

Expand Down Expand Up @@ -320,13 +330,7 @@ onto_name=${newbase-"$upstream_name"}
onto=$(git rev-parse --verify "${onto_name}^0") || exit

# If a hook exists, give it a chance to interrupt
if test -x "$GIT_DIR/hooks/pre-rebase"
then
"$GIT_DIR/hooks/pre-rebase" ${1+"$@"} || {
echo >&2 "The pre-rebase hook refused to rebase."
exit 1
}
fi
run_pre_rebase_hook ${1+"$@"}

# If the branch to rebase is given, that is the branch we will rebase
# $branch_name -- branch being rebased, or HEAD (already detached)
Expand Down
126 changes: 126 additions & 0 deletions t/t3409-rebase-hook.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#!/bin/sh

test_description='git rebase with its hook(s)'

. ./test-lib.sh

test_expect_success setup '
echo hello >file &&
git add file &&
test_tick &&
git commit -m initial &&
echo goodbye >file &&
git add file &&
test_tick &&
git commit -m second &&
git checkout -b side HEAD^ &&
echo world >git &&
git add git &&
test_tick &&
git commit -m side &&
git checkout master &&
git log --pretty=oneline --abbrev-commit --graph --all &&
git branch test side
'

test_expect_success 'rebase' '
git checkout test &&
git reset --hard side &&
git rebase master &&
test "z$(cat git)" = zworld
'

test_expect_success 'rebase -i' '
git checkout test &&
git reset --hard side &&
EDITOR=true git rebase -i master &&
test "z$(cat git)" = zworld
'

test_expect_success 'setup pre-rebase hook' '
mkdir -p .git/hooks &&
cat >.git/hooks/pre-rebase <<EOF &&
#!$SHELL_PATH
echo "\$1,\$2" >.git/PRE-REBASE-INPUT
EOF
chmod +x .git/hooks/pre-rebase
'

test_expect_success 'pre-rebase hook gets correct input (1)' '
git checkout test &&
git reset --hard side &&
git rebase master &&
test "z$(cat git)" = zworld &&
test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,
'

test_expect_success 'pre-rebase hook gets correct input (2)' '
git checkout test &&
git reset --hard side &&
git rebase master test &&
test "z$(cat git)" = zworld &&
test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,test
'

test_expect_success 'pre-rebase hook gets correct input (3)' '
git checkout test &&
git reset --hard side &&
git checkout master &&
git rebase master test &&
test "z$(cat git)" = zworld &&
test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,test
'

test_expect_success 'pre-rebase hook gets correct input (4)' '
git checkout test &&
git reset --hard side &&
EDITOR=true git rebase -i master &&
test "z$(cat git)" = zworld &&
test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,
'

test_expect_success 'pre-rebase hook gets correct input (5)' '
git checkout test &&
git reset --hard side &&
EDITOR=true git rebase -i master test &&
test "z$(cat git)" = zworld &&
test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,test
'

test_expect_success 'pre-rebase hook gets correct input (6)' '
git checkout test &&
git reset --hard side &&
git checkout master &&
EDITOR=true git rebase -i master test &&
test "z$(cat git)" = zworld &&
test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,test
'

test_expect_success 'setup pre-rebase hook that fails' '
mkdir -p .git/hooks &&
cat >.git/hooks/pre-rebase <<EOF &&
#!$SHELL_PATH
false
EOF
chmod +x .git/hooks/pre-rebase
'

test_expect_success 'pre-rebase hook stops rebase (1)' '
git checkout test &&
git reset --hard side &&
test_must_fail git rebase master &&
test "z$(git symbolic-ref HEAD)" = zrefs/heads/test &&
test 0 = $(git rev-list HEAD...side | wc -l)
'

test_expect_success 'pre-rebase hook stops rebase (2)' '
git checkout test &&
git reset --hard side &&
EDITOR=true test_must_fail git rebase -i master &&
test "z$(git symbolic-ref HEAD)" = zrefs/heads/test &&
test 0 = $(git rev-list HEAD...side | wc -l)
'

test_done

0 comments on commit d70b4a8

Please sign in to comment.