1
+ test ! -z " $GIT_USE_REBASE_HELPER " ||
2
+ GIT_USE_REBASE_HELPER=cross-validate
3
+
1
4
# This shell script fragment is sourced by git-rebase to implement
2
5
# its interactive mode. "git rebase --interactive" makes it easy
3
6
# to fix up commits in the middle of a series and rearrange commits.
@@ -677,6 +680,35 @@ do_next () {
677
680
fi &&
678
681
warn " Successfully rebased and updated $head_name ."
679
682
683
+ # Run the same shebang using rebase--helper
684
+ if test cross-validate = " $GIT_USE_REBASE_HELPER " &&
685
+ test -d " $GIT_DIR " /saved-rebase-merge
686
+ then
687
+ rm -rf " $GIT_DIR " /shell-rebase-merge
688
+
689
+ echo " Cross-validating with rebase--helper" >&2
690
+ mv " $GIT_DIR " /rebase-merge " $GIT_DIR " /shell-rebase-merge &&
691
+ cp -R " $GIT_DIR " /saved-rebase-merge " $GIT_DIR " /rebase-merge &&
692
+ echo 1 > " $GIT_DIR " /saved-rebase-merge/cross-validating &&
693
+ git rev-parse HEAD > " $GIT_DIR " /saved-rebase-merge/shell-head &&
694
+ output git checkout \
695
+ $( cat " $GIT_DIR " /saved-rebase-merge/start-head) &&
696
+ case " $( cat " $GIT_DIR " /rebase-merge/head-name) " in
697
+ refs/* ) git update-ref -m " re-run rebase" \
698
+ $( cat " $GIT_DIR " /rebase-merge/head-name) \
699
+ $( cat " $GIT_DIR " /rebase-merge/orig-head)
700
+ ;;
701
+ esac &&
702
+ git rebase--helper ${force_rebase: +--no-ff} --continue ||
703
+ die " Builtin rebase--helper failed"
704
+ if test -f " $todo "
705
+ then
706
+ exit
707
+ else
708
+ check_rebase__helper
709
+ fi
710
+ fi
711
+
680
712
return 1 # not failure; just to break the do_rest loop
681
713
}
682
714
@@ -744,11 +776,27 @@ transform_todo_ids () {
744
776
}
745
777
746
778
expand_todo_ids () {
779
+ cp " $todo " " $todo " .transform
780
+ transform_todo_ids
781
+ mv " $todo " " $todo " .transformed
782
+ cp " $todo " .transform " $todo "
747
783
git rebase--helper --expand-sha1s
784
+ if ! git diff --no-index -w -- " $todo " " $todo .transformed"
785
+ then
786
+ die " rebase--helper failed to expand todo IDs"
787
+ fi
748
788
}
749
789
750
790
collapse_todo_ids () {
791
+ cp " $todo " " $todo " .transform
792
+ transform_todo_ids --short
793
+ mv " $todo " " $todo " .transformed
794
+ cp " $todo " .transform " $todo "
751
795
git rebase--helper --shorten-sha1s
796
+ if ! git diff --no-index -w -- " $todo " " $todo .transformed"
797
+ then
798
+ die " rebase--helper failed to collapse todo IDs"
799
+ fi
752
800
}
753
801
754
802
# Rearrange the todo list that has both "pick sha1 msg" and
@@ -1033,6 +1081,23 @@ check_todo_list () {
1033
1081
fi
1034
1082
}
1035
1083
1084
+ check_rebase__helper () {
1085
+ echo " Cross-validating rebase--helper's result" >&2
1086
+ test -f " $GIT_DIR " /saved-rebase-merge/cross-validating ||
1087
+ return 0
1088
+ rm -rf " $GIT_DIR " /before-rebase-merge
1089
+ mv " $GIT_DIR " /saved-rebase-merge " $GIT_DIR " /before-rebase-merge
1090
+ start_head=$( cat " $GIT_DIR " /before-rebase-merge/start-head)
1091
+ shell_head=$( cat " $GIT_DIR " /before-rebase-merge/shell-head)
1092
+ git rev-parse HEAD > " $GIT_DIR " /before-rebase-merge/builtin-head
1093
+ git log --raw --date-order $start_head ..$shell_head |
1094
+ sed " s/^commit .*$/commit/" > " $GIT_DIR " /before-rebase-merge/shell_log
1095
+ git log --raw --date-order $start_head .. |
1096
+ sed " s/^commit .*$/commit/" > " $GIT_DIR " /before-rebase-merge/builtin_log
1097
+ cmp " $GIT_DIR " /before-rebase-merge/shell_log " $GIT_DIR " /before-rebase-merge/builtin_log ||
1098
+ die " Builtin rebase--helper produced different result"
1099
+ }
1100
+
1036
1101
# The whole contents of this file is run by dot-sourcing it from
1037
1102
# inside a shell function. It used to be that "return"s we see
1038
1103
# below were not inside any function, and expected to return
@@ -1046,10 +1111,21 @@ git_rebase__interactive () {
1046
1111
1047
1112
case " $action " in
1048
1113
continue)
1049
- if test ! -d " $rewritten "
1114
+ if test -f " $GIT_DIR " /saved-rebase-merge/cross-validating
1115
+ then
1116
+ git rebase--helper ${force_rebase: +--no-ff} --continue &&
1117
+ if test ! -f " $todo "
1118
+ then
1119
+ check_rebase__helper
1120
+ fi
1121
+ exit
1122
+ fi
1123
+
1124
+ if test -f " $GIT_DIR " /rebase-merge/use-builtin
1050
1125
then
1051
1126
exec git rebase--helper ${force_rebase: +--no-ff} --continue
1052
1127
fi
1128
+
1053
1129
# do we have anything to commit?
1054
1130
if git diff-index --cached --quiet HEAD --
1055
1131
then
@@ -1107,10 +1183,21 @@ first and then run 'git rebase --continue' again."
1107
1183
skip)
1108
1184
git rerere clear
1109
1185
1110
- if test ! -d " $rewritten "
1186
+ if test -f " $GIT_DIR " /saved-rebase-merge/cross-validating
1187
+ then
1188
+ git rebase--helper ${force_rebase: +--no-ff} --continue &&
1189
+ if test ! -f " $todo "
1190
+ then
1191
+ check_rebase__helper
1192
+ fi
1193
+ exit
1194
+ fi
1195
+
1196
+ if test -f " $GIT_DIR " /rebase-merge/use-builtin
1111
1197
then
1112
1198
exec git rebase--helper ${force_rebase: +--no-ff} --continue
1113
1199
fi
1200
+
1114
1201
do_rest
1115
1202
return 0
1116
1203
;;
@@ -1189,27 +1276,25 @@ else
1189
1276
revisions=$onto ...$orig_head
1190
1277
shortrevisions=$shorthead
1191
1278
fi
1192
- if test t ! = " $preserve_merges "
1193
- then
1194
- git rebase--helper --make-script ${keep_empty: +--keep-empty} \
1195
- $revisions ${restrict_revision+^$restrict_revision } > " $todo "
1196
- else
1197
- format=$( git config --get rebase.instructionFormat)
1198
- # the 'rev-list .. | sed' requires %m to parse; the instruction requires %H to parse
1199
- git rev-list $merges_option --format=" %m%H ${format:-% s} " \
1200
- --reverse --left-right --topo-order \
1201
- $revisions ${restrict_revision+^$restrict_revision } | \
1202
- sed -n " s/^>//p" |
1203
- while read -r sha1 rest
1204
- do
1205
-
1206
- if test -z " $keep_empty " && is_empty_commit $sha1 && ! is_merge_commit $sha1
1207
- then
1208
- comment_out=" $comment_char "
1209
- else
1210
- comment_out=
1211
- fi
1279
+ format=$( git config --get rebase.instructionFormat)
1280
+ # the 'rev-list .. | sed' requires %m to parse; the instruction requires %H to parse
1281
+ git rev-list $merges_option --format=" %m%H ${format:-% s} " \
1282
+ --reverse --left-right --topo-order \
1283
+ $revisions ${restrict_revision+^$restrict_revision } | \
1284
+ sed -n " s/^>//p" |
1285
+ while read -r sha1 rest
1286
+ do
1287
+ if test -z " $keep_empty " && is_empty_commit $sha1 && ! is_merge_commit $sha1
1288
+ then
1289
+ comment_out=" $comment_char "
1290
+ else
1291
+ comment_out=
1292
+ fi
1212
1293
1294
+ if test t ! = " $preserve_merges "
1295
+ then
1296
+ printf ' %s\n' " ${comment_out} pick $sha1 $rest " >> " $todo "
1297
+ else
1213
1298
if test -z " $rebase_root "
1214
1299
then
1215
1300
preserve=t
@@ -1228,7 +1313,23 @@ else
1228
1313
touch " $rewritten " /$sha1
1229
1314
printf ' %s\n' " ${comment_out} pick $sha1 $rest " >> " $todo "
1230
1315
fi
1231
- done
1316
+ fi
1317
+ done
1318
+ if test -z " $rebase_root " && test ! -d " $rewritten "
1319
+ then
1320
+ git rebase--helper --make-script ${keep_empty: +--keep-empty} \
1321
+ $revisions ${restrict_revision+^$restrict_revision } \
1322
+ > " $todo " .helped
1323
+ if test ! -s " $todo " .helped
1324
+ then
1325
+ test ! -f " $todo " || die " $todo .helped should be empty"
1326
+ elif ! cmp " $todo " " $todo " .helped
1327
+ then
1328
+ echo git rebase--helper --make-script \
1329
+ ${keep_empty: +--keep-empty} $revisions \
1330
+ ${restrict_revision+^$restrict_revision } > " $todo " .gen
1331
+ die " make-script generated something incompatible"
1332
+ fi
1232
1333
fi
1233
1334
1234
1335
# Watch for commits that been dropped by --cherry-pick
@@ -1300,10 +1401,20 @@ expand_todo_ids
1300
1401
test -d " $rewritten " || test -n " $force_rebase " || skip_unnecessary_picks
1301
1402
1302
1403
checkout_onto
1303
- if test -z " $rebase_root " && test ! -d " $rewritten "
1404
+ if test true = " $GIT_USE_REBASE_HELPER " && test -z " $rebase_root " &&
1405
+ test ! -d " $rewritten "
1304
1406
then
1305
1407
require_clean_work_tree " rebase"
1408
+ echo 1 > " $GIT_DIR " /rebase-merge/use-builtin
1306
1409
exec git rebase--helper ${force_rebase: +--no-ff} --continue
1410
+ elif test cross-validate = " $GIT_USE_REBASE_HELPER "
1411
+ then
1412
+ rm -rf " $GIT_DIR " /saved-rebase-merge
1413
+ if test -z " $rebase_root " && test ! -d " $rewritten "
1414
+ then
1415
+ cp -R " $GIT_DIR " /rebase-merge " $GIT_DIR " /saved-rebase-merge
1416
+ git rev-parse HEAD > " $GIT_DIR " /saved-rebase-merge/start-head
1417
+ fi
1307
1418
fi
1308
1419
do_rest
1309
1420
0 commit comments