Browse Source

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>
maint
Nanako Shiraishi 16 years ago committed by Shawn O. Pearce
parent
commit
d70b4a8f4b
  1. 11
      git-rebase--interactive.sh
  2. 18
      git-rebase.sh
  3. 126
      t/t3409-rebase-hook.sh

11
git-rebase--interactive.sh

@ -65,6 +65,16 @@ output () {
esac 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 () { require_clean_work_tree () {
# test if working tree is dirty # test if working tree is dirty
git rev-parse --verify HEAD > /dev/null && git rev-parse --verify HEAD > /dev/null &&
@ -507,6 +517,7 @@ first and then run 'git rebase --continue' again."
;; ;;
--) --)
shift shift
run_pre_rebase_hook ${1+"$@"}
test $# -eq 1 -o $# -eq 2 || usage test $# -eq 1 -o $# -eq 2 || usage
test -d "$DOTEST" && test -d "$DOTEST" &&
die "Interactive rebase already started" die "Interactive rebase already started"

18
git-rebase.sh

@ -144,6 +144,16 @@ is_interactive () {
done && test -n "$1" 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 && test -f "$GIT_DIR"/rebase-apply/applying &&
die 'It looks like git-am is in progress. Cannot rebase.' die 'It looks like git-am is in progress. Cannot rebase.'


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


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


# If the branch to rebase is given, that is the branch we will rebase # If the branch to rebase is given, that is the branch we will rebase
# $branch_name -- branch being rebased, or HEAD (already detached) # $branch_name -- branch being rebased, or HEAD (already detached)

126
t/t3409-rebase-hook.sh

@ -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
Loading…
Cancel
Save