summaryrefslogtreecommitdiff
path: root/git-rebase--interactive.sh
diff options
context:
space:
mode:
authorThomas Rast <trast@student.ethz.ch>2010-03-12 17:04:30 (GMT)
committerJunio C Hamano <gitster@pobox.com>2010-03-13 05:55:39 (GMT)
commitb079feed64238558fa24ba8ade892d84628a05ac (patch)
treeb9c518a1135141e6594fc68eed77db22b51805a8 /git-rebase--interactive.sh
parent96e19488f1e8f3964f5f329248852864b4ee4541 (diff)
downloadgit-b079feed64238558fa24ba8ade892d84628a05ac.zip
git-b079feed64238558fa24ba8ade892d84628a05ac.tar.gz
git-b079feed64238558fa24ba8ade892d84628a05ac.tar.bz2
rebase -i: invoke post-rewrite hook
Aside from the same issue that rebase also has (remembering the original commit across a conflict resolution), rebase -i brings an extra twist: We need to defer writing the rewritten list in the case of {squash,fixup} because their rewritten result should be the last commit in the squashed group. Signed-off-by: Thomas Rast <trast@student.ethz.ch> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'git-rebase--interactive.sh')
-rwxr-xr-xgit-rebase--interactive.sh46
1 files changed, 45 insertions, 1 deletions
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 4a69c38..d72f549 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -96,6 +96,13 @@ AUTHOR_SCRIPT="$DOTEST"/author-script
# command is processed, this file is deleted.
AMEND="$DOTEST"/amend
+# For the post-rewrite hook, we make a list of rewritten commits and
+# their new sha1s. The rewritten-pending list keeps the sha1s of
+# commits that have been processed, but not committed yet,
+# e.g. because they are waiting for a 'squash' command.
+REWRITTEN_LIST="$DOTEST"/rewritten-list
+REWRITTEN_PENDING="$DOTEST"/rewritten-pending
+
PRESERVE_MERGES=
STRATEGY=
ONTO=
@@ -198,6 +205,7 @@ make_patch () {
}
die_with_patch () {
+ echo "$1" > "$DOTEST"/stopped-sha
make_patch "$1"
git rerere
die "$2"
@@ -348,6 +356,7 @@ pick_one_preserving_merges () {
printf "%s\n" "$msg" > "$GIT_DIR"/MERGE_MSG
die_with_patch $sha1 "Error redoing merge $sha1"
fi
+ echo "$sha1 $(git rev-parse HEAD^0)" >> "$REWRITTEN_LIST"
;;
*)
output git cherry-pick "$@" ||
@@ -425,6 +434,26 @@ die_failed_squash() {
die_with_patch $1 ""
}
+flush_rewritten_pending() {
+ test -s "$REWRITTEN_PENDING" || return
+ newsha1="$(git rev-parse HEAD^0)"
+ sed "s/$/ $newsha1/" < "$REWRITTEN_PENDING" >> "$REWRITTEN_LIST"
+ rm -f "$REWRITTEN_PENDING"
+}
+
+record_in_rewritten() {
+ oldsha1="$(git rev-parse $1)"
+ echo "$oldsha1" >> "$REWRITTEN_PENDING"
+
+ case "$(peek_next_command)" in
+ squash|s|fixup|f)
+ ;;
+ *)
+ flush_rewritten_pending
+ ;;
+ esac
+}
+
do_next () {
rm -f "$MSG" "$AUTHOR_SCRIPT" "$AMEND" || exit
read command sha1 rest < "$TODO"
@@ -438,6 +467,7 @@ do_next () {
mark_action_done
pick_one $sha1 ||
die_with_patch $sha1 "Could not apply $sha1... $rest"
+ record_in_rewritten $sha1
;;
reword|r)
comment_for_reflog reword
@@ -446,6 +476,7 @@ do_next () {
pick_one $sha1 ||
die_with_patch $sha1 "Could not apply $sha1... $rest"
git commit --amend --no-post-rewrite
+ record_in_rewritten $sha1
;;
edit|e)
comment_for_reflog edit
@@ -453,6 +484,7 @@ do_next () {
mark_action_done
pick_one $sha1 ||
die_with_patch $sha1 "Could not apply $sha1... $rest"
+ echo "$1" > "$DOTEST"/stopped-sha
make_patch $sha1
git rev-parse --verify HEAD > "$AMEND"
warn "Stopped at $sha1... $rest"
@@ -509,6 +541,7 @@ do_next () {
rm -f "$SQUASH_MSG" "$FIXUP_MSG"
;;
esac
+ record_in_rewritten $sha1
;;
*)
warn "Unknown command: $command $sha1 $rest"
@@ -537,6 +570,11 @@ do_next () {
test ! -f "$DOTEST"/verbose ||
git diff-tree --stat $(cat "$DOTEST"/head)..HEAD
} &&
+ if test -x "$GIT_DIR"/hooks/post-rewrite &&
+ test -s "$REWRITTEN_LIST"; then
+ "$GIT_DIR"/hooks/post-rewrite rebase < "$REWRITTEN_LIST"
+ true # we don't care if this hook failed
+ fi &&
rm -rf "$DOTEST" &&
git gc --auto &&
warn "Successfully rebased and updated $HEADNAME."
@@ -571,7 +609,12 @@ skip_unnecessary_picks () {
esac
echo "$command${sha1:+ }$sha1${rest:+ }$rest" >&$fd
done <"$TODO" >"$TODO.new" 3>>"$DONE" &&
- mv -f "$TODO".new "$TODO" ||
+ mv -f "$TODO".new "$TODO" &&
+ case "$(peek_next_command)" in
+ squash|s|fixup|f)
+ record_in_rewritten "$ONTO"
+ ;;
+ esac ||
die "Could not skip unnecessary pick commands"
}
@@ -685,6 +728,7 @@ first and then run 'git rebase --continue' again."
test -n "$amend" && git reset --soft $amend
die "Could not commit staged changes."
}
+ record_in_rewritten "$(cat "$DOTEST"/stopped-sha)"
fi
require_clean_work_tree