diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 531ee94..c0abc01 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -35,6 +35,8 @@ mark the corrected paths with 'git add <paths>', and
run 'git rebase --continue'"
export GIT_CHERRY_PICK_HELP
+mark_prefix=refs/rebase-marks/
+
warn () {
echo "$*" >&2
}@@ -105,6 +107,10 @@ die_with_patch () {
}
cleanup_before_quit () {
+ for ref in $(git for-each-ref --format='%(refname)' "${mark_prefix%/}")
+ do
+ git update-ref -d "$ref" "$ref" || return 1
+ done
rm -rf "$DOTEST"
}
@@ -244,6 +250,15 @@ peek_next_command () {
sed -n "1s/ .*$//p" < "$TODO"
}
+mark_to_ref () {
+ if expr match "$1" "^:[0-9][0-9]*$" >/dev/null
+ then
+ echo "$mark_prefix$(printf %d ${1#:})"
+ else
+ echo "$1"
+ fi
+}
+
do_next () {
rm -f "$DOTEST"/message "$DOTEST"/author-script \
"$DOTEST"/amend || exit@@ -321,6 +336,17 @@ do_next () {
die_with_patch $sha1 ""
fi
;;
+ mark)
+ mark_action_done
+
+ mark=$(mark_to_ref :${sha1#:})
+ test :${sha1#:} = "$mark" && die "Invalid mark '$sha1'"
+
+ git rev-parse --verify "$mark" > /dev/null 2>&1 && \
+ warn "mark $sha1 already exist; overwriting it"
+
+ git update-ref "$mark" HEAD || die "update-ref failed"
+ ;;
*)
warn "Unknown command: $command $sha1 $rest"
die_with_patch $sha1 "Please fix this in the file $TODO."@@ -533,10 +559,15 @@ do
# Rebase $SHORTUPSTREAM..$SHORTHEAD onto $SHORTONTO
#
+# In the todo insn whenever you need to refer to a commit, in addition
+# to the usual commit object name, you can use ':mark' syntax to refer
+# to a commit previously marked with the 'mark' insn.
+#
# Commands:
# pick = use commit
# edit = use commit, but stop for amending
# squash = use commit, but meld into previous commit
+# mark :mark = mark the current HEAD for later reference
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 8d29878..fa3560e 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -82,6 +82,9 @@ for line in $FAKE_LINES; do
case $line in
squash|edit)
action="$line";;
+ mark*)
+ echo "mark ${line#mark}"
+ echo "mark ${line#mark}" >> "$1";;
*)
echo sed -n "${line}s/^pick/$action/p"
sed -n "${line}p" < "$1".tmp@@ -189,6 +192,20 @@ test_expect_success '-p handles "no changes" gracefully' '
test $HEAD = $(git rev-parse HEAD)
'
+test_expect_success 'setting marks works' '
+ git checkout master &&
+ FAKE_LINES="mark:0 2 1 mark:42 3 edit 4" git rebase -i HEAD~4 &&
+ marks_dir=.git/refs/rebase-marks &&
+ test -d $marks_dir &&
+ test $(ls $marks_dir | wc -l) -eq 2 &&
+ test "$(git rev-parse HEAD~4)" = \
+ "$(git rev-parse refs/rebase-marks/0)" &&
+ test "$(git rev-parse HEAD~2)" = \
+ "$(git rev-parse refs/rebase-marks/42)" &&
+ git rebase --abort &&
+ ls $marks_dir | wc -l | grep -Fx 0
+'
+
test_expect_success 'preserve merges with -p' '
git checkout -b to-be-preserved master^ &&
: > unrelated-file &&
--
1.5.5.1