1+ test ! -z " $GIT_USE_REBASE_HELPER " ||
2+ GIT_USE_REBASE_HELPER=cross-validate
3+
14# This shell script fragment is sourced by git-rebase to implement
25# its interactive mode. "git rebase --interactive" makes it easy
36# to fix up commits in the middle of a series and rearrange commits.
@@ -676,6 +679,30 @@ do_next () {
676679 fi &&
677680 warn " Successfully rebased and updated $head_name ."
678681
682+ # Run the same shebang using rebase--helper
683+ if test cross-validate = " $GIT_USE_REBASE_HELPER " &&
684+ test -d " $GIT_DIR " /saved-rebase-merge
685+ then
686+ rm -rf " $GIT_DIR " /shell-rebase-merge
687+
688+ echo " Cross-validating with rebase--helper" >&2
689+ mv " $GIT_DIR " /rebase-merge " $GIT_DIR " /shell-rebase-merge &&
690+ cp -R " $GIT_DIR " /saved-rebase-merge " $GIT_DIR " /rebase-merge &&
691+ echo 1 > " $GIT_DIR " /saved-rebase-merge/cross-validating &&
692+ git rev-parse HEAD > " $GIT_DIR " /saved-rebase-merge/shell-head &&
693+ output git checkout \
694+ $( cat " $GIT_DIR " /saved-rebase-merge/start-head) &&
695+ case " $( cat " $GIT_DIR " /rebase-merge/head-name) " in
696+ refs/* ) git update-ref -m " re-run rebase" \
697+ $( cat " $GIT_DIR " /rebase-merge/head-name) \
698+ $( cat " $GIT_DIR " /rebase-merge/orig-head)
699+ ;;
700+ esac &&
701+ git rebase--helper ${force_rebase: +--no-ff} --continue ||
702+ die " Builtin rebase--helper failed"
703+ check_rebase__helper
704+ fi
705+
679706 return 1 # not failure; just to break the do_rest loop
680707}
681708
@@ -743,11 +770,27 @@ transform_todo_ids () {
743770}
744771
745772expand_todo_ids () {
773+ cp " $todo " " $todo " .transform
774+ transform_todo_ids
775+ mv " $todo " " $todo " .transformed
776+ cp " $todo " .transform " $todo "
746777 git rebase--helper --expand-sha1s
778+ if ! git diff --no-index -w -- " $todo " " $todo .transformed"
779+ then
780+ die " rebase--helper failed to expand todo IDs"
781+ fi
747782}
748783
749784collapse_todo_ids () {
785+ cp " $todo " " $todo " .transform
786+ transform_todo_ids --short
787+ mv " $todo " " $todo " .transformed
788+ cp " $todo " .transform " $todo "
750789 git rebase--helper --shorten-sha1s
790+ if ! git diff --no-index -w -- " $todo " " $todo .transformed"
791+ then
792+ die " rebase--helper failed to collapse todo IDs"
793+ fi
751794}
752795
753796# Rearrange the todo list that has both "pick sha1 msg" and
@@ -1032,6 +1075,23 @@ check_todo_list () {
10321075 fi
10331076}
10341077
1078+ check_rebase__helper () {
1079+ echo " Cross-validating rebase--helper's result" >&2
1080+ test -f " $GIT_DIR " /saved-rebase-merge/cross-validating ||
1081+ return 0
1082+ rm -rf " $GIT_DIR " /before-rebase-merge
1083+ mv " $GIT_DIR " /saved-rebase-merge " $GIT_DIR " /before-rebase-merge
1084+ start_head=$( cat " $GIT_DIR " /before-rebase-merge/start-head)
1085+ shell_head=$( cat " $GIT_DIR " /before-rebase-merge/shell-head)
1086+ git rev-parse HEAD > " $GIT_DIR " /before-rebase-merge/builtin-head
1087+ git log --raw $start_head ..$shell_head |
1088+ sed " s/^commit .*$/commit/" > " $GIT_DIR " /before-rebase-merge/shell_log
1089+ git log --raw $start_head .. |
1090+ sed " s/^commit .*$/commit/" > " $GIT_DIR " /before-rebase-merge/builtin_log
1091+ cmp " $GIT_DIR " /before-rebase-merge/shell_log " $GIT_DIR " /before-rebase-merge/builtin_log ||
1092+ die " Builtin rebase--helper produced different result"
1093+ }
1094+
10351095# The whole contents of this file is run by dot-sourcing it from
10361096# inside a shell function. It used to be that "return"s we see
10371097# below were not inside any function, and expected to return
@@ -1045,10 +1105,21 @@ git_rebase__interactive () {
10451105
10461106case " $action " in
10471107continue)
1048- if test ! -d " $rewritten "
1108+ if test -f " $GIT_DIR " /saved-rebase-merge/cross-validating
1109+ then
1110+ git rebase--helper ${force_rebase: +--no-ff} --continue &&
1111+ if test ! -f " $todo "
1112+ then
1113+ check_rebase__helper
1114+ fi
1115+ return
1116+ fi
1117+
1118+ if test -f " $GIT_DIR " /rebase-merge/use-builtin
10491119 then
10501120 exec git rebase--helper ${force_rebase: +--no-ff} --continue
10511121 fi
1122+
10521123 # do we have anything to commit?
10531124 if git diff-index --cached --quiet HEAD --
10541125 then
@@ -1106,10 +1177,21 @@ first and then run 'git rebase --continue' again."
11061177skip)
11071178 git rerere clear
11081179
1109- if test ! -d " $rewritten "
1180+ if test -f " $GIT_DIR " /saved-rebase-merge/cross-validating
1181+ then
1182+ git rebase--helper ${force_rebase: +--no-ff} --continue &&
1183+ if test ! -f " $todo "
1184+ then
1185+ check_rebase__helper
1186+ fi
1187+ return
1188+ fi
1189+
1190+ if test -f " $GIT_DIR " /rebase-merge/use-builtin
11101191 then
11111192 exec git rebase--helper ${force_rebase: +--no-ff} --continue
11121193 fi
1194+
11131195 do_rest
11141196 return 0
11151197 ;;
@@ -1188,27 +1270,25 @@ else
11881270 revisions=$onto ...$orig_head
11891271 shortrevisions=$shorthead
11901272fi
1191- if test t ! = " $preserve_merges "
1192- then
1193- git rebase--helper --make-script ${keep_empty: +--keep-empty} \
1194- $revisions ${restrict_revision+^$restrict_revision } > " $todo "
1195- else
1196- format=$( git config --get rebase.instructionFormat)
1197- # the 'rev-list .. | sed' requires %m to parse; the instruction requires %H to parse
1198- git rev-list $merges_option --format=" %m%H ${format:-% s} " \
1199- --reverse --left-right --topo-order \
1200- $revisions ${restrict_revision+^$restrict_revision } | \
1201- sed -n " s/^>//p" |
1202- while read -r sha1 rest
1203- do
1204-
1205- if test -z " $keep_empty " && is_empty_commit $sha1 && ! is_merge_commit $sha1
1206- then
1207- comment_out=" $comment_char "
1208- else
1209- comment_out=
1210- fi
1273+ format=$( git config --get rebase.instructionFormat)
1274+ # the 'rev-list .. | sed' requires %m to parse; the instruction requires %H to parse
1275+ git rev-list $merges_option --format=" %m%H ${format:-% s} " \
1276+ --reverse --left-right --topo-order \
1277+ $revisions ${restrict_revision+^$restrict_revision } | \
1278+ sed -n " s/^>//p" |
1279+ while read -r sha1 rest
1280+ do
1281+ if test -z " $keep_empty " && is_empty_commit $sha1 && ! is_merge_commit $sha1
1282+ then
1283+ comment_out=" $comment_char "
1284+ else
1285+ comment_out=
1286+ fi
12111287
1288+ if test t ! = " $preserve_merges "
1289+ then
1290+ printf ' %s\n' " ${comment_out} pick $sha1 $rest " >> " $todo "
1291+ else
12121292 if test -z " $rebase_root "
12131293 then
12141294 preserve=t
@@ -1227,7 +1307,23 @@ else
12271307 touch " $rewritten " /$sha1
12281308 printf ' %s\n' " ${comment_out} pick $sha1 $rest " >> " $todo "
12291309 fi
1230- done
1310+ fi
1311+ done
1312+ if test -z " $rebase_root " && test ! -d " $rewritten "
1313+ then
1314+ git rebase--helper --make-script ${keep_empty: +--keep-empty} \
1315+ $revisions ${restrict_revision+^$restrict_revision } \
1316+ > " $todo " .helped
1317+ if test ! -s " $todo " .helped
1318+ then
1319+ test ! -f " $todo " || die " $todo .helped should be empty"
1320+ elif ! cmp " $todo " " $todo " .helped
1321+ then
1322+ echo git rebase--helper --make-script \
1323+ ${keep_empty: +--keep-empty} $revisions \
1324+ ${restrict_revision+^$restrict_revision } > " $todo " .gen
1325+ die " make-script generated something incompatible"
1326+ fi
12311327fi
12321328
12331329# Watch for commits that been dropped by --cherry-pick
@@ -1299,10 +1395,20 @@ expand_todo_ids
12991395test -d " $rewritten " || test -n " $force_rebase " || skip_unnecessary_picks
13001396
13011397checkout_onto
1302- if test -z " $rebase_root " && test ! -d " $rewritten "
1398+ if test true = " $GIT_USE_REBASE_HELPER " && test -z " $rebase_root " &&
1399+ test ! -d " $rewritten "
13031400then
13041401 require_clean_work_tree " rebase"
1402+ echo 1 > " $GIT_DIR " /rebase-merge/use-builtin
13051403 exec git rebase--helper ${force_rebase: +--no-ff} --continue
1404+ elif test cross-validate = " $GIT_USE_REBASE_HELPER "
1405+ then
1406+ rm -rf " $GIT_DIR " /saved-rebase-merge
1407+ if test -z " $rebase_root " && test ! -d " $rewritten "
1408+ then
1409+ cp -R " $GIT_DIR " /rebase-merge " $GIT_DIR " /saved-rebase-merge
1410+ git rev-parse HEAD > " $GIT_DIR " /saved-rebase-merge/start-head
1411+ fi
13061412fi
13071413do_rest
13081414
0 commit comments